validate must contain %s: /usr/sbin/apachectl -tf /etc/httpd/conf/httpd.conf

Hi List,

I’m trying to securely place a vhost file for apache.
Before I place a new chost from template, I want it to be checked for correct behaviour before really deploying it:

- name: Plaats de verschillende extra vhosts
  template: src=vhost.j2 dest=/etc/httpd/conf.d/vhosts.conf backup=yes validate="/usr/sbin/apachectl -tf /etc/httpd/conf/httpd.conf"
  notify: reload httpd
  tags: httpd

Well, this will result in this error message:

TASK: [httpd | Plaats de verschillende extra vhosts] ************************** 
<10.34.34.66> ESTABLISH CONNECTION FOR USER: root on PORT 22 TO 10.34.34.66
<10.34.34.66> EXEC /bin/sh -c 'mkdir -p $HOME/.ansible/tmp/ansible-tmp-1412077952.61-262594095082263 && echo $HOME/.ansible/tmp/ansible-tmp-1412077952.61-262594095082263'
<10.34.34.66> EXEC /bin/sh -c 'rc=0; [ -r "/etc/httpd/conf.d/vhosts.conf" ] || rc=2; [ -f "/etc/httpd/conf.d/vhosts.conf" ] || rc=1; [ -d "/etc/httpd/conf.d/vhosts.conf" ] && echo 3 && exit 0; (/usr/bin/md5sum /etc/httpd/conf.d/vhosts.conf 2>/dev/null) || (/sbin/md5sum -q /etc/httpd/conf.d/vhosts.conf 2>/dev/null) || (/usr/bin/digest -a md5 /etc/httpd/conf.d/vhosts.conf 2>/dev/null) || (/sbin/md5 -q /etc/httpd/conf.d/vhosts.conf 2>/dev/null) || (/usr/bin/md5 -n /etc/httpd/conf.d/vhosts.conf 2>/dev/null) || (/bin/md5 -q /etc/httpd/conf.d/vhosts.conf 2>/dev/null) || (/usr/bin/csum -h MD5 /etc/httpd/conf.d/vhosts.conf 2>/dev/null) || (/bin/csum -h MD5 /etc/httpd/conf.d/vhosts.conf 2>/dev/null) || (echo "${rc} /etc/httpd/conf.d/vhosts.conf")'
<10.34.34.66> PUT /tmp/tmpJob224 TO /root/.ansible/tmp/ansible-tmp-1412077952.61-262594095082263/source
<10.34.34.66> PUT /tmp/tmpAvdktD TO /root/.ansible/tmp/ansible-tmp-1412077952.61-262594095082263/copy
<10.34.34.66> EXEC /bin/sh -c 'LANG=C LC_CTYPE=C /usr/bin/python /root/.ansible/tmp/ansible-tmp-1412077952.61-262594095082263/copy; rm -rf /root/.ansible/tmp/ansible-tmp-1412077952.61-262594095082263/ >/dev/null 2>&1'
failed: [ISUFD4ACCPRES03] => {"failed": true}
msg: validate must contain %s: /usr/sbin/apachectl -tf /etc/httpd/conf/httpd.conf

FATAL: all hosts have already failed -- aborting

Apparantly I need to add %s to the validate command. But validating in apachectl does not work that way, it just needs the “top” config and then works it’s way through that one and all “include” directories inside that file and validate the complete setup for me.

I tried altering the command to: “validate=”/usr/sbin/apachectl -tf /etc/httpd/conf/httpd.conf #%s” but ansible then thinks I forgot the closing quotes (Because it’s behind a comment sign :wink:

Then I tried “validate=”/usr/sbin/apachectl -tf /etc/httpd/conf/httpd.conf #%s” you see? trying to escape the hash sign, which then gets translated to the command as: “/usr/sbin/apachectl -tf /etc/httpd/conf/httpd.conf #/etc/httpd/confd./vhosts.conf” which then causes apachectl to fail again :wink:

A bit stuck here. Can we make %s optional?

Thanks,
Mark

Based on this beauty:
https://coderwall.com/p/lxchtg

I worked around it with:


- name: Check the apache configuration
command: apachectl -t
register: apache_result
ignore_errors: yes
tags: httpd

- name: Ending playbook
action: fail msg="Apache configuration is invalid. Please check before re-running the playbook."
when: apache_result|failed
tags: httpd

right after placing the vhosts config file.

Thanks!
Mark

validate uses %s to find the temporary file BEFORE putting it into
place, if the check fails the target is not updated. This does not
work for multifile configs, use the suggestion from Mark for that.