Ansible is great, it’s really simple to setup and easy to use. There are still some hidden tricks that can make your workflow more efficient.
I was setting up new machines with PHP-FPM support. I’d like to change several FPM parameters using Ansible, you can copy (transfer) the whole configurations from your Ansible task to remote machines via synchronize
or template
, it’s fast but you can’t handle config changes from program updates. So my idea is dynamically replace the parameters I want to change via lineinfile
:
After googling around, I found this answer by Ben Whaley fit the bill:
- name: Set some kernel parameters
lineinfile:
dest: /etc/sysctl.conf
regexp: "{{ item.regexp }}"
line: "{{ item.line }}"
with_items:
- { regexp: '^kernel.shmall', line: 'kernel.shmall = 2097152' }
- { regexp: '^kernel.shmmax', line: 'kernel.shmmax = 134217728' }
- { regexp: '^fs.file-max', line: 'fs.file-max = 65536' }
That snippet works but it’s tedious. regexp
and line
has the duplicated parameter key names, let’s clean up the code:
- name: set PHP-FPM parameters
lineinfile:
dest: /etc/php-fpm.conf
regexp: "^{{ item.param }}"
insertafter: "^;{{ item.param }}"
line: "{{ item.param }} = {{ item.value }}"
with_items:
- { param: 'error_log', value: '/var/log/php-fpm/error.log' }
- { param: 'log_level', value: 'error' }
- { param: 'emergency_restart_threshold', value: '10' }
Everything works fine untill I meet the following config:
php_value[session.save_handler] = 'files'
I can’t target keys like this with previous regexp
, and cannot match square brackets directly or Ansible will fall running this task. So I have to escape speciall characters:
- name: set PHP-FPM pool parameters
lineinfile:
dest: /etc/php-fpm.d/www.conf
regexp: '^{{ item.param|replace("[", "\[")|replace("]", "\]") }} *?='
insertafter: '^;{{ item.param|replace("[", "\[")|replace("]", "\]") }} *?='
line: "{{ item.param }} = {{ item.value }}"
with_items:
- { param: 'php_value[session.save_handler]', value: 'memcache' }
- ...
Cool for the summer.