■ はじめに
Ansible には Playbook Debugger という、Playbook 実行時に変数の値を確認、変更などできる機能があります。
参考
タスク変数も変更できますが、変更後、タスクを再実行しても変更前の値のまま再実行してしまう現象があります。
2.5 系 から 2.7 系までが対象です。2.4 系では発生しない現象でした。次期バージョンの Ansible 2.8 で、追加される Debugger のコマンド update_task
によって改修される予定です。
この記事ではこの現象についてご紹介します。
■ 公式ドキュメントに記載の手順は正しくタスク変数の値が変更できない
本記事執筆時点で、最新安定版(2.7対応)のドキュメントの Playbook Debugger の説明ページには、以下のようなタスス変数の変更手順が記載されています。
- Playbook
- hosts: test strategy: debug gather_facts: yes vars: pkg_name: not_exist tasks: - name: install package apt: name={{ pkg_name }}
- デバッガ操作手順
[192.0.2.10] TASK: install package (debug)> p task_vars['pkg_name'] u'not_exist' [192.0.2.10] TASK: install package (debug)> task_vars['pkg_name'] = 'bash' [192.0.2.10] TASK: install package (debug)> p task_vars['pkg_name'] 'bash' [192.0.2.10] TASK: install package (debug)> redo
手順はここで終わっていて、redo
の結果が記載されていません。これを実際試すと redo
後にエラーにってしまいます。
(環境の都合上、apt
ではなく yum
モジュールを利用しますが、現象に影響はありません)
$ ansible-playbook -i localhost, debuger_ad.yml PLAY [localhost] ************************************************* TASK [Gathering Facts] ******************************************* ok: [localhost] TASK [install package] ******************************************* fatal: [localhost]: FAILED! => {"changed": false, "msg": "No package matching 'not_exist' found available, installed or updated", "rc": 126, "results": ["No package matching 'not_exist' found available, installed or updated"]} [localhost] TASK: install package (debug)> redo fatal: [localhost]: FAILED! => {"changed": false, "msg": "No package matching 'not_exist' found available, installed or updated", "rc": 126, "results": ["No package matching 'not_exist' found available, installed or updated"]} [localhost] TASK: install package (debug)> task_vars['pkg_name'] = 'bash' [localhost] TASK: install package (debug)> p task_vars['pkg_name'] 'bash' [localhost] TASK: install package (debug)> redo fatal: [localhost]: FAILED! => {"changed": false, "msg": "No package matching 'not_exist' found available, installed or updated", "rc": 126, "results": ["No package matching 'not_exist' found available, installed or updated"]} [localhost] TASK: install package (debug)>
redo
後も、not_exist
というパッケージ名を探していて、見つからないためエラーになっています。つまり、task_vars['pkg_name'] = 'bash'
のようにタスク変数を書き換えても、実際のタスク実行上に利用する値は変更前(この場合 not_exits
)ということになります。
■ 2.7 までのワークアラウンド
変更した(見かけ上の)タスク変数の値をタスクのオプション(task.args['name']
)に代入すれば、変更後の値で redo
できます。
(...略...) [localhost] TASK: install package (debug)> task_vars['pkg_name'] = 'bash' [localhost] TASK: install package (debug)> p task_vars['pkg_name'] 'bash' [localhost] TASK: install package (debug)> task.args['name'] = '{{ pkg_name }}' [localhost] TASK: install package (debug)> redo ok: [localhost] PLAY RECAP ***************************************************************** localhost : ok=1 changed=0 unreachable=0 failed=0
もちろん、タスク変数を経由せずに、最初から task.args['name'] = 'bash'
のようにタスクのオプションの値を直接変更しても、正常に redo
できます。
(...略...) [localhost] TASK: install package (debug)> task.args['name'] = 'bash' [localhost] TASK: install package (debug)> redo ok: [localhost] PLAY RECAP ***************************************************************** localhost : ok=1 changed=0 unreachable=0 failed=0
■ 2.8 からの新しい手順で正しく変更
次期バージョンの Ansible 2.8 の Playbook Debugger では update_task
というコマンドが利用できます。
このコマンドにより、Debuger 上で変更したタスク変数の値を、正しく redo
時にタスクが利用できます。
次期バージョン(2.8/devel)のドキュメントにも以下の手順が記載されています。
[192.0.2.10] TASK: install package (debug)> p task_vars['pkg_name'] u'not_exist' [192.0.2.10] TASK: install package (debug)> task_vars['pkg_name'] = 'bash' [192.0.2.10] TASK: install package (debug)> p task_vars['pkg_name'] 'bash' [192.0.2.10] TASK: install package (debug)> update_task [192.0.2.10] TASK: install package (debug)> redo
■ [補足] Ansible 2.4 では本現象は発生しない
Ansible 2.4 にも Playbook Debugger 機能はあります(debugger
ディレクティブではなく、strategy: debug
としての機能)。2.4 では本件の現象は発生せず、通常の手順で変更後のタスク変数の値でタスクを再実行できます。
$ ansible --version ansible 2.4.0.0 (...略...) $ ansible-playbook -i localhost, debuger_ad.yml PLAY [localhost] ************************************************************ TASK [Gathering Facts] ****************************************************** ok: [localhost] TASK [install package] ****************************************************** fatal: [localhost]: FAILED! => {"changed": false, "failed": true, "msg": "No package matching 'not_exist' found available, installed or updated", "rc": 126, "results": ["No package matching 'not_exist' found available, installed or updated"]} Debugger invoked (debug) p vars['pkg_name'] u'not_exist' (debug) vars['pkg_name'] = 'bash' (debug) p vars['pkg_name'] 'bash' (debug) redo ok: [localhost] PLAY RECAP ***************************************************************** localhost : ok=2 changed=0 unreachable=0 failed=0
※ Ansible 2.4 までは、タスク変数は vars
内に格納されていましたが、Python のオブジェクト名と重複するため、2.5 で task_vars
に変更されました。
■ まとめ
- Ansible 2.5 系 から 2.7 系までの Playbook Debugger で、タスク変数の値を変更後に
redo
しても、変更前の値のまま再実行してしまう - ワークアラウンドはタスクのオプション
task.args
への代入 - Ansible 2.8 で改修予定(
update_task
コマンドの追加)
参考
- 対応issue
- 対応PR