Ansibleのcheck_modeオプションでcheckモードを制御する
渡辺です。
Ansible2.2からcheck_modeオプションが追加されます。 ひじょーに欲しかった機能なので紹介します。
Ansibleのcheckモード
ansible-playbook
コマンド実行時、--check
オプションを追加した場合、AnsibleはいわゆるDryRunになります。
この時、モジュールでは、サーバの状態をチェックして変更の必要性を確認しますが、変更を行うことはありません。
checkモードは、Playbookを変更する前や、変更を適用する前に利用されます。
commandモジュールはcheckモードでは実行されない
commandモジュールはcheckモードでは実行をスキップします。 これは、commandモジュールがサーバの状態を変更するとみなしているからです。 実際にはcommandモジュールで実行するコマンド次第なのですが、Ansibleの設計ポリシーとしては変更する可能性があるものは変更する、とみなしているのです。
- command: test -f /path_to/file register: _test_file
したがって、ファイルの存在チェックなどサーバの状態をチェックするコマンドであっても必ずchanged
となり、checkモードでは必ず実行されないということになります。
とはいえ、ファイルの存在チェックであれば、statモジュールを利用すれば解決します。
- stat: path: /path_to/file register: _stat_file
commandモジュールの結果は他のモジュールの実行判定に利用する
commandモジュールがなんらかのチェックを行うコマンドを実行しており、かつそれが標準モジュールで代替できない場合、checkモードでは後続のモジュール実行時にエラーが発生することになります。
これは、commandモジュールが実行されないため、register
で変数が登録されなからです。
あちらを立てればこちらが立たず・・・困ったところです。
- command: test -f /path_to/file register: _test_file - some_module: hogehohe when: _test_file.rc = 1 # _test_fileがないとエラー
checkモードで実行を強制するcheck_mode
ここで登場するのがcheck_mode
です。
check_mode
にはyes
またはno
を指定します。
check_mode
をyes
にした場合、--check
オプションをつけなくてもモジュールは常にcheckモードで実行されます。
check_mode
をno
にした場合、--check
オプションをつけた場合でも、モジュールは常に通常モードで実行されます。
つまり、check_mode: no
とすれば、commandモジュールを強制実行させることができるわけです。
結果、後続のモジュール実行犯定時に変数がなくてエラーとなることを回避できることになります。
- command: test -f /path_to/file check_mode: no changed_when: false register: _test_file - some_module: hogehohe when: _test_file.rc = 1
なお、check_mode: yes
の方は、グループ変数やコンディションを入れることで特定の条件下でcheckモードかどうかを制御する・・・ような使い方ですかね。
今の所、使いどころはいまいち解りません。
まとめ
check_mode: no
はAWS関連のタスクを実行する時、非常に重宝します。
例えば、ec2_vpc_subnet_factsモジュールはサブネットの情報を収集しますが、checkモードでは実行されません。
AWS CLIを実行する場合にはcommandモジュールを利用するので同様です。
ですが、check_mode
を利用すれば、checkモードでも実行出来るので、冪等性を保ったPlaybookを書きやすくなります。
- name: Facts subnet ec2_vpc_subnet_facts: profile: "{{ profile }}" region: "{{ region }}" check_mode: no register: _subnet_facts