クリーム色の背景、色付き表示、高コントラスト、大きな文字のほうが読みやすいですか?配色と文字を選ぶと、すべてのページに一度で反映されます。

無料レッスン

冪等性とドリフト

このレッスンのあとで: プレイブックを2回実行し、何が変わったか、なぜ変わったかを言える。

60分のレッスンコマンド10件Ansible のラボ:プレイブックでマシンを設定する(ブラウザーで)

誰かが手で直したサーバー

午前2時、店の掲示は「休業」のはずが「営業中」になっています。誰かが本番サーバーのファイルを直し、誰にも伝えませんでした。

次にプレイブックを実行したとき、それに気づいてファイルを戻してほしいところです。このレッスンでは、その方法と、何も変えずに先に確認する方法を学びます。

このレッスンのゴール

メモ

プレイブックを2回実行し、何が変わったか、なぜ変わったかを言える。

重要な言葉

ことばいみれい
冪等もう一度実行しても、何も変わらないこと
ドリフト現実が、書いた説明と合わなくなること
チェックモード変更を行わず、変わる内容だけ知らせる実行--check
差分変わる行--diff
リキャップ実行の最後に出る合計PLAY RECAP

学生が入力するセルは、このプレビューでは空白です。

プレイブックは手順でなく結果を書く

タスクは、ファイルがどうあるべきかを書きます。何を打つかは書きません。ファイルがすでに正しければ、何もせず ok と知らせます。違っていれば、直して changed と知らせます。

だから良いプレイブックは冪等です。2回目の実行は、変更なしと知らせます。

フォルダを作って入る

コマンド
mkdir -p ~/iac-demo/drift && cd ~/iac-demo/drift

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

タスク1つのプレイブックを書く

コマンド
printf '%s\n' '- hosts: localhost' '  connection: local' '  gather_facts: false' '  vars:' '    hours: "9時から17時まで営業"' '  tasks:' '    - name: write the notice' '      ansible.builtin.copy:' '        dest: ./notice.txt' '        content: "{{ hours }}\n"' '        mode: "0644"' > site.yml

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

1回目の実行

コマンド
ansible-playbook -i localhost, site.yml | grep -E "changed="

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

もう一度実行する

コマンド
ansible-playbook -i localhost, site.yml | grep -E "changed="

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

ドリフトは記録されない変更

ドリフトとは、現実が説明と合わなくなることです。多くは、誰かが手で直したことで起きます。冪等だと、ドリフトを直しやすくなります。

まずプレイブックをチェックモードで実行します。変わる内容を知らせ、--diff は行を見せますが、何も書き込みません。

ファイルを手で直す

コマンド
echo "一週間休業" > notice.txt; cat notice.txt

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

まずチェックと差分で見る

コマンド
ansible-playbook -i localhost, site.yml --check --diff | grep -E "^[-+][^-+]|changed="

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

ファイルをもう一度読む

コマンド
cat notice.txt

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

本当に実行し、もう一度実行する

コマンド
ansible-playbook -i localhost, site.yml | grep -E "changed="; cat notice.txt; ansible-playbook -i localhost, site.yml | grep -E "changed="

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

shellタスクは変化を見分けられない

copy モジュールは、ファイルを望む内容と比べます。shell モジュールはコマンドを実行するだけで、何か変わったかを知りません。毎回 changed と知らせます。

Ansible のラボが、shell コマンドだけのプレイブックを断るのは、この理由です。

同じ仕事をshellコマンドで書く

コマンド
printf '%s\n' '- hosts: localhost' '  connection: local' '  gather_facts: false' '  tasks:' '    - name: write with a shell' '      ansible.builtin.shell: echo "9時から17時まで営業" > ./shell.txt' > shell.yml

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

2回実行する

コマンド
ansible-playbook -i localhost, shell.yml | grep -E "changed="; ansible-playbook -i localhost, shell.yml | grep -E "changed="

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

よくある間違い

注意

1回目に changed=0 なら、プレイブックは役に立つことをしていない、と考える人が多くいます。意味するのは、マシンがすでに望む状態だったということです。毎回 changed と出る実行はドリフトを隠します。本物の変更が、普通の変更と同じに見えるからです。

OpenTofuはstateでドリフトを探す

本物のプロバイダがあれば、tofu plan はまず本物のサービスに何があるかを尋ね、stateとの違いを見せます。手での変更に気づけるのは、そのためです。

ラボの terraform_data は値だけを持ち、OpenTofu の外には何もありません。手で直せるものがないので、このレッスンではファイルを使います。

収束をPythonで計算

コード: python
# マシンを望む状態に合わせ、変わった数を数えます。
wish = {"hours": "9時から17時まで営業", "phone": "0100"}
machine = {"hours": "休業", "extra": "そのままにする"}
changed = 0
for name in wish:
    if name not in machine or machine[name] != wish[name]:
        machine[name] = wish[name]
        changed = changed + 1
print("changed =", changed)
# ループをもう一度実行して、changed を見てみましょう。

さらに進む: 望む状態を変える

ansible-playbook -i localhost, site.yml -e '{"hours": "10時から16時まで営業"}' | grep -E "changed=" を実行し、続けて cat notice.txt を実行します。同じコマンドをもう一度実行します。

1回目はファイルが変わり、2回目は変わらないのはなぜですか。どの変数が勝ちましたか。

このラボとソースについて: Ansible のラボ:プレイブックでマシンを設定する(ブラウザーで)

授業で使いますか?このモジュールを学生に割り当てると、教員用ガイド、自動採点つきの課題、学生ごとのラボを使えます。