/ ansible

Ansible: Using item in templates

This may seem obvious to some people but, I just stumbled upon this last week, in Ansible, you can use the item variable from a loop, inside of a template. I guess that should be obvious from all the variables being available in the template but, it just never occurred to me that this was something that could be done.

I figured this out while I was attempting to set up our custom services. We have a number of them but, the actual service scripts donʼt vary greatly. It is usually just a single word difference and it didnʼt make sense to create a custom template for each one. So, here is what I did in the template:

description "{{item}}"

console output

start on runlevel [2345]
stop on runlevel [016]

respawn
respawn limit 99 5

setuid app
setgid app

script
  /usr/local/bin/{{item}}
end script

This is what I did inside of the role:

- name: Add the service scripts
  template: src=service.j2
            dest=/etc/init/{{item}}.conf
            owner=root
            group=root
            mode=0755
  with_items:
    - service1
    - service2

Of course, even if the commands werenʼt the same, it would still be useful to set it up this way. Typically, init scripts contain quite a bit of boilerplate. Here is a more generalized solution, allowing you to reuse the template even with completely different commands:

description "{{ item.name }}"

console output

start on runlevel [2345]
stop on runlevel [016]

respawn
respawn limit 99 5

setuid app
setgid app

script
  {{ item.command }}
end script

with the role containing:

- name: Add the service scripts
  template: src=service.j2
            dest=/etc/init/{{item}}.conf
            owner=root
            group=root
            mode=0755
  with_items:
    - {name: service1, command: "/usr/local/bin/service1"}
    - {name: service2, command: "java -jar /usr/local/service2/start.jar"}

You could extend that with anything that you might need to vary between the scripts. For example, you could add a user value to allow the services to run as different users.

I found this to be completely non-obvious when I started out with Ansible. Now, it seems completely obvious that it is possible to do this. Hopefully, youʼll find this to be useful as well.