変わったときだけ知らせたい
Ansible のテンプレート(Jinja2)とハンドラーは、設定ファイルを変数から作り、変わったときだけ後始末を1回行う仕組みです。
屋台のメニュー表を、品の一覧から毎回作るとします。メニューが変わったときだけ店員に知らせ、変わらないなら黙っていたい。その2つを、この回で身につけます。
このレッスンのゴール
メモ
テンプレートを変数から作り、ハンドラーを1回だけ動かせる。
重要な言葉
| ことば | いみ | れい |
|---|---|---|
| テンプレート | 変数を埋め込んでファイルを作る、ひな形 | board.j2 |
| Jinja2 | テンプレートを書くための言語 | |
| for | リストの1つずつについて、同じ行を繰り返す書き方 | |
| if | 条件が成り立つときだけ、その行を出す書き方 | |
| ハンドラー | 変更があったときだけ、最後に動く作業 | |
| notify | タスクがハンドラーを呼ぶ指定 | notify: Tell the staff |
学生が入力するセルは、このプレビューでは空白です。
テンプレートは変数を埋め込むひな形
テンプレートの中では、{{ 名前 }} が変数の値に置き換わります。{% for 変数 in リスト %} から {% endfor %} までは、リストの数だけ繰り返されます。
{% if 条件 %} から {% endif %} までは、条件が真のときだけ出ます。{% %} の行そのものは、出力に残りません。ファイルにするのは、template モジュールです。
メニュー表のテンプレート
{% for item in menu %}
- {{ item }}
{% endfor %}
{% if sold_out %}
sold out today
{% endif %}
自分のフォルダを作る
mkdir -p ~/board/templatesここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
そのフォルダに入る
cd ~/boardここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
テンプレートを書く
printf '%s\n' '{% for item in menu %}' '- {{ item }}' '{% endfor %}' '{% if sold_out %}' 'sold out today' '{% endif %}' > templates/board.j2ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
品を2つ渡して作る
ansible localhost -i localhost, -c local -m ansible.builtin.template -a 'src=templates/board.j2 dest=preview.txt' -e '{"menu":["takoyaki","yakisoba"],"sold_out":false}' | grep changedここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
できたファイルを読む
cat preview.txtここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
品を1つにして売り切れにする
ansible localhost -i localhost, -c local -m ansible.builtin.template -a 'src=templates/board.j2 dest=preview.txt' -e '{"menu":["takoyaki"],"sold_out":true}' | grep changedここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
作り直したファイルを読む
cat preview.txtここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
ハンドラーは変わったときだけ最後に1回
タスクに notify と書くと、ハンドラーの名前を呼べます。呼ばれたハンドラーは、プレイの最後にまとめて動きます。
同じハンドラーを何回呼んでも、動くのは1回です。呼んだタスクがどれも変更しなかったときは、1回も動きません。ハンドラーが動く順番は、呼んだ順でなく、書いた順です。
2つのタスクが呼ぶプレイブックを書く
printf '%s\n' '- hosts: localhost' ' gather_facts: false' ' vars:' ' menu: [takoyaki, yakisoba]' ' sold_out: false' ' tasks:' ' - name: Write the board' ' ansible.builtin.template:' ' src: board.j2' ' dest: board.txt' ' notify: Tell the staff' ' - name: Write the stamp' ' ansible.builtin.copy:' ' content: open' ' dest: stamp.txt' ' notify: Tell the staff' ' handlers:' ' - name: Tell the staff' ' ansible.builtin.debug:' ' msg: the handler ran' > play.ymlここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
1回目: 2つとも変わる
ansible-playbook -i localhost, -c local play.yml | grep -E "^(TASK|RUNNING HANDLER)|changed:"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
2回目: ハンドラーの回数を数える
ansible-playbook -i localhost, -c local play.yml | grep -c "RUNNING HANDLER"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
売り切れにして実行する
ansible-playbook -i localhost, -c local play.yml -e sold_out=true | grep -E "^(TASK|RUNNING HANDLER)|changed:"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
作り直した表を読む
cat board.txtここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
よくある間違い
注意
ハンドラーは、呼ばれた回数だけ動くと思いがちです。実際は、何回呼ばれても1回で、しかも呼んだタスクが変更したときだけです。変更がなければ、動きません。だから、何度実行しても、むだな再起動が起きません。