AnsibleのDynamic Inventoryを使ってOpenStackやMackerelから適用先を自動取得する

AnsibleにDynamic Inventoryという機能があることを知った。Ansibleではインベントリという機能があり、適用先やグループ分けをファイルに書くことで適用するプレイブックを切り替えられる。しかし、これは静的なため、サーバーの台数が多いと管理が不便なこともある。Dynamic Inventoryを使えば動的に適用先を取得できるようだが、まだ試したことがなかったので、試してみる。

準備

まず、以下のようなサーバーを用意する。全てFloatingIPを付与していて、直接SSHできる。

復習: Static Inventory

しばらくAnsibleから離れていたので、Dynamic Inventoryの前にStaticな方の挙動を確認しておくことにする。SSHするユーザやプライベートキーをansible.cfgに設定。

インベントリは以下のように、inventoryというファイルを用意してベタ書きする。

各サーバーに対してpingするようなplaybookを用意する。

これで、ansibleを実行すると、各サーバーにpingしていることが確認できる。

本題1: Dynamic Inventory

次にDynamic Inventoryだ。OpenStackのダイナミックインベントリについての公式ドキュメントを見つつやってみる。openstack.pyをダウンロードしてきて、オプションに指定する。OpenStackのAPIを使えるように環境変数を設定しておくのを忘れないこと。また、ansible_python_interpreterはオプションで指定した。

なるほど、ちゃんとAPIから適用先を取得して適用できる。適用先名がサーバーのIDになっていて読みにくいが、これはopenstack.pyに少し手を入れれば直せそうだ。

本題2: Dynamic Inventory を使って適用するプレイブックを変更する

さて、動的に適用先サーバーを取得できることがわかった。となると、次はメタデータを使って適用するロールを変更する、ということがやりたくなるのは自明である。実は、node-001〜node-003には以下のようにメタデータを設定してある。node-001とnode-002はgroup01、node-003はgroup02という具合だ。

test.ymlに、group01とgroup02用の処理を書き足す。

この状態でansible-playbookを実行すると、group01とgroup02で実行するタスクが違っていることが確認できる。なるほど便利だ…

応用:Dynamic InventoryとしてMackerelを利用する

さて、openstack.pyが1ファイルのスクリプトであることから、自分でDynamic Inventoryを定義することもできる。今回はMackerelを使ってみる。OpenStackではメタデータからグループを取得していたが、Mackerelではロールを代わりに使ってみよう。まずはわかりやすくするため、サーバーに付与するIPアドレスを直接アクセス可能なものに変更する。

また、Mackerel上でそれぞれのサーバーにロールを設定する。OpenStackの時と同様、node-001と002がgroup01、node-003がgroup02だ。

DynamicInventoryの作り方の記事としては Ansible Dynamic Inventoryをつくろう! と Developing Dynamic Inventory Sources を参考にした。スクリプトは以下の通り。今回は試すだけなので、かなり手抜き…

このスクリプトを単体で実行すると、以下のようになる。

最後に、ansible-playbookで動作確認。ロールによって適用されるタスクがちゃんと違っていることがわかる。なるほどねー。

まとめ

AnsibleのDynamic Inventoryを試し、動的に適用先を取得できること、メタデータによって適用するプレイブックを変更できることを確認した。今回はansibleが用意していたOpenStackと、Mackerel用のスクリプトを書いてみた。他にもConsulのようなAPIも使えそうだ。また、ChefやPuppetにも同様の機能がないか調べてみたいところだ。

参考文献