Ansible deployment of DNS zone files.

January 8th, 2016 § 0 comments § permalink

Ansible

I’ve recently started to refactor my server configuration. It’s always been built with Ansible but it was one of the first things I ever did using that and I was fairly certain that every way I could have been doing it wrong I was.

One of the things I’d wanted to do was rationalise what was in my playbooks. They should ideally be all code and no configuration but I was using a lot of templates for various system files and they were mostly configuration for content, not services – the chief culprits being dns zone and nginx/apache vhost files. When you refer to a template from with a playbook it expects that the files are inside the playbook itself. This just doesn’t seem right to me. You can specify absolute locations though and so with a bit of finagling I was able to get the files where I wanted. The magic is to do something like

{{ inventory_dir }}/../templates/zones/*.j2

inventory_dir is the absolute path to your main inventory file and so we can use this to point at a global templates folder with a bit of path manipulation. As you can see I’m stepping up out of the hosts folder and then down into templates.

This works really well but there was another thing I wanted to do. I was configuring the zones that I had to populate on the system using normal vars files (a simple list object with domain names in), and then using that to grab the templates to put on the system. This struck me as wasteful. The addition of a new domain meant that I had to add the file and then amend an array just to inform Ansible to read the file. There had to be a better way. Sure enough with_fileglob came to the rescue. This allows Ansible to parse a path for files and then gives us the tools necessary to feed our provisioning. With a bit of Jinja2 manipulation magic I ended up with this

- name: Install zone files
  template:
  src: "{{ item }}"
  dest: /etc/bind/zones/{{ item | basename | regex_replace("\.j2$","") }}
  owner: root
  group: root
  mode: 0644
  register: zone_files
  with_fileglob:
    - "{{ inventory_dir }}/../templates/zones/*.j2"
  notify:
    - reload bind9

The final piece of this puzzle was to make sure that each of these zone files were referred to in the Bind configuration. I scratched my head over this for a bit and then it occurred I could register the results of the above action as a variable and use it in the template for that file. So I registered zone_files and set about concocting a template loop

{% for zone in zone_files.results %}
zone "{{ zone.item | basename | regex_replace("\.db\.j2$","") }}" {
   type master;
   file "/etc/bind/zones/{{ zone.item | basename | regex_replace("\.j2$","") }}";
   allow-transfer { slaves; };
};
{% endfor %}

It didn’t turn out too complicated in the end – certainly very readable but the end result is a much nicer playbook with all configuration being both more succinct and living in appropriate places.

Why do my sockets keep disappearing?

May 14th, 2015 § 0 comments § permalink

I’m working on getting my froxlor instance setup with PHP5-FPM and Nginx and was encountering an issue whereupon reboot the PHP functionality would be broken. Looking in syslog would give me about 30 lines of PHP5-FPM failing to start and then giving up. Looking in /var/log/php5-fpm.log would tell me nothing useful other then the configtest passed.

I eventually found a helpful message in the /var/log/upstart/php5-fpm.log file:

[14-May-2015 09:21:54] ERROR: unable to bind listening socket for 
address '/var/run/nginx/username-domain.com-php-fpm.socket': No 
such file or directory (2)

True enough the /var/run/nginx folder did not exist. I could not figure out where it was going.

After hair pulling research I found that the /var/run mount point is run as tmpfs and so is deleted on reboot. In order to fix this I had to ensure the directory was recreated before PHP5-FPM started. It turns out this if fairly easy with upstart. I added this stanza:

pre-start
    ... other stuff ...
    [ -d /var/run/nginx ] || mkdir -p /var/run/nginx
end script

to the /etc/init/nginx.conf file to have the folder created on boot.

Problem solved.

css.php