chef
vagrant

今更ですがChefとVagrantを勉強してみた

More than 4 years have passed since last update.

はじめに

今更ですが、サーバ構成(プロビジョニング)手順を自動化するプロビジョニングフレームワークChefを使ってみたという話。
ですので、本記事の対象読者はChefとVagrantの初心者です。
本記事を読むと、

  • Chef/Vagrantとは何か?について
  • 作成したクックブックの対象ノードへの適用方法
  • serverspecを使ったサーバ構築プロセスのテスト方法

を学ぶことができる(と思う)。

Chefとは

Opscodeによって開発されているRubyで書かれたOSS。 レシピ と呼ばれるファイルに記述した設定内容に応じてユーザの作成やパッケージのインストールなどを自動的に行ってくれる。

Vagrantとは

簡単なコマンドで任意の構成の仮想マシンを自動的に構築してくれるツール。

準備

Chefの検証環境構築に必要なツールを準備する。

VirtualBoxのインストール

ここから使用しているOSのパッケージをダウンロードして、インストーラの指示に従ってインストールを行う。

Vagrantのインストール

ここからダウンロードして、インストーラの指示に従ってインストールを行う。

仮想イメージの取得

初めてVagrantを利用する場合、利用したいOSのイメージ( box )を取得する必要がある。boxはここから取得する。例えばubuntuというラベルでイメージを取得するにはターミナルで下記コマンドを入力する。

$ vagrant box add ubuntu http://cloud-images.ubuntu.com/vagrant/quantal/current/quantal-server-cloudimg-amd64-vagrant-disk1.box

イメージの取得が完了すれば、準備は終わり。

仮想サーバの起動/停止/破棄

適当な作業ディレクトリを用意して

$ vagrant init ubuntu

を実行し、Vagrantファイルを生成する。続いて

$ vagrant up

を実行して、仮想サーバを起動する。仮想サーバが起動したら

$ vagrant ssh

でsshログインする。仮想サーバを停止させたい場合は

$ vagrant halt

仮想サーバを破棄したい場合は

$ vagrant destroy

を実行する。haltでは次回仮想サーバ起動時にイメージの内容はhalt時点のものに復元されるが、destroyはまっさらな状態となる。

SSHの設定

$ vagrant ssh-config --host HOSTNAME >> ~/.ssh/config

を実行すると、ssh HOSTNAMEでログインできる様になる。

knife-soloでChefを実行する

sshログインしてchef-soloを直接実行する方法には、

  • いちいちsshログインするのは面倒
  • リモート編集では使い慣れたエディタが使えない

といった煩わしさがある。
そこで、knifeのプラグインであるknife-soloを使うとローカル環境で編集したクックブックをrsyncで ノード (構成管理対象のホスト/サーバのこと)に転送してchef-soloを実行できる。

knife-soloのインストール

下記GemfileをVagrantファイルと同じディレクトリに作成する。

source 'https://rubygems.org'
gem "knife-solo", "~> 0.3.0.pre3"

作成したら

$ bundle

でインストールする。インストールが完了したら下記コマンドを実行してknifeの初期化を行う。

$ bundle exec knife configure

knife-soloでChefリポジトリを作る

Gemfileのあるディレクトリで下記コマンドを実行し、Chef用ディレクトリを作成する。

$ bundle exec knife solo init chef-repo

knife-solo prepareでノードにChef Soloを入れる

  • 対象ノードにChef Soloが入っていない
  • 対象ノードにChef Soloが入っているが、バージョンが古いためバージョンアップしたい

場合は下記コマンドを実行する(NODENAMEには自分のノード名を指定する)。

$ bundle exec knife solo prepare NODENAME

knife solo prepareはChefのインストールの他、knife-solo用のrsync関連の設定も調整してくれるらしいので、一度実行すると良いと思う。

クックブックの作成

chef-repoディレクトリへ移動し、下記コマンドを実行して新規クックブックを作成する。

$ bundle exec knife cookbook create nginx -o site-cookbooks

続いて下記ファイルをchef-repo/site-cookbooks/nginx/に作成する。

/chef-repo/site-cookbooks/nginx/default.rb
#
# Cookbook Name:: nginx
# Recipe:: default
#
# Copyright 2014, YOUR_COMPANY_NAME
#
# All rights reserved - Do Not Redistribute
#
package "nginx" do
    action :install
end

続いて対象ノードに今作成したクックブック(nginx)を適用させる命令を、設定ファイル( Nodeオブジェクト )に書く。設定ファイルは/chef-repo/nodes/NODENAME.jsonで(NODENAMEは自分が指定したノード名)、内容は下記の通り。

/chef-repo/nodes/NODENAME.json
{
    "run_list":[
        "recipe[nginx]"
    ]   
}

以上の作業が完了したら、下記コマンドを実行してクックブックを対象ノードに適用させる(2200の部分は/.ssh/configに記載されているPort番号を指定する)。

$ bundle exec knife solo cook -i ~/.vagrant.d/insecure_private_key -p 2200 vagrant@127.0.0.1

上記コマンドの実行が完了したら、対象ノードへsshログインし、

$ rpm -qa | grep nginx

で実際にnginxがインストールされていることを確認できればOK。

補足

リソース

default.rbで書いたpackageは、リソースと呼ばれる(ちなみにactionは属性と呼ばれる)。他にどんなリソースがあるのか知りたい方はここを参照。

クックブック

今回はクックブックを自作したが、ここに他の方が作成したクックブックが公開されているので、それをダウンロードして利用することも可能。

serverspecによるテスト

Chefを適用したあと、正しく変更が反映されたかどうかを目視するのは大変。ということで、serverspecという、サーバテストフレームワークを使って変更が反映されたかどうかの確認を自動化しよう。

serverspecとは

サーバ構成のテストを行うRuby製フレームワーク。テスト自体はRSpecを使って書く。
serverspecはChefやその他プロビジョニングフレームワークから独立しているため、Chefを使っていない環境のテストのテストにもChefで構成されている環境にも使えるというメリットがある(つまり、将来Chefで構成されたサーバを別のフレームワークで構成し直したい(またはその逆の)場合、テストコードを修正する必要はなく、そのまま流用できる)。

準備

検証用サーバの用意

任意のディレクトリに移動し、検証用サーバの初期化・起動を行う。

$ vagrant init ubuntu
$ vagrant up

任意のホスト名も設定しておく(ここではexampleとする)。

serverspecのインストール

gemでインストールできる。serverspecはssh経由で対象ホスト(今回はexample)にログインしてテストを行うツールなので、 Vagrantで起動したホストではなく、ローカル環境にインストールする 必要がある。
下記Gemfileを作成し$ bundleでインストールする。

source 'https://rubygems.org'
gem 'serverspec'
gem 'rake'

インストールが完了したら

$ bundle exec serverspec-init

でテストの初期化を行う。その際いくつか質問されるが、

  • backend typeはSSH
  • Vagrant instanceはno(ホスト名にexampleを指定)

を選択する。
全質問に回答を終えると、spec/example/にhttpd_spec.rbが生成される。

テストの実行

下記コマンドを実行してテストを実行する(検証用サーバは起動したばかりで、Apacheがインストールされていないため、テストは失敗する)。

$ bundle exec rake spec

テストを通す

exampleにsshログインして、Apacheインストール・有効化・ServerNameの置き換え・Apacheの起動を行い、再度テストを実行すると、テストが通る(はず)。