はじめに
冪等性(Idempotence)とは、Playbook を繰り返し実行しても、目的の状態が欠如しているか、あるいは現在の状態と異なる場合にのみシステムに変更を加える性質を指します。
この実験では、一般的な Ansible モジュールを使用してホストエイリアス用のディレクトリと設定ファイルを作成します。その後、Playbook を 2 回実行することで、2 回目の実行が安定している(変更が発生しない)ことを証明します。
冪等性練習用プロジェクトの作成
このステップでは、2 つのローカル管理ホストエイリアスを持つ小さな Ansible プロジェクトを作成します。各エイリアスは独自のディレクトリに書き込むため、1 つの RHEL 10 VM 内でホスト固有の結果を確認できます。
デフォルトの LabEx ワークスペースから開始します。
cd /home/labex/project
-p オプションは、必要に応じて親ディレクトリを作成し、ディレクトリが既に存在する場合でも成功を返すよう mkdir に指示します。
mkdir -p rhce-ansible/{inventory/group_vars,playbooks,managed,reports}
cd rhce-ansible
Ansible がインベントリを指し示し、リトライファイルを無効にするプロジェクトのデフォルト設定を作成します。
cat > ansible.cfg <<'EOF'
[defaults]
inventory = ./inventory/hosts
host_key_checking = False
retry_files_enabled = False
EOF
managed ディレクトリには Playbook によって生成されたファイルが格納され、reports ディレクトリには保存された Playbook の出力が格納されます。これらを分離しておくことで、目的のコンテンツと Ansible の実行結果を比較しやすくなります。
ローカル管理ホストと変数の定義
このステップでは、インベントリとグループ変数を作成します。エイリアスには ansible_connection=local を使用します。これは、Ansible がこの VM 上で安全に実行されながら、名前付きホストをターゲットにすることを意味します。
このステップでコマンドを実行する前に、Ansible プロジェクトディレクトリに戻ってください。これにより、LabEx が各ステップを個別に実行する場合でもコマンドが安定します。
cd /home/labex/project/rhce-ansible
1 つのグループ内に 2 つのアプリホストエイリアスを作成します。
cat > inventory/hosts <<'EOF'
[app]
app1 ansible_connection=local
app2 ansible_connection=local
EOF
グループ変数は、グループ内のすべてのホストで共有される目的の状態を記述します。
cat > inventory/group_vars/app.yml <<'EOF'
app_owner: labex
app_environment: training
app_message: Managed by Ansible common modules
EOF
Ansible が 2 つのホストを認識できることを確認します。
ansible app --list-hosts
出力には app1 と app2 がリストされるはずです。この確認は Playbook を作成する前に重要です。app をターゲットにする Play は、インベントリでそのグループに解決されるホストにしか影響を与えないためです。
目的の状態を定義する Playbook の作成
このステップでは、file、copy、lineinfile を使用する Playbook を作成します。これらのモジュールは、シェルコマンドを手動で実行するのではなく、最終的な状態を記述します。
このステップでコマンドを実行する前に、Ansible プロジェクトディレクトリに戻ってください。
cd /home/labex/project/rhce-ansible
Playbook を作成します。パスには {{ inventory_hostname }} が含まれているため、各エイリアスは独自の出力ディレクトリを取得します。
cat > playbooks/common-modules.yml <<'EOF'
---
- name: Configure app host directories with common modules
hosts: app
gather_facts: false
tasks:
- name: Ensure host directory exists
ansible.builtin.file:
path: "/home/labex/project/rhce-ansible/managed/{{ inventory_hostname }}"
state: directory
mode: '0755'
- name: Install base application configuration
ansible.builtin.copy:
dest: "/home/labex/project/rhce-ansible/managed/{{ inventory_hostname }}/app.conf"
content: |
owner={{ app_owner }}
environment={{ app_environment }}
message={{ app_message }}
mode: '0644'
- name: Ensure managed message is present
ansible.builtin.lineinfile:
path: "/home/labex/project/rhce-ansible/managed/{{ inventory_hostname }}/app.conf"
line: "message={{ app_message }}"
create: true
mode: '0644'
EOF
file タスクはディレクトリを作成し、copy タスクは完全な設定を書き込み、lineinfile タスクは単一行を強制する方法を示しています。これらのモジュールは現在の状態と目的の状態を比較するため、冪等性を保つことができます。
新しい Playbook を実行する前に構文チェックを行います。
ansible-playbook playbooks/common-modules.yml --syntax-check
Playbook の実行とファイルの確認
このステップでは、目的の状態を定義した Playbook を初めて実行します。ターゲットファイルがまだ存在しないため、最初の実行では変更が報告されるはずです。 このステップでコマンドを実行する前に、Ansible プロジェクトディレクトリに戻ってください。
cd /home/labex/project/rhce-ansible
Playbook を実行し、後の比較のために出力を保存します。
ansible-playbook playbooks/common-modules.yml | tee reports/first-run.txt
ホストディレクトリと app.conf ファイルが新規作成されるため、最初の実行では変更が報告されます。tee を使用することで、実行内容を確認しながら、冪等性チェックのために同じ出力を保存できます。
Ansible によって作成されたホスト固有のファイルを確認します。
cat managed/app1/app.conf managed/app2/app.conf
両方のファイルには同じ所有者、環境、メッセージの値が含まれているはずですが、それぞれ異なるホストエイリアスディレクトリの下に存在します。これは、Playbook が各インベントリホストに対して同じ目的の状態を適用したことを示しています。
冪等性を証明するための Playbook の再実行
このステップでは、同じ Playbook を再度実行します。ファイルは既に目的の状態と一致しているため、Ansible は両方のホストに対して変更がゼロであることを報告するはずです。 このステップでコマンドを実行する前に、Ansible プロジェクトディレクトリに戻ってください。
cd /home/labex/project/rhce-ansible
Playbook を 2 回目に実行し、出力を保存します。
ansible-playbook playbooks/common-modules.yml | tee reports/second-run.txt
要約行(recap lines)で changed=0 を探します。
grep -E 'app[12].*changed=0' reports/second-run.txt
2 回目の実行で changed=0 となることが、冪等性の重要なシグナルです。これは、モジュールが既存のファイルを検査し、修復の必要がないと判断したことを意味します。
まとめ
Ansible プロジェクトを構築し、共通モジュールを使用して目的の状態を記述し、Playbook を実行しました。そして、変更が報告されない 2 回目の実行を通じて、冪等性を証明しました。


