Template an Ansible playbook w/o interpreting variables
Sometimes you want to use an Ansible role to place ansible playbooks on a target system. But how do you preserve the uninterpreted form of variables when you're using jinja2 to template such a playbook? Here is a solution
Inside the jinja2 template, on the first line, place a header that overrides the default variable marker
#jinja2: variable_start_string: "[%" , variable_end_string: "%]"
Now any variable in the format [% variable %] will be interpreted, while any variables using the default ansible notation {{ variable }} will be left uninterpreted.
So a template (hostname.j2) like this:
#jinja2: variable_start_string: "[%" , variable_end_string: "%]"
---
# usage: ansible-playbook hostname.yml -K
- hosts: 127.0.0.1
connection: local
user: admin
vars:
hostname: '[% ansible_hostname %]'
domain: '[% domain %]'
tasks:
- name: Edit /etc/hostname
copy: content='{{hostname}}' dest='/etc/hostname' force='yes'
- name: Set hostname
shell: 'hostname {{hostname}}'
- name: Set ServerName in apache2 site.conf and site-ssl.conf
lineinfile: regexp='^ServerName' line='ServerName {{hostname}}.{{domain}}' state='present' dest='{{item}}'
with_items:
- "/etc/apache2/sites-available/site.conf"
- "/etc/apache2/sites-available/site-ssl.conf"
Can be used in an Ansible task inside another playbook or role:
- name: Add hostname.yml playbook to target VM
template: src='hostname.j2' dest='/home/{{item.name}}/playbooks/hostname.yml'
with_items: admins
And will render as (hostname.yml) such:
---
# usage: ansible-playbook hostname.yml -K
- hosts: 127.0.0.1
connection: local
user: admin
vars:
hostname: 'testbox'
domain: 'local.lan'
tasks:
- name: Edit /etc/hostname
copy: content='{{hostname}}' dest='/etc/hostname' force='yes'
- name: Set hostname
shell: 'hostname {{hostname}}'
- name: Set ServerName in apache2 site.conf and site-ssl.conf
lineinfile: regexp='^ServerName' line='ServerName {{hostname}}.{{domain}}' state='present' dest='{{item}}'
with_items:
- "/etc/apache2/sites-available/site.conf"
- "/etc/apache2/sites-available/site-ssl.conf"
as you can see, in the vars stanza, hostname and domain were interpreted, but nothing else.
This rendered playbook can now be used with Ansible on the target VM and use the defined vars properly.
Written by Sarah Zelechoski
Related protips
2 Responses
Thanks
Excellent. Thanks