Validate nginx.conf during ansible deploy

I have a single Ansible-provisioned server running a number of sites.

My Ansible tasks look roughly like:

- name: site nginx config
  template: src="nginx-site.conf.j2" dest=/etc/nginx/conf.d/{{item.name}}.conf
            owner=root group=root mode=0444
  with_items: sites
  notify: restart nginx

- name: nginx conf
  template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf 
            owner=root group=root mode=0444
  notify: restart nginx

I'd like to use the validate parameter to Ansible's template module to call nginx -t and make sure my new configs are syntactically valid. It works for the main nginx.conf:

  template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf 
            owner=root group=root mode=0444
            validate="/usr/sbin/nginx -c %s -t"

But it doesn't seem to pick up changes to the site-specific config files. Putting validate on the site-specific templates doesn't work, as they need to be wrapped in an http directive to be valid.

What can I do to check the validity of these site-specific files?


Solution 1:

You may do there some trick and validate placed file like (idea borrowed from https://gist.github.com/psd/5042334): validate: bash -c 'nginx -t -c /dev/stdin <<< "events {worker_connections 1;} http { include %s; }"'

Solution 2:

I used an approach similar to the accepted answer taking into account the other answer's concerns.

I created this gist for that purpose.

The idea is to copy the whole /etc/nginx directory to a temporary directory, change one the file from the %s parameter and test the main nginx config for problems. If you assume that initially the nginx config is valid and all tasks that modify the nginx config use that to validate, then I guess there would be no problem.

As a one liner it would look like this:

validate: bash -c 'NGINX_CONF_DIR=`mktemp -d`; cp -rTp /etc/nginx/ "$NGINX_CONF_DIR" && cp -Tp %s "$NGINX_CONF_DIR"/sites-enabled/new-site.conf && nginx -t -c "$NGINX_CONF_DIR"/nginx.conf'