前回はノード属性を使って汎用的なレシピを書く方法を紹介しました。汎用的なレシピは様々な環境で利用できるので、レシピをプラグインとして公開しておくことで再利用できます。また、プラグインとして独自のリソースを定義し、レシピを簡潔に書けます。
プラグイン
Itamaeにはプラグイン機構が用意されていて、汎用的なレシピを公開したり、独自のリソースを実装することができます。プラグインはRubygemとして公開できるようになっていて、2015年8月24日(月)現在、33個のプラグインが存在します。プラグインは単なるGemなので、Bundlerを使って依存関係を管理できます。
レシピプラグイン
レシピプラグインを作ることで、レシピを再利用できる形で公開できます。レシピプラグインGemの名前はitamae-plugin-recipe-(レシピ名)
の形式にする必要があります。rubygems.orgでitamae-plugin-recipe
を検索すると既存のプラグインを探すことができます。
ここでは例としてnginx用のレシピプラグインを作ってみたいと思います。まず、bundle gem
コマンドを使って、Gemのひな形を生成します。
gemspecファイルにTODO
が含まれていると、Gemのインストールで失敗するので、修正しておきます。
レシピはlib/itamae/plugin/recipe/nginx/default.rb
に書くことで、他のレシピからinclude_recipe "nginx"
で読み込むことができます。また、複数のレシピを使い分けて読み込みたい場合は、lib/itamae/plugin/recipe/nginx/proxy.rb
のように同じディレクトリにレシピを配置すると、include_recipe "nginx::proxy"
またはinclude_recipe "nginx/proxy"
で読み込むことができます。
レシピやテンプレートの書き方は通常のレシピと同様です。できるだけ様々なシーンで利用できるように、node
の値を参照して柔軟に設定できるようにしておくことをお勧めします。このレシピが期待通り動くかどうかをServerspecでテストしましょう。Serverspecはサーバの状態を記述して想定通りの状態になっているかどうかをテストするためのフレームワークです。
まず、gemspecにServerspecへの依存を記述します。
テストはVagrantで起動した仮想マシンに対して実行するので、Vagrantfile
を生成します。なお、Vagrantのインストールについては公式ドキュメントを参照してください。
Serverspec用の設定を書きます。spec/spec_helper.rb
に以下を記述します。
Serverspecのテストを記述します。
BundlerでServerspecをインストールし、テストを実行します。
ItamaeがVagrantの仮想マシンに実行された後、テストが実行されます。プラグインをリリースする際は通常のrubygemと同様、rake release
でリリースします。
リソースプラグイン
続いて、リソースプラグインの作り方を解説します。レシピプラグインと同様にリソースプラグインのGemの名前はitamae-plugin-resource-(リソース名)
にします。ここでは例としてcron
リソースを作ってみます。レシピプラグインと同様にbundle gem
コマンドでひな形を作成します。
lib/itamae/plugin/resource/cron.rb
を編集してリソースを実装します。まず、アクションの実行前に実行される部分を書いてみます。
基本的な動作はコード内のコメントに記述しましたが、リソースの処理の基本的な流れとしては、
set_current_attributes
でホスト上の現在のリソースの状態(current)を読み込む
pre_action
でその他の処理を実行する
current
(現在の状態)とattributes
(設定したい状態)の差を埋める
といった形です。current
とattributes
を適切に設定しておくと、実行時に何が変更されるのか、変更前と変更後の値が表示されます。また、current
とattributes
に差がある場合のみ、アクション実行後にnotifies
とsubscribes
に指定したアクションが実行されます。
実際のアクションはaction_(アクション名)
メソッドに実装します。cronリソースの場合は以下のように実装しました。
ここまで何回か登場したrun_specinfra
はSpecinfraのコマンドを実行するためのメソッドです。ItamaeはSpecinfraの上で動く設計になっていて、run_specinfra
を呼ぶと対象サーバのOSなどを判定して適切なコマンドを実行してくれます。例えば、install_package
を呼ぶとUbuntuではapt-get install
、RHELではyum install
を実行します。この仕組みを利用することでItamae側にはOSごとの分岐をほぼ書かずに実装ができています。実際にどういったコマンドが利用できるかは、Specinfraのドキュメントやコードを参照してみてください。
では、ここまで実装したcronリソースを使ってみます。適当なディレクトリを用意して、Gemfileとサンプルレシピを作成して、
Bundlerを使って実行します。
/etc/cron.d
の下にファイルができていれば成功です。なお、今回実装したcronリソースのコードはGitHubにあります。
まとめ
今回はレシピをプラグインとして再利用可能な形で公開する方法、そして、Itamaeに用意されていない処理を独自リソースで行う方法を紹介しました。ぜひ、プラグインを開発して公開していただければと思います。