
If you are not familiar with modules, check out Ansible - Getting Started with Modules.
ansible.builtin.template is similar to ansible.builtin.copy in that both copy a file from your control node (that's your Ansible server) to target systems. The big difference is that ansible.builtin.template will copy a .j2 file and the .j2 file can contain jinja2 references whereas Role Files or files copied with the ansible.builtin.copy cannot. For example, let's say foo.txt.j2 on the control node (that's your Ansible server) contains the following.
Default IP address is {{ ansible_default_ipv4.address }}
The following playbook would copy /tmp/foo.txt.j2 on your Ansible server to /tmp/foo.txt on each target system.
---
- hosts: all
tasks:
- name: copy /tmp/foo.txt.j2 to /tmp/foo.txt
ansible.builtin.template:
src: /tmp/foo.txt.j2
dest: /tmp/foo.txt
...
The /tmp/foo.txt file on each target system should then have something like this.
Default IP address is 10.4.56.133
List / Array
Let's say you have a list of items, such as a list of fruit.
---
- hosts: all
vars:
fruits:
- apple
- orange
- grapes
tasks:
- name: copy /tmp/foo.txt.j2 to /tmp/foo.txt
ansible.builtin.template:
src: /tmp/foo.txt.j2
dest: /tmp/foo.txt
...
Here is what you could have in your .j2 file so that the file contains the list of fruits.
{% for fruit in fruits %}
- {{ fruit }}
{% endfor %}
Role Template
Template files can also be placed in the roles templates directory.
/etc/ansible/roles/my-role/templates/foo.txt.j2
At a bare minimum, three playbook are needed to copy a template file to your managed nodes when the template file is in the roles templates directory.
- The playbook that invokes the role that contains the template file
- The roles main playbook (e.g. /etc/ansible/roles/my-role/tasks/main.yml)
- The template file (e.g. /etc/ansible/roles/my-role/templates/foo.txt.j2)
The playbook that invokes my-role could look something like this.
---
- hosts: all
roles:
- role: my-role
...
And the my-role playbook could look something like this. Notice in this example the src: foo.txt.j2 does not contain the full absolute path (/etc/ansible/roles/my-role/templates/foo.txt.j2). By default, the template module will look for the template file in the <base Ansible directory>/roles/<the name of the role>/templates directory.
- name: copy /etc/ansible/roles/my-role/templates/foo.txt.j2 to /tmp/bar.txt
ansible.builtin.template:
src: foo.txt.j2
dest: /tmp/foo.txt
Be aware that certain markup in a template file may produce unexpected errors. Let's say foo.txt.j2 contains the following.
LogFormat "%{%Y-%m-%d %T}t"
When attempting to copy foo.txt.j2 to your managed nodes, the play may fail and return something like this. This is occurring because {%Y is built in Jinja2 syntax.
Encounted unknown tag 'Y'
In this scenario, raw and endraw are used to remedy this issue.
{% raw %}LogFormat "%{%Y-%m-%d %T}t"{% endraw %}
Did you find this article helpful?
If so, consider buying me a coffee over at