冪等な Playbook を記述する

AnsibleBeginner
オンラインで実践に進む

はじめに

関連する単発コマンドを 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 回目の実際の実行では追加の変更がなく、読み取り専用のチェックモードでも未適用の変更は見つかりませんでした。