インベントリを作りアドホックで叩く
目標
インベントリに自動化の対象を定義し、プレイブックなしで、アドホックコマンドだけで、複数のサーバーを一度に扱えるようになります。
なぜ重要なのか
自動化ツールを学ぶとき、人は「何を実行するか」から知りたがりますが、実際の事故は、ほとんどの場合「誰に対して実行されたか」で起きます。インベントリは、その対象をファイルで固定しておく仕組みです。グループは、単なる別名ではなく、変数が流れる通り道でもあります。[web:vars]に入れた値は、webグループのホストにだけ届き、ホスト個別の変数は、それをさらにオーバーライドします。この優先順位を知らないと、「設定がなぜ効かないのか」という疑問に1日を費やします。そして、対象を絞り込むときは、必ず実行オプション(--limit)を使ってください。インベントリを一時的に直す習慣は、そのファイルがコミットされた瞬間に、長期の障害に変わります。
ステップ
/root/ans/inventory/hosts.iniを作成してください。webグループにweb1、web2、dbグループにdb1を入れ、3つのホストすべてに、ansible_host=127.0.0.1、ansible_port=2222を持たせてください。- 同じファイルに、
[web:vars]でapp_port=8080を、[all:vars]でansible_user=rootを追加してください。app_portは、db1では見えてはいけません。 [prod:children]セクションを作成して、webとdbの2つのグループを子として入れてください。prodにホストを直接書かないでください。/root/ans/inventory/hosts.ymlに、同じ構造(ホスト3つ、グループweb/db/prod、ansible_hostの値)を、YAML形式で表現してください。ansible -i hosts.ini all -m pingを実行し、出力全体を/root/ans/out/ping.txtに保存してください。3つのホストすべてがSUCCESSである必要があります。- アドホックの
fileモジュールで、/root/ans/artifacts/adhoc.dディレクトリを、パーミッション0750で作成してください。 webグループだけを対象にして、アドホックをもう一度実行し、出力を/root/ans/out/limit.txtに保存してください。db1が結果に出てきてはいけません。/root/ans/out/report.txtを作成してください。prodに属するすべてのホストを、그룹:호스트の形式(プレースホルダーはグループとホストです)で1行に1つずつ、辞書順にソートして入れます。db:db1、web:web1、web:web2の3行です。
参考
ansible-inventory -i hosts.ini --listで、実際の解釈結果をJSONで見られます。--graphは、グループの階層をツリー状に表示します。- この環境のsshdは、
127.0.0.1:2222で、キー認証で動作します。 - よくある間違い1:
[prod:children]にホスト名を書いてしまうことです。childrenセクションにはグループ名だけが入ります。 - よくある間違い2: ステップ8で
.prod.hostsをそのまま読んでしまうことです。prodは子グループを通してホストを持つので、子をたどって下りる必要があります。
INIインベントリにweb・dbグループを作成する
/root/ans/inventory/hosts.iniを作成してください。webグループにweb1、web2、dbグループにdb1を入れ、3つのホストすべてに、ansible_host=127.0.0.1、ansible_port=2222を持たせてください。
INIインベントリは、[그룹이름]の下に、ホストを1行ずつ書きます。接続情報は、ホストの後ろに키=값の形で付けます(プレースホルダーはグループ名、キー、値です)。この環境のsshdのポートを確認してください。
グループ変数とグローバル変数を入れる
同じファイルに、[web:vars]でapp_port=8080を、[all:vars]でansible_user=rootを追加してください。app_portは、db1では見えてはいけません。
[그룹:vars]セクションはそのグループにだけ、[all:vars]はすべてのホストに適用されます(プレースホルダーはグループ名です)。dbにはapp_portが見えてはいけません。
上位グループprodにまとめる
[prod:children]セクションを作成して、webとdbの2つのグループを子として入れてください。prodにホストを直接書かないでください。
[이름:children]セクションには、ホストではなくグループ名を書きます(プレースホルダーは名前です)。prodにホストを直接書いてはいけません。
同じ構造をYAMLで書き直す
/root/ans/inventory/hosts.ymlに、同じ構造(ホスト3つ、グループweb/db/prod、ansible_hostの値)を、YAML形式で表現してください。
YAMLインベントリは、最上位がall:で、その下にchildren:、hosts:、vars:が来ます。結果が同じかどうかを、ansible-inventory --listで比較してください。
3つのホストにpingモジュールを実行する
ansible -i hosts.ini all -m pingを実行し、出力全体を/root/ans/out/ping.txtに保存してください。3つのホストすべてがSUCCESSである必要があります。
アドホックは、ansible -i 인벤토리 대상 -m 모듈の形です(プレースホルダーはインベントリ、対象、モジュールです)。pingモジュールは、ICMPではなく、Pythonが動いているかを確認します。出力をファイルに残してください。
アドホックでディレクトリを作成する
アドホックのfileモジュールで、/root/ans/artifacts/adhoc.dディレクトリを、パーミッション0750で作成してください。
fileモジュールに、-aで引数を渡します。path=、state=、mode=の3つが必要で、modeは引用符で囲むほうが安全です。
対象をwebグループに絞り込む
webグループだけを対象にして、アドホックをもう一度実行し、出力を/root/ans/out/limit.txtに保存してください。db1が結果に出てきてはいけません。
インベントリを直さず、実行側で絞り込みます。グループ名を対象として指定するか、--limitを使ってください。
グループごとのホストのレポートを作成する
/root/ans/out/report.txtを作成してください。prodに属するすべてのホストを、그룹:호스트の形式(プレースホルダーはグループとホストです)で1行に1つずつ、辞書順にソートして入れます。db:db1、web:web1、web:web2の3行です。
ansible-inventory --listのJSONをjqで加工します。prodは子グループを通してホストを持つという点に注意してください。ソートも必要です。