← Back to list

KodeKloud Engineer Day 92: Managing Jinja2 Templates Using Ansible.

Hey Everyone! I have taken up the kodekloud engineer daily challenge [100 days of Devops] and through this series, we shall slowly but…

Jane Mils · 2026-05-29 13:47 · 0 claps · 5.1 min read
#kodekloud #kodekloudengineer #devops #ansible #jinja2
Open on Medium ↗
Wiki topics: ☁️ · DevOps & Cloud

KodeKloud Engineer Day 92: Managing Jinja2 Templates Using Ansible.

Hey Everyone! I have taken up the kodekloud engineer daily challenge [100 days of Devops] and through this series, we shall slowly but steadily start solving the daily challenges.

Here’s the link to get started with the challenge: https://engineer.kodekloud.com/practice

Day #92 Task: Managing Jinja2 Templates Using Ansible.

One of the Nautilus DevOps team members is working on to develop a role for httpd installation and configuration. Work is almost completed, however there is a requirement to add a jinja2 template for index.html file. Additionally, the relevant task needs to be added inside the role. The inventory file ~/ansible/inventory is already present on jump host that can be used. Complete the task as per details mentioned below:

a. Update ~/ansible/playbook.yml playbook to run the httpd role on App Server 2.

b. Create a jinja2 template index.html.j2 under /home/thor/ansible/role/httpd/templates/ directory and add a line This file was created using Ansible on <respective server> (for example This file was created using Ansible on stapp01 in case of App Server 1). Also please make sure not to hard code the server name inside the template. Instead, use inventory_hostname variable to fetch the correct value.

c. Add a task inside /home/thor/ansible/role/httpd/tasks/main.yml to copy this template on App Server 2 under /var/www/html/index.html. Also make sure that /var/www/html/index.html file's permissions are 0744.

d. The user/group owner of /var/www/html/index.html file must be respective sudo user of the server (for example tony in case of stapp01).

Note: Validation will try to run the playbook using command ansible-playbook -i inventory playbook.yml so please make sure the playbook works this way without passing any extra arguments.

Day #92 Task: Managing Jinja2 Templates Using Ansible.

Day #92 Task: Managing Jinja2 Templates Using Ansible.

Let’s understand a few things, before working on this task.

What is Jinja2?

Jinja2 is a tool that allows you to create dynamic files using variables, conditions, and loops instead of hardcoding everything. Without Jinja, you’ll have to write multiple config/template files for multiple setups. With Jinja, one template file works for all servers dynamically. You can think of it as a document template with blanks to fill automatically, (which will be done so, by Ansible, in our case).

Now, there’s another difference to be spotted with this challenge. In all our previous challenges, we were directly adding the tasks in the playbook.yml file and it executes, when we trigger it. In this challenge, we are making use of the Ansible role structure, where the playbook only calls the role, and the actual tasks, templates, files, and configurations are organized inside separate role directories like tasks/, templates/, files/, etc.

This makes automation more modular, reusable, and easier to manage in real production environments. Now let’s move on to solving the task.

Step-1: Verify the existing inventory file.

Let’s just check the content of the existing inventory file.

thor@jump-host ~/ansible$ cat inventory 
stapp01 ansible_host=stapp01 ansible_ssh_pass=Ir0nM@n ansible_user=tony
stapp02 ansible_host=stapp02 ansible_ssh_pass=Am3ric@ ansible_user=steve
stapp03 ansible_host=stapp03 ansible_ssh_pass=BigGr33n ansible_user=banner

This means that the playbook that we’ll create will run on all the three app-servers.

Step-2: Edit the playbook, jinja file and the roles file with the defined requirements.

Let’s checkout the existing playbook file and the task file.

# Let's check out the existing playbook file.
thor@jump-host ~$ cat ~/ansible/playbook.yml 

# Content of the playbook.yml file.
---
- hosts: 
  become: yes
  become_user: root
  roles:
    - role/httpd

# Let's check out the httpd task file and see what kind of tasks will be executed.
# We need to make a note as to what to add in this file.
thor@jump-host ~/ansible$ cat role/httpd/tasks/main.yml
---
# tasks file for role/test

- name: install the latest version of HTTPD
  yum:
    name: httpd
    state: latest

- name: Start service httpd
  service:
    name: httpd
    state: started

From this, we can observe that there are certain things that needs to be added/modified in all these files. Let’s go through them step-by-step.

In the playbook.yml, we need to add the host as stapp02 as it’s mentioned in the problem statement. For the roles, it’ll automatically pick up, what ever task is defined in *~/role/httpd*path. So, let’s modify the playbook.yml to run in App server 02.

# Let's edit the playbook.yml file.
thor@jump-host ~$ vi ~/ansible/playbook.yml 

# Content of the playbook.yml file.
---
- hosts: stapp02 
  become: yes
  become_user: root
  roles:
    - role/httpd

Now, let’s create the jinja file *index.html.j2in path:`/home/thor/ansible/role/httpd/templates/`*.

# Let's create the jinja file index.html.j2in path:/home/thor/ansible/role/httpd/templates/.

thor@jump-host ~/ansible$ vi role/httpd/templates/index.html.j2

# Content of the jinja file:-
This file was created using Ansible on {{ inventory_hostname }}

# This file will pick up, whichever host the playbook is running on.

Let’s move on to the tasks file now. It needs to pick up the template from the jinja file that we created and also need to change the ownership and permission of the file.

# Modify the tasks file.
thor@jump-host ~/ansible$ cat role/httpd/tasks/main.yml

# Content of the task file.
---
# tasks file for role/test

- name: install the latest version of HTTPD
  yum:
    name: httpd
    state: latest

- name: Start service httpd
  service:
    name: httpd
    state: started

# Added this to pick up the jinja file and modify the ownership and permission.
- name: Deploy index.html template
  template:
    # Take a Jinja2 template file, render its variables, and copy the final generated file to the remote server (App Server 02, in this case).
    src: index.html.j2
    dest: /var/www/html/index.html
    owner: "{{ ansible_user }}"
    group: "{{ ansible_user }}"
    mode: '0744'

Step-3: Validate the execution of the playbook against the inventory file.

Check in the app server 02, before executing the playbook file, if any such file exists.

# Check if there exists any file in the /var/www/html path in App Server 02.
thor@jump-host ~$ cat ansible/inventory 
stapp01 ansible_host=stapp01 ansible_ssh_pass=Ir0nM@n ansible_user=tony
stapp02 ansible_host=stapp02 ansible_ssh_pass=Am3ric@ ansible_user=steve
stapp03 ansible_host=stapp03 ansible_ssh_pass=BigGr33n ansible_user=banner

thor@jump-host ~$ ssh steve@stapp02
The authenticity of host 'stapp02 (10.244.234.245)' can't be established.
ED25519 key fingerprint is SHA256:07ELy86qBUSR3TQmn60CbIJgywNSoCzFuX6eKP9R+rg.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'stapp02' (ED25519) to the list of known hosts.
steve@stapp02's password: 
[steve@stapp02 ~]$ sudo systemctl status httpd
Unit httpd.service could not be found.
[steve@stapp02 ~]$ ls /var/www/html
ls: cannot access '/var/www/html': No such file or directory
[steve@stapp02 ~]$ cat /var/www/html/index.html
cat: /var/www/html/index.html: No such file or directory
# Run the playbook and verify if the playbook is executed successfully.
thor@jump-host ~/ansible$ ansible-playbook -i inventory playbook.yml

PLAY [stapp02] **************************************************************************

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

TASK [role/httpd : install the latest version of HTTPD] *********************************
changed: [stapp02]

TASK [role/httpd : Start service httpd] *************************************************
changed: [stapp02]

TASK [role/httpd : Deploy index.html template] ******************************************
changed: [stapp02]

PLAY RECAP ******************************************************************************
stapp02                    : ok=4    changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
# Check if the file index.html is created  in the /var/www/html path in App Server 02. Also verify the ownership and the permission of the file.
[steve@stapp02 ~]$ sudo systemctl status httpd
● httpd.service - The Apache HTTP Server
     Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; preset: d>
     Active: active (running) since Mon 2026-05-25 10:47:43 UTC; 12s ago
       Docs: man:httpd.service(8)
   Main PID: 27606 (httpd)
     Status: "Total requests: 0; Idle/Busy workers 100/0;Requests/sec: 0; Bytes>
      Tasks: 177 (limit: 404712)
     Memory: 14.9M
        CPU: 72ms
     CGroup: /system.slice/httpd.service
             ├─27606 /usr/sbin/httpd -DFOREGROUND
             ├─27788 /usr/sbin/httpd -DFOREGROUND
             ├─27791 /usr/sbin/httpd -DFOREGROUND
             ├─27794 /usr/sbin/httpd -DFOREGROUND
             └─27797 /usr/sbin/httpd -DFOREGROUND

May 25 10:47:43 stapp02 systemd[1]: Starting The Apache HTTP Server...
May 25 10:47:43 stapp02 httpd[27606]: AH00558: httpd: Could not reliably determ>
May 25 10:47:43 stapp02 httpd[27606]: Server configured, listening on: port 80
May 25 10:47:43 stapp02 systemd[1]: Started The Apache HTTP Server.

[steve@stapp02 ~]$ cat /var/www/html/index.html
This file was created using Ansible on stapp02
[steve@stapp02 ~]$ ls /var/www/html
index.html
[steve@stapp02 ~]$ ls -la /var/www/html/index.html 
-rwxr--r-- 1 steve steve 47 May 25 10:48 /var/www/html/index.html

That’s it for Day #92. Let’s hop on to the next challenge! See you there! Toodaloo!


메타데이터
post_id
a7c8e24ab8b4
slug
kodekloud-engineer-day-92-managing-jinja2-templates-using-ansible-a7c8e24ab8b4
url
https://medium.com/@janemils/kodekloud-engineer-day-92-managing-jinja2-templates-using-ansible-a7c8e24ab8b4
canonical_url
https://medium.com/@janemils/kodekloud-engineer-day-92-managing-jinja2-templates-using-ansible-a7c8e24ab8b4
author_url
https://medium.com/@janemils
status
ok
fetched_at
2026-06-21 19:25:17