はじめに
意図しないまま実行を進めないようにするため、ちょっとしたことでもエラーに倒して早めに処理を止める設定の紹介です。インベントリ周りが中心です。
ansible.cfg
[defaults] duplicate_dict_key=error [inventory] host_pattern_mismatch=error any_unparsed_is_failed=True
要件などに合わせて調整は必要かと思いますが、このあたりからベースにすると良いのではないかと思っています。
インベント周りはデフォルトでは結構ゆるい印象があります。
以下詳細(ansible 2.9.23 で確認)です。
YAMLのキーの重複時の挙動の指定(DUPLICATE_YAML_DICT_KEY
)
YAMLのキーの重複時の挙動を指定する。デフォルトは warn
で、警告を表示して処理を継続する。
例えば以下の Playbook では、モジュール名である debug
が重複している。
--- - hosts: ios gather_facts: false tasks: - name: debug: msg: msg1 debug: msg: msg2
これを実行すると、警告が表示されるが処理を続ける。後に定義したキーが優先される。
$ ansible-playbook -i inventory.ini test.yml [WARNING]: While constructing a mapping from /home/ansible/test.yml, line 10, column 7, found a duplicate dict key (debug). Using last defined value only. PLAY [ios] ******************************************************************************************************** TASK [debug] ****************************************************************************************************** ok: [ios01] => { "msg": "msg2" } PLAY RECAP ******************************************************************************************************** ios01 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 $ echo $? 0
キーの重複時にエラーとしたい場合は error
を指定する。
[defaults] duplicate_dict_key=error
この設定で Playbook を実行すると以下のようにエラーとなる。エラーメッセージは分かりにくい。
$ ansible-playbook -i inventory.ini test.yml ERROR! Unexpected Exception, this is probably a bug: 'NoneType' object has no attribute 'line' to see the full traceback, use -vvv $ echo $? 250
なお、モジュール指定の重複だけでなく、オプションや変数名の重複(同一YAML内)でもエラーになる。
hosts の指定が誤っている場合の挙動の指定(HOST_PATTERN_MISMATCH
)
Playbook の hosts:
の指定したホストやグループ名が、インベントリ内に見つからない場合の挙動。デフォルトは warning
で、警告を表示するのみ。ansible-playbook
コマンドのリターンコードは正常 0
となる。
$ ansible-playbook -i inventory.ini test.yml [WARNING]: Could not match supplied host pattern, ignoring: not_existed PLAY [not_existed] ************************************************************************************************ skipping: no hosts matched PLAY RECAP ******************************************************************************************************** $ echo $? 0
この場合、Ansible Tower のワークフローとしても正常扱いで次のジョブテンプレートへと進む。
hosts
の指定先がインベントリ内に見つからない状況は、その後に想定外の状況を引き起こしかねないので、エラーとして扱って処理を中止した場合もある。特に hosts: "{{ target_host }}"
のように変数で指定する場合は、起こりやすい。
エラーとして扱う場合は ansible.cfg
で以下のように設定する。defaults
セクションではないので注意。
[inventory] host_pattern_mismatch=error
以下のように、エラー扱い(リターンコード 1
)となる。
$ ansible-playbook -i inventory.ini test.yml ERROR! Could not match supplied host pattern, ignoring: not_existed $ echo $? 1
パースできないインベントリがある場合にエラーとするかの指定(INVENTORY_ANY_UNPARSED_IS_FAILED
)
INVENTORY_ANY_UNPARSED_IS_FAILED
インベントリファイルの書式の誤りで、正しくパースできないインベントリがある場合にエラーとするかどうかの指定。デフォルトは False
で、エラーとしない扱い。
例えば、以下は書式が誤っているインベントリファイル(inventory2.ini
)。
[ios2] ios02 ansible_host=192.168.1.11 # vars とすべきところ var [ios2:var] ansible_network_os=ios ansible_connection=network_cli
このインベントリを指定して Playbook を実行すると、警告は表示されるがPlaybookの処理は続行しようとする。
$ ansible-playbook -i inventory.ini -i inventory2.ini test.yml [WARNING]: * Failed to parse /home/ansible/inventory2.ini with ini plugin: /home/ansible/inventory2.ini:5: Section [ios:var] has unknown type: var [WARNING]: Unable to parse /home/ansible/inventory2.ini as an inventory source PLAY [ios] ******************************************************************************************************** TASK [debug] ****************************************************************************************************** ok: [ios01] => { "msg": "Hello Ansible!" } PLAY RECAP ******************************************************************************************************** ios01 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 $ echo $? 0
早めにエラーとして処理を中止したい場合は True
に設定する。
[inventory] any_unparsed_is_failed=True
以下のように、Playbookの実行前にエラーで処理が止まる。
$ ansible-playbook -i inventory.ini -i inventory2.ini test.yml [WARNING]: * Failed to parse /home/ansible/inventory2.ini with ini plugin: /home/ansible/inventory2.ini:5: Section [ios:var] has unknown type: var ERROR! Completely failed to parse inventory source /home/ansible/inventory2.ini $ echo $? 1
ダイナミックインベントリにも有効。なので、認証情報に誤りがあってインベントリを取得できないときは処理を中止する」という使い方もできる。(aws_ec2
で確認)
補足
似た設定に INVENTORY_UNPARSED_IS_FAILEDもあるが、これは指定されたインベントリのうち1つでもパースできればエラーにしない。 一方、INVENTORY_ANY_UNPARSED_IS_FAILEDは、全てのインベントリがパースできれば正常、1つでもパースできなければエラーとするため、より安全。