Open In App

Ansible and Jinja2: Creating Dynamic Templates

Last Updated : 01 Aug, 2024
Comments
Improve
Suggest changes
Like Article
Like
Report

Automation is a very integral part of modern IT operations, where teams can deploy, manage, and scale applications in quite an easy manner. Ansible, with its agentless architecture and very easy configuration language, is one powerful automation tool to do these tasks. One of the most versatile features of Ansible is its integration with Jinja2, a templating engine for Python.

Jinja2 allows the creation of dynamic templates in which variables and other contextual data can be embedded at runtime. That gets particularly handy in generating resources like configuration files or scripts that are adapted to one environment or condition after another. Ansible users can make their playbooks much more flexible and reusable, reducing possible redundancy and the risk of error when using Jinja2 templates.

This article focuses on the way Jinja2 is used in Ansible to create dynamic templates. First, we shall start with the basic concepts, then guide you through a step-by-step process of creating and using templates before finally providing some practical examples that would explain the advantage of the approach. Whether you are new to Ansible or trying to make your automation workflow better, this guide will put you in control of dynamic templating with Jinja2.

Primary Terminologies

Ansible

  • Ansible Playbook: A list of tasks to be executed in the managed hosts, defined in a file using YAML. The playbook defines the overall workflow for automation.
  • Ansible Task: An individual, atomic operation to be performed on the target system. For example, install a package, copy a file, restart a service, etc.
  • Ansible Role: A way of bundling playbooks and other Ansible components into a reusable unit. Roles allow easy reuse, re-sharing, and composition of automation scripts.
  • Inventory: Lists of managed hosts defined in either a file or dynamically retrieved. It is a definition of which hosts that Ansible should manage and what their variables are.

Jinja2

  • Template: A file with text data and a field for dynamic fields. Fields are in Jinja2 notation. Templates can be used to build up output information, configurations, scripts, or any other kind of text file.
  • Variables: Variables are placeholders in a Jinja2 template for real-time, actual values that could be simple values, lists, dictionaries, or more complex kinds of data structures.
  • Filters Functions which you can be applied to a variable in a template expression to modify its value. A typical case is the 'upper' filter that converts the input string to uppercase.
  • Loops: Iteration constructs over lists or dictionaries within a template that allow dynamic generation of repetitive content.
  • Conditionals: Structures which control when content is to be rendered conditionally in a template based on variable values.

Dynamic Templates

  • Dynamic Content: This is the content of a template generated or modified during run-time, depending on input variables and logic defined in the template.
  • Context: A set of variables and their values used by a Jinja2 template at rendering time. The context defines the resulting output that is obtained from a template.

Rendering

  • Render: The process of operating a Jinja2 template, with an environment and variables, up to the final output. This encompasses variable replacement, applying filters, and possibly going as far as evaluating loops and conditionals.
  • YAML: YAML (YAML Ain't Markup Language) A human-readable serialization format that is typically used for configuration files and data interchange between programming languages with dissimilar data structures, of which YAML is a superset. Ansible playbooks are expressed in YAML.

Step-by-Step Process for Creating Dynamic Templates with Ansible and Jinja2

Step 1: Launch an EC2 Instance

Screenshot-2024-07-02-183127

Step 2: Install Ansible

Screenshot-2024-07-22-142901

Step 3: Setup Host Details

Screenshot-2024-05-20-171946

Step 4: Set Up the Project Directory

  • Create a project directory and navigate into it.
mkdir ansible-jinja2-demo
cd ansible-jinja2-demo
Screenshot-2024-07-22-142740

Step 5: Write the Playbook for Creating Your First Jinja2 Template in Ansible

- name: Deploy Nginx configuration
hosts: webservers
become: yes
vars_files:
- vars.yml
tasks:
- name: Copy Nginx configuration file
template:
src: templates/nginx.conf.j2
dest: /etc/nginx/nginx.conf
notify: restart nginx
handlers:
- name: restart nginx
service:
name: nginx
state: restarted
Screenshot-2024-07-22-142629

Step 6: Create the Jinja2 Template

mkdir templates
  • Create a file named nginx.conf.j2 inside the templates directory:
server {
listen {{ nginx_port }};
server_name {{ server_name }};


location / {
proxy_pass http://localhost:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Screenshot-2024-07-22-142526

Step 7: Define Variables in an Ansible Playbook

  • Create a variables file named vars.yml:
nginx_port: 80
server_name: gfg.com #change your server name
Screenshot-2024-07-22-142414

Step 8: Run the Playbook

ansible-playbook demo.yml
Screenshot-2024-07-22-141936

Step 9: Verify the Deployment

  • We can check our deployment by using following command
cat /etc/nginx/nginx.conf
Screenshot-2024-07-22-143239

Looping Through Data with Jinja2 in Ansible

Create a Jinja2 Template with a Loop:

{% for item in items %}
- {{ item }}
{% endfor %}

Define Variables in an Ansible Playbook:

  • Here is the example playbook
- name: Example Playbook with Loops
hosts: all
become: yes
vars:
packages:
- httpd
- mariadb
- php
users:
alice:
password: encrypted_password_for_alice
bob:
password: encrypted_password_for_bob
tasks:
- name: Install packages using loop
yum:
name: "{{ item }}"
state: present
loop: "{{ packages }}"
- name: Create users using loop with_dict
user:
name: "{{ item.key }}"
state: present
password: "{{ item.value.password }}"
with_dict: "{{ users }}"
loop_control:
label: "Creating user {{ item.key }}"
Screenshot-2024-07-09-103155

Run the Playbook

ansible-playbook use_template.yml
Screenshot-2024-07-09-102723-(1)

Error Handling in Templates

Handling errors in Jinja2 templates ensures that your playbooks can gracefully handle missing or invalid data.

Create a Jinja2 Template with Error Handling:

Hello, {{ name | default("Guest") }}!

Define Variables in an Ansible Playbook:

- hosts: localhost
vars:
# name is intentionally omitted
tasks:
- name: Render Jinja2 template with error handling
template:
src: error_handling_template.j2
dest: /tmp/error_handling_output.txt

Run the Playbook:

ansible-playbook use_template.yml

Verify the Output:

cat /tmp/error_handling_output.txt

You should see:

Hello, Guest!

Integrating Templates into Ansible Playbooks

  • Integrating Jinja2 templates into Ansible playbooks allows you to generate dynamic content based on your playbook's data.

Create a Jinja2 Template:

Server name: {{ inventory_hostname }}

Create an Ansible Playbook:

- hosts: all
tasks:
- name: Render Jinja2 template
template:
src: integration_template.j2
dest: /tmp/integration_output.txt
Screenshot-2024-07-28-164218

Run the Playbook

ansible-playbook playbook.yml 
Screenshot-2024-05-24-184052

Conclusion:

In conclusion, the integration of Ansible and Jinja2 provides a very potent solution for the management and deployment of dynamic configurations in a multiplicity of environments. This combination—powerful automation features by Ansible and versatile templating capabilities by Jinja2—makes it easy to create dynamic templates.

We discussed the core terminologies and how playbooks, tasks, roles, inventories, and templates all come together to help automate repetitive tasks and manage the configuration of the system. The example was quite hands-on in terms of practical application, which showed how Jinja2 templates can be assigned dynamically into variables and rendered so that one may create fine-tuned configuration files for certain environments.

This way, through the use of templates, the organization is able to have consistent results without human errors and saves valuable time that would have been consumed by manual creation of these files. The filters, loops, and conditionals supported by Jinja2 put more flexibility and power on the template, which gives it a high capability for adaptation to the configuration.

And that is not just making the deployment process easier but also the maintainability and scalability of it. Embracing Ansible and Jinja2 for dynamic templating is perhaps one of the most important steps into smarter, more effective practice of infrastructure management that DevOps and modern IT operations teams have to take.


Next Article
Article Tags :

Similar Reads