tasksでhttpd.conf をcopyする際にvalidateにapachectl configtestを実行するよう設定すると、、、
- name: copy httpd.conf template action: template src=/template/apache/conf/httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf backup=yes validate='/usr/sbin/apachectl configtest' notify: - restart apache
# ansible-playbook hoge.yaml TASK: [copy httpd.conf template] ********************************************** failed: [hoge] => {"failed": true, "item": "", "parsed": false} invalid output was: Traceback (most recent call last): File "/root/.ansible/tmp/ansible-1381199762.87-223339696345573/copy", line 1104, in ? main() File "/root/.ansible/tmp/ansible-1381199762.87-223339696345573/copy", line 151, in main (rc,out,err) = module.run_command(validate % src) TypeError: not all arguments converted during string formatting FATAL: all hosts have already failed -- aborting
python初心者すぎてウッと絶望しかけたけど何かエラーは見たことある!
>>> print "%s, %s" % ("hoge", "fuga") hoge, fuga >>> print "%s, %s" % ("hoge") Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: not enough arguments for format string
型と変数の数が一致してないときのエラーですね。
たぶんこの例を見る感じだとvalidate に"%s" が必須でdestの引数のファイル名前が与えられるのだろう。
# Copy a new "sudoers file into place, after passing validation with visudo - action: template src=/mine/sudoers dest=/etc/sudoers validate='visudo -cf %s'
ただ、apachectl configtest のようにファイル名を引数に取らないコマンドの場合はapachtctl configtest httpd.conf などと余計な引数をつけると怒られる。なのでコマンドに影響を与えない無意味な環境変数に%sを使って、強引に解決するバッドノウハウを編み出した結果が以下の内容。
- name: copy httpd.conf template action: template src=/template/apache/conf/httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf backup=no validate='DUMMY=%s apachectl configtest' notify: - restart apache