Itamaeが構成管理を仕込みます! ~新進気鋭の国産・構成管理ツール~

第2回 レシピの書き方

この記事を読むのに必要な時間:およそ 4 分

リソースの実行順序

Itamaeのリソースは基本的に上から下に順番に実行されます。しかし,リソースの定義は実行前に行われるため注意が必要です。具体例を以下に示します。

puts "A"

local_ruby_block "local" do
  puts "B"
  block do
    puts "C"
  end
  puts "D"
end

puts "E"
vagrant@vagrant-ubuntu-trusty-64:/vagrant$ itamae local -l debug order.rb
 INFO : Starting Itamae...
A
B
D
E
 INFO : Recipe: /vagrant/order.rb

C

実行結果を見るとわかるように,DECより前に出力されています。これはリソースアクションCの前にリソース定義部分が評価されているためです。レシピを書く際はこの挙動にご注意ください。

リソース間の連携

例えば,特定のファイルが更新された際にサービスをリロードしたいなど,リソース間で連携を取りたい場合があると思います。notifiessubscribesで,リソースに変更があった場合に他のリソースのアクションを実行できます。

notifies

service "nginx" do
  action :nothing
end

template "/etc/nginx/conf.d/app.conf" do
  notifies :reload, "service[nginx]"
end

上記の例では,templateに更新があった場合(ファイルの内容に変更があった場合など)servicereloadアクションを実行するようになります。これにより設定ファイルが変更された時だけ,設定ファイルをリロードすることができます。

serviceに指定されてるnothingアクションはnotifiessubscribesのためのアクションで,すべてのリソースで利用可能です。nothingを指定すると,実際にはアクションが実行されずリソース定義だけが行われるので,notifiessubscribesでのみアクションが実行されます。

subscribes

subscribesnotifiesの逆で,あるリソースの変更を監視して,変更があった場合にアクションを実行することができます。

service "nginx" do
  action :nothing
  subscribes :reload, "template[/etc/nginx/conf.d/app.conf]"
end

template "/etc/nginx/conf.d/app.conf"

上記の例では先に出てきたnotifiesの例と同様,templateに変更があった場合にserviceのリロードを行います。

なお,notifiessubscribesは1つのリソースに複数指定することも可能です。

複数のリソースをまとめる

defineを使うと,複数のリソースをまとめて1つのリソースのように見せることができます。

define :install_and_enable_package, version: nil do
  package params[:name] do
    version params[:version] if params[:version]
    action :install
  end

  service params[:name] do
    action :enable
  end
end

このようにリソースを定義すると,定義以降install_and_enable_packageリソースが使えるようになります。

install_and_enable_package 'nginx' do
  version '1.4.6-1ubuntu3.3'
end

複数回同じようなリソース定義が出てくる場合はこのようにdefineを使って抽象化をすると見通しが良くなります。

他のレシピを読み込む

レシピを書いていくと,ファイルが大きくなって見通しが悪くなったり,再利用したくなる場合があります。その場合はinclude_recipeを使って他のレシピを読み込み,ファイルを分割することをお勧めします。

# cookbooks/nginx/default.rb
package "nginx"
template "/etc/nginx/conf.d/app.conf"
# cookbooks/nginx/templates/etc/nginx/conf.d/app.conf にテンプレートを置く
# cookbooks/ruby/default.rb
package "ruby" do
  version "2.2.2"
end
# roles/app.rb
include_recipe "../cookbooks/nginx/default.rb"
include_recipe "../cookbooks/ruby/default.rb"
# include_recipeにはレシピがあるディレクトリからの相対パスを指定する

このようにソフトウェアごとにディレクトリを作って,サーバの役割ごとのレシピからinclude_recipeでレシピを読み込む形を推奨しています

実際に実行する際は以下のようにroles以下のファイルを指定します。

$ itamae local roles/app.rb

まとめ

今回は比較的よく使うリソースの解説と,レシピを書きやすくする機能について紹介しました。

次回はホストごとに異なる値の渡し方・取得の仕方や,Itamaeプラグインの作り方について解説します。

著者プロフィール

荒井良太(あらいりょうた)

クックパッド株式会社 インフラエンジニア。ソフトウェアでのインフラの改善,運用の自動化に興味があり,オペレーションのない世界を夢見ている。休日はOSS活動をしていることが多い。ItamaeInfratasterの開発者。

URL:http://ryotarai.info