Workshop Exercise - Templates

Read this in other languages:
uk English, japan日本語, brazil Portugues do Brasil, france Française,Español Español.

Table of Contents


Exercise 1.5 introduces Jinja2 templating within Ansible, a powerful feature for generating dynamic files from templates. You’ll learn how to craft templates that incorporate host-specific data, enabling the creation of tailored configuration files for each managed host.


Step 1 - Introduction to Jinja2 Templating

Ansible leverages Jinja2, a widely-used templating language for Python, allowing dynamic content generation within files. This capability is particularly useful for configuring files that must differ from host to host.

Step 2 - Crafting Your First Template

Templates end with a .j2 extension and mix static content with dynamic placeholders enclosed in {{ }} .

In the following example, let’s create a template for the Message of the Day (MOTD) that includes dynamic host information.

Set Up the Template Directory:

Ensure a templates directory exists within your lab_inventory directory to organize your templates.

mkdir -p ~/lab_inventory/templates

Develop the MOTD Template:

Create a file named motd.j2 in the templates directory with the following content:

Welcome to {{ ansible_hostname }}.
OS: {{ ansible_distribution }} {{ ansible_distribution_version }}
Architecture: {{ ansible_architecture }}

This template dynamically displays the hostname, OS distribution, version, and architecture of each managed host.

Step 3 - Deploying the Template with a Playbook

Utilize the ansible.builtin.template module in a playbook to distribute and render the template across your managed hosts.

Modify the system_setup.yml Playbook with the following content:

- name: Basic System Setup
  hosts: all
  become: true
    - name: Update MOTD from Jinja2 Template
        src: templates/motd.j2
        dest: /etc/motd

    - name: Reload Firewall
        name: firewalld
        state: reloaded

The ansible.builtin.template module takes the motd.j2 template and generates an /etc/motd file on each host, filling in the template’s placeholders with the actual host facts.

Step 4 - Executing the Playbook

Run the playbook to apply your custom MOTD across all managed hosts:

[student@ansible-1 lab_inventory]$ ansible-navigator run system_setup.yml -m stdout
PLAY [Basic System Setup] ******************************************************

TASK [Update MOTD from Jinja2 Template] ****************************************
changed: [node1]
changed: [node2]
changed: [node3]
changed: [ansible-1]

PLAY RECAP *********************************************************************
ansible-1                  : ok=6    changed=1    unreachable=0    failed=0    skipped=2    rescued=0    ignored=0
node1                      : ok=8    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
node2                      : ok=8    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
node3                      : ok=8    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Verify the changes by SSHing into the node, and you should see the message of the day:

[rhel@control ~]$ ssh node1
Welcome to node1.
OS: RedHat 8.7
Architecture: x86_64
Register this system with Red Hat Insights: insights-client --register
Create an account or view all your systems at
Last login: Mon Jan 29 16:30:31 2024 from

Previous Exercise - Next Exercise

Click here to return to the Ansible for Red Hat Enterprise Linux Workshop