最初のプレイブックを書きチェックモードで回す
目標
プレイブックでサーバーの望ましい状態を宣言し、実行前にチェックモードで影響範囲を確認できるようになります。
なぜ重要なのか
シェルスクリプトは「何をするか」を書きますが、プレイブックは「終わったときにどのような状態になっているべきか」を書きます。この違いのために、同じプレイブックを何回実行しても、結果が同じになります。その性質を生み出すのは、文法ではなくモジュールです。fileモジュールは、ディレクトリがすでにあれば何もせず、パーミッションだけが違えば、パーミッションだけを直します。逆に、command/shellは、今の状態を知らないので、常に変更したと報告します。そのため、「専用のモジュールがあるなら、シェルを使わない」という原則が、スタイルの好みではなく、正確性の問題になります。最後に、--check --diffは、本番サーバーに初めて手を付ける前の、最後の安全装置です。
ステップ
/root/ans/play/site.ymlを作成してください。プレイは1つで、nameがあり、hostsはwebです。ansible-playbook -i /root/ans/inventory/hosts.ini --syntax-checkを通過する必要があります。fileモジュールで、/root/ans/artifacts/appディレクトリをパーミッション0755で作成するタスクを追加して、実行してください。copyモジュールで/root/ans/artifacts/app/app.confを作成してください。内容に、listen_port=8080とenv=labの2行が、それぞれ1行ずつ含まれている必要があります。このとき、envの値はハードコードせず、app_env変数に切り出して、デフォルト値をlabにしてください(ステップ6でこの値を変えてみます)。- タスクを3つ以上にして、すべてのタスクに
nameを付けてください。 - 設定を扱うタスクに
configタグを付けて、--tags configで実行した出力を/root/ans/out/tags.txtに保存してください。 - プレイブックを
--check --diff -e app_env=stageで実行し、出力を/root/ans/out/check.txtに保存してください。出力のdiffにはenv=stageが見えている必要がありますが、実際の/root/ans/artifacts/app/app.confは依然としてenv=labである必要があります。このステップでは、絶対に実際に適用しないでください。 /opt/lab/fixtures/ansible/motd.seedを/root/ans/artifacts/motdにコピーしたあと、lineinfileで、Welcome=labhubとOwner=platform-teamになるように修正してください。Banner=unsetの行はそのままにしておく必要があり、Welcome=で始まる行は1つだけ残る必要があります。/opt/lab/fixtures/ansible/broken-play.ymlを/root/ans/play/fixed.ymlにコピーして、エラー4か所を修正し、実行してください。結果として、/root/ans/artifacts/fixed/report.txtにfixed by studentが含まれ、ハンドラーの定義とnotifyが生きている必要があります。
参考
- ラボのPodは、ラボごとに新しく起動します。
/root/ans/inventory/hosts.iniがなければ、最初のラボで作成したものと同じインベントリ(web1・web2・db1、ansible_host=127.0.0.1、ansible_port=2222、ansible_user=root、[prod:children]にweb・db)を、先に作り直してください。構造は、/opt/lab/fixtures/ansible/inventory.sample.iniを参考にすればよいです。 ansible-playbook -i 인벤토리 플레이북.ymlが、基本の実行形式です(プレースホルダーはインベントリとプレイブックです)。-vを増やすほど、詳しくなります。- タグで実行すると、対象でないタスクは
skippingと表示されます。 - よくある間違い1: ステップ7で、
lineinfileにregexpを指定しないことです。そうすると、同じ行が追加され続けます。 - よくある間違い2: ステップ8のエラーを、すべてYAML文法の問題だと見なすことです。引数の名前と値が間違っている場合もあるので、モジュールのドキュメントを確認してください。
プレイブックの骨組みを作って文法チェックを通過する
/root/ans/play/site.ymlを作成してください。プレイは1つで、nameがあり、hostsはwebです。ansible-playbook -i /root/ans/inventory/hosts.ini --syntax-checkを通過する必要があります。
プレイブックの最上位はリストです。各プレイにname、hosts、tasksを入れて、--syntax-checkで確認してください。
fileモジュールでディレクトリを作成する
fileモジュールで、/root/ans/artifacts/appディレクトリをパーミッション0755で作成するタスクを追加して、実行してください。
シェルコマンドの代わりに、fileモジュールを使ってください。stateの値と、modeの表記(引用符)を確認してください。
copyモジュールで設定ファイルを配置する
copyモジュールで/root/ans/artifacts/app/app.confを作成してください。内容に、listen_port=8080とenv=labの2行が、それぞれ1行ずつ含まれている必要があります。このとき、envの値はハードコードせず、app_env変数に切り出して、デフォルト値をlabにしてください(ステップ6でこの値を変えてみます)。
copyモジュールは、srcの代わりにcontentで、内容を直接渡すこともできます。複数行は、YAMLのブロックスカラーで書きます。環境の値は、あとで変えてみられるように、変数に切り出しておいてください。
すべてのタスクに名前を付ける
タスクを3つ以上にして、すべてのタスクにnameを付けてください。
タスクが3つ以上必要で、nameがないタスクが1つでもあってはいけません。
タグを付けて一部だけを実行する
設定を扱うタスクにconfigタグを付けて、--tags configで実行した出力を/root/ans/out/tags.txtに保存してください。
設定関連のタスクにtags: [config]を付けて、--tags configで実行してください。タグのないタスクも、必ず1つは残しておいてください。そうしないと、絞り込んだことが見えません。
1つ誤解しやすい点があります。--tagsで絞り込まれたタスクは、skippingと表示されません。出力からまったく消え、skipped=も0です。when:で絞り込まれたものとは異なります。そちらは、タスクが実行対象には入ったうえで条件に引っかかるので、痕跡が残ります。
チェックモードでプレビューする
プレイブックを--check --diff -e app_env=stageで実行し、出力を/root/ans/out/check.txtに保存してください。出力のdiffにはenv=stageが見えている必要がありますが、実際の/root/ans/artifacts/app/app.confは依然としてenv=labである必要があります。このステップでは、絶対に実際に適用しないでください。
--check --diffに、-eで別の値を渡してみてください。出力には変更される内容が見えますが、実際のファイルはそのままである必要があります。
既存ファイルの特定の行だけを変更する
/opt/lab/fixtures/ansible/motd.seedを/root/ans/artifacts/motdにコピーしたあと、lineinfileで、Welcome=labhubとOwner=platform-teamになるように修正してください。Banner=unsetの行はそのままにしておく必要があり、Welcome=で始まる行は1つだけ残る必要があります。
フィクスチャを/root/ans/artifacts/motdにコピーしたあと、lineinfileで修正してください。regexpで既存の行を見つけないと、行が増えてしまいます。
壊れたプレイブックを直す
/opt/lab/fixtures/ansible/broken-play.ymlを/root/ans/play/fixed.ymlにコピーして、エラー4か所を修正し、実行してください。結果として、/root/ans/artifacts/fixed/report.txtにfixed by studentが含まれ、ハンドラーの定義とnotifyが生きている必要があります。
モジュールの引数名が2つ、stateの値が1つ、最上位のキー名が1つ、間違っています。エラーメッセージがどの行を指しているかを見てください。