サーバー設定ツール「Chef」の概要と基礎的な使い方 3ページ
chef-soloコマンド用の設定ファイルを作成する
作成したCookbookは、chef-soloコマンドで実行できる。chef-soloコマンドの挙動はコマンドラインオプションのほか、設定ファイルで指定でき、そのパスはデフォルトでは/etc/chef/solo.rbファイルとなっている。このファイルは自動的には作成されないので、手動で作成しておく必要がある。
# mkdir /etc/chef # vi /etc/chef/solo.rb
このファイルの内容についてはsolo.rbに関するドキュメントを参照してほしいが、今回はCookbookを格納しているディレクトリの指定のみを行うこととする。たとえば「/home/hylom/chef-repo/cookbooks」というディレクトリ内にCookbookを格納している場合、以下のように記述すれば良い。
cookbook_path ["/home/hylom/chef-repo/cookbooks"]
solo.rbファイルを作成したら、chef-soloコマンドでCookbookを実行してみよう。なお、実行にはroot権限が必要だ。実行するRecipe名は「-o」オプションで指定できる。Recipe名は「<Cookbook名>::<Recipe名>」という形で指定する。Recipe名を省略してCookbook名のみを指定することも可能だ。その場合、recipesディレクトリ内の「default.rb」というRecipeが実行される。
以下の例は、先ほど作成したsetup-userのdefault.rbというRecipeを実行したものだ。
# chef-solo -o setup-user Starting Chef Client, version 11.6.0 Compiling Cookbooks... Converging 2 resources Recipe: setup-user::default * group[taro] action create - create group[taro] * user[taro] action create - create user user[taro] Chef Client finished, 2 resources updated
出力結果からは、Recipeファイルに記述したとおりにグループとユーザーが作成されていることが分かる。ちなみに、同じCookbookを再度実行すると、次のようにメッセージが表示される。
# chef-solo -o setup-user Starting Chef Client, version 11.6.0 Compiling Cookbooks... Converging 3 resources Recipe: setup-user::default * group[taro] action create (up to date) * user[taro] action create * You must have ruby-shadow installed for password support!
ここでは「ruby-shadow」が必要と表示されているが、gemコマンドでこのパッケージをインストールすればこのメッセージは表示されなくなる。
# gem install ruby-shadow
実行するRecipeを指定する
先の例では-oオプションで実行するRecipeを指定したが、通常は実行するRecipeをファイルに記述し、そのファイルをコマンドラインオプションで指定するのが一般的だ。実行するRecipe一覧はJSON形式で記述し、chef-soloコマンドの-jオプションでそのファイルを指定する。
たとえば、先の「setup-user」Recipeを実行する場合、JSONファイルは以下のようになる。
{ "run_list": [ "recipe[setup-user]" ] }
/etc/chef/solo.jsonというファイルにこれを記述した場合、次のようにしてchef-soloを実行する。
# chef-solo -j /etc/chef/solo.json
なお、ここで指定したJSONファイルではRecipeやCookbookに与えるパラメータ(Attribute)を記述することも可能だ。こちらについては後述する。
パッケージをインストールさせる
続いては、Chefのデフォルトで用意されているリソースタイプを使ったRecipeをいくつか紹介しておこう。まず、yum経由でパッケージをインストールするには「yum_package」リソースタイプを利用する。
yum_package <パッケージ名> do action :install end
たとえば「sudo」パッケージをyumでインストールするRecipeは以下のようになる。
yum_package "sudo" do action :install end
また、RPMファイルからパッケージをインストールするには、「rpm_package」リソースタイプを利用する。
rpm_package <パッケージ名> do source <RPMファイルのパス名> action :install end
ただし、rpm_packageリソースタイプではローカルにあるファイルしかインストールできない。リモートにあるRPMファイルをインストールしたい場合、リモートからファイルをダウンロードする「remote_file」リソースタイプと組み合わせて利用する必要がある。
remote_file <ダウンロードしたファイルの保存先パス名> do source <ダウンロードするURL> end
以下のRecipeは、「http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm」というURLで公開されているRPMファイルをダウンロードしてインストールするものだ。
remote_file "#{Chef::Config[:file_cache_path]}/epel-release-6-8.noarch.rpm" do source "http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm" not_if "rpm -qa | grep -q '^epel-release'"" action :create notifies :install, "rpm_package[epel-release]", :immediately end rpm_package "epel-release" do source "#{Chef::Config[:file_cache_path]}/epel-release-6-8.noarch.rpm" action :nothing end
「#{Chef::Config[:file_cache_path]}」はChefの設定データベース内で「file_cache_path」というキーに格納されている値を参照するという意味だ。ここにはファイルキャッシュとして使用するディレクトリのパス名が格納されている。また、「not_if」は指定した文字列を実行し、その結果が真でなければ処理を実行するよう指定するものだ。ここでは「epel-release」パッケージがインストールされていなければ処理を実行するよう指定している。さらに、「notifies」属性はそのリソースに対する処理が実行された際に、続けて実行するリソースを指定するものだ。ここでは「rpm_package」型の「epel-release」というリソースについて、即座に(immediately)インストールを実行するよう指定している。
「epel-release」リソースのactionに「:nothing」が指定されていることも注目したい。これが指定されたリソースは通常何の処理も実行されない。つまり、このRecipeはepel-releaseパッケージがインストールされていない場合にのみパッケージをダウンロードしてインストールする、という内容になる。
テンプレートを使う
次は、設定ファイルを指定したディレクトリに作成するRecipeを紹介しよう。内容としては、httpdパッケージをインストールしてhttpdサービスを起動し、/var/www/testというディレクトリと/etc/httpd/conf.d/mysite.confという設定ファイルを作成する、というものだ。
設定ファイルを作成する場合、そのひな形はtemplates/defaultディレクトリ内に格納する。また、テンプレートファイルはeRuby形式(拡張子は.erb)で記述する。今回の例では、templates/default/mysite.conf.erbとして設定ファイルを作成する。
NameVirtualHost *:8000 <VirtualHost *:8000> ServerName <%= @hostname %> DocumentRoot /var/www/test ErrorLog logs/test-error_log CustomLog logs/test-access_log common </VirtualHost>
eRuby形式についての詳細は割愛するが、「<%」と「%>」 で囲まれた部分がRubyコードとして実行され、また「<%=」と「%>」で囲まれた部分はその実行結果に置き換えられる(「<% print」と「%>」で囲んだものと等価)。つまり、このテンプレートファイルでは「<%= @hostname %>」の部分がhostname変数の値に置き換えられる、ということになる。
この設定ファイルを利用するRecipeは次のようになる。
# httpdパッケージをインストールする yum_package "httpd" do action :install end # httpdサービスを起動する service "httpd" do action :start end # /var/www/testディレクトリを作成する directory "/var/www/test" do owner "root" group "root" mode 0755 action :create end # mysite.conf.erbというテンプレートから # /etc/httpd/conf.d/mysite.confという設定ファイルを作成する template "/etc/httpd/conf.d/mysite.conf" do source "mysite.conf.erb" owner "root" group "root" mode 0644 action :create variables({ # テンプレートに与える変数の値を指定する :hostname => `/bin/hostname`.chomp }) end
設定内容はコメントに記載したとおりだが、注目したいのが「/etc/httpd/conf.d/mysite.conf」リソースでの「variables」属性だ。ここではテンプレートに与えるhostname変数の値を指定しているのだが、Rubyの「`」(バッククォート)構文を使って/bin/hostnameコマンドを実行し、その結果の行末の改行を取り除いたものを変数に格納している。このように、Rubyの機能を利用してRecipeを記述できるのがChefの特徴の1つだ。
コマンドを実行する
「execute」リソースタイプでは、特定のコマンドを実行するリソースを作成できる。実行するコマンドは「command」属性で指定する。また、actionには「:run」もしくは「:nothing」が指定できる。
execute <リソース名> do command <実行するコマンド> action <実行するアクション> end
たとえば、sedコマンドを使って「/etc/yum.repos.d/epel.repo」という設定ファイルを編集するようなRecipeは、以下のように記述できる。
execute 'epel.repo' do command "/bin/sed -i -e 's/^enabled\s*=\s*1/enabled=0/g' /etc/yum.repos.d/epel.repo" action :nothing subscribes :run, "rpm_package[epel-release]", :immediately end
ここで指定されている「subscribes」属性は、指定したリソースが実行された後に特定のactionを実行する、ということを指定するものだ。この例の場合、「rpm_package[epel-release]」というリソースが実行された場合、即座にこのリソースに対し「:run」というアクションを実行する、ということを意味している。