Ansible : Templates – Jinja2

Ansible_Logo

Ansible templates allows users to dynamically generate text-based files using templates, variables, and facts for configuration and other purposes.

The difference between Ansible Facts and Templates is as follows:

An ansible Fact stores variables that can be used by a playbook when executed

An ansible template, which used ansible facts and pulls values of variable defined in facts, used them to create files which incorporates these values.

Let us create a template file in the controller node in Jinja format:

[root@centos9vm ~]# cat template.j2

===== ====
Welcome to the {{ ansible_facts[‘hostname] }} from the {{ ansible_facts[‘fqdn’] }}

{# This line will not appear any where. Below is a variable declared in playbook #}

My name is {{  myName }}

===== ===

Let us create a playbook to copy the template to managed node and execute the playbook to create a new file

[root@centos9vm ~]# cat example7.yml

===== ====
    – – –
    – name: Share the jinja tempate with values to managed node
        hosts: testGRP

        vars:
                myName: SHIJU
        tasks:

            – name: Using copied template to generate file
                ansible.builtin.template:
                    src: /root/template.j2
                    dest: /root/file_created_from_template.txt
==== ====

[root@centos9vm ~]# ansible-navigator run -m stdout example7.yml

===== ====

PLAY [Share the jinja tempate with values to managed node] *********************

TASK [Gathering Facts] *********************************************************
ok: [192.168.48.129]

TASK [Copy the template.j2 file to managed node] *******************************
changed: [192.168.48.129]

TASK [Using copied template to generate file] **********************************
changed: [192.168.48.129]

PLAY RECAP *********************************************************************
192.168.48.129 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

===== ===

Let us verify if the file got created in the managed node

[root@centosMYOBvm ~]# cat file_created_from_template.txt

===== ==== ==
Welcome to the centosMYOBvm from the centosMYOBvm

SHIJU
===== === ==

Creating a loop using variable list in playbook
====== @@@@@ ======

In the below example, we will create a playbook with a variable list called fruitList, and use a jinja template to create a file in managed node that will have names of all fruits in the fruitList.

[root@centos9vm ~]# cat temp.yml

==== ====
– – –
– name: Playbook to install a template
    hosts: dev
    vars:
        myName: Shiju
        fruitList:
            – Apple
            – Orange
            – Grapes
    tasks:
        – name: Task to deploy a template
            ansible.builtin.template:
                src: shiju.j2
                dest: /webdevelop/index.html
==== ====

[root@centos9vm ~]# cat shiju.j2
===== ==
Welcome to {{ ansible_facts[‘hostname’] }} on {{ ansible_facts[‘default_ipv4’][‘address’] }}
Welcome to {{ ansible_facts[‘nodename’] }} on {{ ansible_facts[‘all_ipv4_addresses’] }}

My name is {{ myName }}

{% for theFruits in fruitList %}
{{ theFruits }}
{% endfor %}
====== ==

[root@centos9vm ~]# ansible-navigator run -m stdout temp.yml
===== =====
PLAY [Playbook to install a template] ******************************************

TASK [Gathering Facts] *********************************************************
ok: [192.168.48.132]

TASK [Task to deploy a template] ***********************************************
ok: [192.168.48.132]

PLAY RECAP *********************************************************************
192.168.48.132 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
====== ===

[root@centos9vm ~]# ssh 192.168.48.132 ‘cat /webdevelop/index.html’
===== =====
Welcome to centos9test1 on 192.168.48.132
Welcome to centos9test1 on [‘192.168.48.132’]

My name is Shiju

Apple
Orange
Grapes
===== ===

listing hostnames of group in Inventory file
===== @@@@@ =======

Now let us write a jinja template to loop through the list of managed hosts in the playbook and create a file in all managed nodes in the list, with the content being hostnames  all nodes in the list

[root@centos9vm ~]# cat shiju.j2

======== ====
{% for i in groups[‘dev’]%}
{{ hostvars[i][‘ansible_facts’][‘hostname’] }}
{% endfor %}

====== ==

[root@centos9vm ~]# cat temp.yml

====== ===
– – –
      – name: Playbook to install a template
         hosts: dev
         tasks:
      – name: Task to deploy a template
         ansible.builtin.template:
             src: shiju.j2
            dest: /webdevelop/index.html

===== ===

[root@centos9vm ~]# cat inventory

===== ==
[prod]
192.168.48.100

[dev]
192.168.48.132
192.168.48.129
===== ==

[root@centos9vm ~]# ansible-navigator run -m stdout temp.yml

PLAY [Playbook to install a template] *********************************************

TASK [Gathering Facts] ************************************************************
ok: [192.168.48.129]
ok: [192.168.48.132]

TASK [Task to deploy a template] **************************************************
changed: [192.168.48.129]
changed: [192.168.48.132]

PLAY RECAP ************************************************************************
192.168.48.129 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
192.168.48.132 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

===== ===

[root@centos9vm ~]# ssh 192.168.48.132 ‘cat /webdevelop/index.html’
centos9test1
centosMYOBvm

==== ===

Now let us edit the jinja template to create content for an /etc/hosts file

==== ====

[root@centos9vm ~]# cat shiju.j2
{% for i in groups[‘dev’]%}
{{hostvars[i][‘ansible_facts’][‘default_ipv4’][‘address’]}} {{ hostvars[i][‘ansible_facts’][‘fqdn’] }} {{ hostvars[i][‘ansible_facts’][‘hostname’] }}
{% endfor %}

===== ===

[root@centos9vm ~]# ansible-navigator run -m stdout temp.yml

[root@centos9vm ~]# ssh 192.168.48.132 ‘cat /webdevelop/index.html’

==== =====
192.168.48.132        centos9test1       centos9test1
192.168.48.129        centosMYOBvm       centosMYOBvm