はじめに
関連する単発コマンドを Playbook に保存すると、繰り返しの実行やレビューが容易になります。有用な Playbook は、安定した望ましい状態を記述し、意図したすべての対象で観察可能な結果を生み出します。
file モジュールと copy モジュールを使って小さな YAML Playbook を記述し、2 つの SSH ノードに適用して、作成されたファイルと、変更がゼロとなる再実行の両方を検証します。この実習では、変数、ループ、ロールを使わずに、Play、タスク、冪等性を紹介します。
YAML で Playbook を記述する
このステップでは、すでに練習した file と copy モジュールを、再利用可能な Playbook にまとめます。
ターミナルでプロジェクトに移動します。
cd /home/labex/project
Playbook は、Play の YAML リストです。各 Play は、ホストパターンを順序付きのタスクリストに結び付けます。各タスクは、モジュールとその引数を指定します。name のラベルは出力を読みやすくしますが、それ自体で設定を作成するものではありません。
YAML はインデントでデータを入れ子にします。タブではなくスペースを使ってください。先頭の - はリスト項目の開始を示し、コロンはキーの値を導入します。ここでは tasks に 2 つのモジュールタスクが含まれます。"0750" のように引用符で囲んだモードは、権限の文字列のまま扱われます。これらの固定状態のタスクはファクトを利用しないため、gather_facts: false は自動的なファクト収集を省略します。
前に練習したように、引用符付きのヒアドキュメントでファイルを作成します。最後の EOF 行までコピーしてください。
cat > workspace.yml <<'EOF'
- name: Prepare managed workspaces
hosts: all
gather_facts: false
tasks:
- name: Create the workspace directory
ansible.builtin.file:
path: /home/automation/workspace
state: directory
mode: "0750"
- name: Write the workspace notice
ansible.builtin.copy:
dest: /home/automation/workspace/README.txt
content: "Workspace managed by Ansible\n"
mode: "0640"
EOF
最初のタスクはディレクトリを宣言します。2 番目は、コントローラーの src ファイルを読む代わりに、copy の content 引数でリテラルテキストを直接指定します。二重引用符で囲まれた YAML 文字列は、\n を末尾の改行として解釈します。固定内容は再実行を安定させます。毎回変わるタイムスタンプは追加しないでください。
この Play の hosts: all は、用意された両方の SSH ノードを意味します。通常のタスクは automation として実行されるため、become なしでそのホームディレクトリに書き込めます。
ansible-playbook は Playbook ファイルを実行します。まず --syntax-check で、タスクを適用せずに構造を検証します。
ansible-playbook workspace.yml --syntax-check
Playbook を識別する行が表示され、パーサーエラーはないはずです。構文検証だけでは、リモート接続や最終ファイルの正しさは証明できません。
--list-hosts で Play のホスト選択をプレビューします。
ansible-playbook workspace.yml --list-hosts
Play には web1 と web2 が表示される必要があります。空のリストは、使用可能な 2 ホストの Playbook とはいえません。
望ましい状態を適用する
このステップでは、Playbook を実行し、実際のリモート結果を調べます。
設定とインベントリが選択されるように、プロジェクトからファイルを実行してください。
ansible-playbook workspace.yml
Ansible は各 Play とタスクの名前を表示し、最後に PLAY RECAP を表示します。新しい環境では、2 つのタスクが各ホストを変更するはずです。
web1 : ok=2 changed=2 unreachable=0 failed=0 ...
web2 : ok=2 changed=2 unreachable=0 failed=0 ...
空白やホストの順序は異なる場合があります。ok は成功したタスク数、changed は変更が必要だったタスク数です。unreachable と failed はどちらもゼロになるはずです。タスク名の成功表示だけでは、必要なファイルのバイト列や権限は証明できません。
アドホックの command モジュールで、各リモート通知を読みます。
ansible all -m ansible.builtin.command -a 'cat /home/automation/workspace/README.txt'
両方の標準出力に Workspace managed by Ansible と表示されるはずです。読み取り専用のコマンドによる問い合わせでも、CHANGED が報告されることがあります。Playbook の file/copy の結果は、宣言された状態を示します。管理対象ディレクトリのモードは 0750、通知のモードは 0640 で、両方の所有者は automation です。
冪等な収束を検証する
このステップでは、Playbook を繰り返し、一致した状態では追加の変更が不要なことを確認します。
冪等性とは、同じ望ましい状態を繰り返し適用しても、収束後に不要な変更が生じないことです。同じ Playbook をもう一度実行してください。
ansible-playbook workspace.yml
各対象の recap は、ok=2、changed=0、unreachable=0、failed=0 になるはずです。両方のファイルは存在し、正しい状態を保ちます。毎回変わるタイムスタンプや、無条件の汎用コマンドは、この安定した結果を損ないます。
--check はプレビューを要求します。対応するモジュールは、変更を適用せずに予測します。file と copy は両方とも、この手順に対応しています。収束した Playbook をプレビューしてください。
ansible-playbook workspace.yml --check
再び、両ホストの変更はゼロになるはずです。プレビューは、最初の実際の実行や実際の状態の調査の代わりにはなりません。ここでは、すでに作成された作業スペースが宣言と一致することを確認します。
今後再利用できるよう、Playbook を残してください。きれいな recap を作り出すために、changed_when で変更を抑制したり、タスクを強制的にチェックモードの対象外にしたりしないでください。結果は、実際に状態が一致していることを反映する必要があります。
まとめ
ホスト選択と順序付きのモジュールタスクを YAML で表現し、構文と対象範囲を確認して、2 つの実際の管理対象ノードに Playbook を適用しました。実際のファイル状態は要件に一致し、2 回目の実際の実行では追加の変更がなく、読み取り専用のチェックモードでも未適用の変更は見つかりませんでした。



