はじめに
Ansible の lineinfile
や replace
などのファイルを編集するモジュールには validate
オプションを備えているものがあります。
validate
オプションには編集後のファイルの妥当性を検証するコマンドを指定します。
これにより、編集に問題がなければ処理を継続、問題があれば処理を停止、のようにワンクッション挟めるため安全性を高められます。
公式ドキュメントの lineinfile
モジュールの Example には、/etc/sudoers
編集後に実行する validate
オプションの例があります。
この記事では、 Apache httpd の設定ファイルである、httpd.conf
を validete する Playbook の例をご紹介します。
サンプル Playbook の作成
以下のような簡単な Playbook を利用します。
- hosts: web gather_facts: no become: yes tasks: - name: configure Listen Port lineinfile: path: /etc/httpd/conf/httpd.conf regexp: '^Listen 80$' line: 'Listen 8080' validate: httpd -tf %s # point notify: - restart httpd handlers: - name: restart httpd service: name: httpd state: restarted enabled: yes
処理は以下のとおりです。
lineinfile
モジュールによりhttpd.conf
の^Listen 80$
をListen 8080
に置換- 変更なしなら、終了
- 変更ありなら、次へ
httpd -tf
コマンドにて validate する- 問題ありなら、エラーで終了
- 問題なしなら、次へ
validate: httpd -tf %s
について補足
validate
オプションには httpd -tf %s
を指定しています。
httpd
コマンドの -t
オプションによって、httpd.conf
に問題がないか検証できます。-f
オプションを併用することで検証対象のファイルを明示指定できます。
%s
は Ansible 側の仕様によるものです。lineinfile
などのモジュールでは、編集対象のファイルを直接編集せず、編集用に一時ファイルを作成します。その一時ファイルのパスが %s
に格納されます。
そのため、httpd -t
のみの指定の場合、Ansible が編集した一時ファイルを検証の対象にしないでご注意ください。
Playbook の実行
validete が OK なパターンと NG なパターンそれぞれ試します。
OK パターン
$ ansible-playbook -i inventory.ini web.yml PLAY [localhost] **************************************************************************************************** TASK [configure Listen Port] **************************************************************************************** changed: [localhost] RUNNING HANDLER [restart httpd] ************************************************************************************* changed: [localhost] PLAY RECAP ********************************************************************************************************** localhost : ok=2 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
validete に問題がなかったので、処理が継続されました。
NG パターン
Playbook で指定した置換後文字列の
line: 'Listen 8080'
を
line: 'Listen XXX'
にして試します。 httpd.conf
の Listen は待受ポート番号を指定する項目のため、文字列が指定されると httpd -tf %s
の validate によって Syntax Check になります。
$ ansible-playbook -i inventory.ini web.yml PLAY [localhost] **************************************************************************************************** TASK [configure Listen Port] **************************************************************************************** fatal: [localhost]: FAILED! => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": false, "msg": "failed to validate: rc:1 error:AH00526: Syntax error on line 43 of /tmp/tmpbcDcMD:\nPort must be specified\n"} PLAY RECAP ********************************************************************************************************** localhost : ok=0 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
failed to validate: rc:1 error:AH00526: Syntax error on line 43 of /tmp/tmpbcDcMD:\nPort must be specified\n"
というエラーメッセージとともに validate が NG となり、処理がエラーで停止されました。
手動で validate した場合は、以下の実行イメージです。
$ httpd -tf <対象httpd.conf> AH00526: Syntax error on line 43 of <対象httpd.conf>: Port must be specified
さいごに
もし validate
オプションを指定しなかった場合、httpd.conf
に問題があっても、ハンドラー restart httpd
が呼ばれてしまい、再起動を試みたところで失敗し、httpd
が停止したままになってしまいます。
validate
オプションを有効に使うことで、このような自体を未然に防げます。