TT Lab
はじめる
学ぶ 学習パス コース

Ansible実戦

再利用できるロールを作る

TT Labで続きを見る

目標

プレイブックの断片をロールにまとめて再利用可能な単位にし、同じロールを異なる値で複数回呼び出せるようになります。

なぜ重要なのか

ロールの本質は「コードを分けること」ではなく、「規約を決めておいて、設定なしで再利用できるようにすること」です。templates/に置いたファイルはパスを書かなくても見つかり、handlers/main.ymlのハンドラーは登録の手続きなしで使えます。この規約のおかげで、他人が作ったロールも構造を推測できます。再利用性を実際に決めるのは、defaultsとvarsの選択です。ユーザーが変更する値をvarsに置くと優先度が高く、外からオーバーライドできず、そのロールは結局コピー・修正されて再び分岐します。そして、変数名にロール名をプレフィックスとして付ける習慣は、ロールが2つを超えた瞬間に価値を発揮します。

ステップ

  1. /root/ans/roles/roles/webappの下に、tasks、defaults、handlers、templates、metaディレクトリとtasks/main.ymlを作成してください。
  2. /root/ans/roles/roles/webapp/defaults/main.ymlに、webapp_port: 8080とwebapp_root: /root/ans/roles/artifactsを定義してください。
  3. /root/ans/roles/roles/webapp/tasks/main.ymlに名前の付いたタスクを2つ以上入れ、実行すると/root/ans/roles/artifactsディレクトリが作られるようにしてください。
  4. /root/ans/roles/roles/webapp/templates/webapp.conf.j2を作成し、/root/ans/roles/artifacts/webapp.confへレンダリングしてください。結果にport = 8080の行があり、テンプレートはwebapp_port変数を参照している必要があります。
  5. /root/ans/roles/roles/webapp/handlers/main.ymlにrestart webappハンドラーを定義し、/root/ans/roles/roles/webapp/tasks/main.ymlのタスクからnotifyしてください。ハンドラーは/root/ans/roles/artifacts/restart.markerを作成します。
  6. /root/ans/roles/roles/baselineロール(エントリポイントは/root/ans/roles/roles/baseline/tasks/main.yml)を作成して/root/ans/roles/artifacts/baseline.stampを残すようにし、/root/ans/roles/roles/webapp/meta/main.ymlのdependenciesに宣言してください。
  7. /root/ans/roles/site.ymlでwebappロールを2回呼び出してください。1回はデフォルト値で(webapp.conf、port 8080)、もう1回はwebapp_port: 9443で/root/ans/roles/artifacts/staging.confを作るようにします。ロールのディレクトリをコピーしてはいけません。
  8. プレイブックを2回目に実行した出力を/root/ans/roles/out/run2.txtに、ansible-lintの結果を/root/ans/roles/out/lint.txtに保存してください。2回目の実行はchanged=0で、ハンドラーが動かない必要があります。

参考

ロールのスケルトンディレクトリを作る

/root/ans/roles/roles/webappの下に、tasks、defaults、handlers、templates、metaディレクトリとtasks/main.ymlを作成してください。

ansible-galaxy role initが標準構造を作ってくれます。必要なディレクトリはtasks/defaults/handlers/templates/metaです。

デフォルト値を2つ定義する

/root/ans/roles/roles/webapp/defaults/main.ymlに、webapp_port: 8080とwebapp_root: /root/ans/roles/artifactsを定義してください。

オーバーライドされることを想定した値は、defaultsに置きます。名前にはロール名のプレフィックスを付けてください。

ロールのタスクを書いて実行する

/root/ans/roles/roles/webapp/tasks/main.ymlに名前の付いたタスクを2つ以上入れ、実行すると/root/ans/roles/artifactsディレクトリが作られるようにしてください。

tasks/main.ymlがエントリポイントです。タスクは2つ以上で、すべてに名前が必要です。

ロールのテンプレートで設定ファイルを作る

/root/ans/roles/roles/webapp/templates/webapp.conf.j2を作成し、/root/ans/roles/artifacts/webapp.confへレンダリングしてください。結果にport = 8080の行があり、テンプレートはwebapp_port変数を参照している必要があります。

templates/の中のファイルは、名前だけを書けば見つかります。ポートの値はハードコードせず、変数を使ってください。

ロールのハンドラーを定義して発火させる

/root/ans/roles/roles/webapp/handlers/main.ymlにrestart webappハンドラーを定義し、/root/ans/roles/roles/webapp/tasks/main.ymlのタスクからnotifyしてください。ハンドラーは/root/ans/roles/artifacts/restart.markerを作成します。

handlers/main.ymlのハンドラーは自動的に登録されます。実行されたらマーカーファイルを残してください。

依存ロールを設定して先に実行させる

/root/ans/roles/roles/baselineロール(エントリポイントは/root/ans/roles/roles/baseline/tasks/main.yml)を作成して/root/ans/roles/artifacts/baseline.stampを残すようにし、/root/ans/roles/roles/webapp/meta/main.ymlのdependenciesに宣言してください。

baselineロールを別に作り、meta/main.ymlのdependenciesに書きます。依存ロールが先に実行されます。

同じロールを異なる値で2回呼び出す

/root/ans/roles/site.ymlでwebappロールを2回呼び出してください。1回はデフォルト値で(webapp.conf、port 8080)、もう1回はwebapp_port: 9443で/root/ans/roles/artifacts/staging.confを作るようにします。ロールのディレクトリをコピーしてはいけません。

プレイのrolesセクションで、ロール名と一緒に変数を渡せます。ロールをコピーしてはいけません。

再実行での冪等性とリントの通過

プレイブックを2回目に実行した出力を/root/ans/roles/out/run2.txtに、ansible-lintの結果を/root/ans/roles/out/lint.txtに保存してください。2回目の実行はchanged=0で、ハンドラーが動かない必要があります。

2回目の実行でchanged=0になり、ハンドラーも動かない必要があります。ansible-lintの結果も残してください。