Skip to content

Ansible Level 04 Day 03: Managing Jinja2 Templates using Ansible

This document outlines the solution for Ansible Level 04 Day 03. The objective was to update an existing Ansible role (httpd) by incorporating a Jinja2 template to dynamically generate an index.html file and executing this role specifically on App Server 2.

Table of Contents


Task Overview

Objective: Deploy a dynamic index.html file to App Server 2 using an Ansible role and a Jinja2 template.

Requirements: 1. Target Host: App Server 2 (stapp02). 2. Playbook: Update ~/ansible/playbook.yml to run the httpd role on the target host. 3. Template Location: ~/ansible/role/httpd/templates/index.html.j2. 4. Template Content: This file was created using Ansible on {{ inventory_hostname }}. 5. Task Updates: Add a task to ~/ansible/role/httpd/tasks/main.yml to copy the template to /var/www/html/index.html. 6. File Attributes: * Permissions: 0755. * Owner/Group: The respective sudo user of the server (steve for stapp02, which can be dynamically referenced using {{ ansible_user }}).


Step-by-Step Solution

1. Update the Playbook

We first need to configure the main playbook to execute the existing httpd role specifically on App Server 2 (stapp02). Privilege escalation (become: yes) is necessary for web server configuration.

Command:

vi ~/ansible/playbook.yml

Content:

---
- name: Deploy HTTPD Role
  hosts: stapp02
  become: yes
  roles:
    - role: httpd
(Ensure that the role path matches your directory structure. Sometimes roles are located in a folder like roles/httpd or just httpd. Adjust the - role: httpd line accordingly if the path is explicitly role/httpd.)

2. Create the Jinja2 Template

Navigate to the templates directory inside the httpd role and create the Jinja2 (.j2) file. We utilize the inventory_hostname built-in variable to avoid hardcoding server names.

Command:

mkdir -p ~/ansible/role/httpd/templates/
vi ~/ansible/role/httpd/templates/index.html.j2

Content:

This file was created using Ansible on {{ inventory_hostname }}

3. Update the Role Tasks

Now, add the deployment logic to the role's main tasks file. The template module reads the .j2 file, replaces the variables, and writes the output to the destination server.

Command:

vi ~/ansible/role/httpd/tasks/main.yml

Content (Append to existing tasks):

# ... (existing tasks like installing httpd and starting the service) ...

- name: Deploy dynamic index.html using Jinja2 template
  template:
    src: index.html.j2
    dest: /var/www/html/index.html
    owner: "{{ ansible_user }}"
    group: "{{ ansible_user }}"
    mode: '0755'
Note: Using {{ ansible_user }} ensures the owner is dynamically set to the connection user (which is steve for stapp02), fulfilling the ownership requirement safely without hardcoding.

4. Execute and Validate

Run the playbook from the directory containing the inventory file to ensure no extra arguments are needed.

Command:

cd ~/ansible
ansible-playbook -i inventory playbook.yml

Expected Output:

PLAY [Deploy HTTPD Role] ************************************************************

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

TASK [httpd : Install httpd] ********************************************************
ok: [stapp02]

TASK [httpd : Start httpd service] **************************************************
ok: [stapp02]

TASK [httpd : Deploy dynamic index.html using Jinja2 template] **********************
changed: [stapp02]

PLAY RECAP **************************************************************************
stapp02                    : ok=4    changed=1    unreachable=0    failed=0    skipped=0

Manual Verification (Optional): You can confirm the file's content and permissions on the remote host using an ad-hoc command:

ansible stapp02 -i inventory -m command -a "cat /var/www/html/index.html" --become
# Output: This file was created using Ansible on stapp02

ansible stapp02 -i inventory -m command -a "ls -l /var/www/html/index.html" --become
# Output should show -rwxr-xr-x (0755) and ownership steve:steve


Deep Dive: Ansible Concepts Used

Jinja2 Templates

Jinja2 is a templating language for Python that Ansible leverages heavily. It allows you to create dynamic configuration files that adapt to the environment they are deployed in. When Ansible encounters {{ variable_name }}, it evaluates it against gathered facts and inventory data before pushing the file.

The template Module

The template module is the engine that processes .j2 files. 1. It reads the src file from the control node (jump host). 2. It parses all Jinja2 expressions ({{ ... }}, {% ... %}). 3. It transfers the resulting rendered text to the dest path on the managed node. 4. Unlike the copy module (which copies files exactly as they are), the template module is strictly meant for files requiring dynamic data injection.