Swiftorial Logo
Home
Swift Lessons
Matchups
CodeSnaps
Tutorials
Career
Resources

Using Jinja2 with Templates in Ansible

Introduction

Jinja2 is a modern and designer-friendly templating engine for Python. In the context of Ansible, Jinja2 templates are used to generate configuration files or scripts dynamically. This tutorial will guide you through the steps necessary to use Jinja2 templates in Ansible from start to finish.

Prerequisites

Before we begin, ensure that you have the following installed on your system:

  • Ansible
  • Python (which is required to run Ansible)

Setting Up Your Environment

First, make sure you have Ansible installed. You can install Ansible using pip:

pip install ansible

Creating a Jinja2 Template

Jinja2 templates are written in plain text and can include variables, loops, and conditionals. Let’s create a simple Jinja2 template to generate an Nginx configuration file. Create a file named nginx.conf.j2 with the following content:

server {
    listen 80;
    server_name {{ server_name }};

    location / {
        proxy_pass http://{{ proxy_pass }};
        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;
    }
}
                    

Creating an Ansible Playbook

Next, create an Ansible playbook to use the Jinja2 template. Create a file named site.yml with the following content:

---
- name: Configure Nginx
  hosts: webservers
  vars:
    server_name: example.com
    proxy_pass: 127.0.0.1:8080
  tasks:
    - name: Template out the Nginx configuration file
      template:
        src: nginx.conf.j2
        dest: /etc/nginx/nginx.conf
    - name: Ensure Nginx is running
      service:
        name: nginx
        state: restarted
                    

Running the Playbook

To run the playbook, use the following command:

ansible-playbook -i inventory site.yml

Ensure that your inventory file is correctly set up with the target hosts. For example:

[webservers]
webserver1 ansible_host=192.168.1.100 ansible_user=root
                    

Understanding the Output

Once the playbook has been executed, Ansible will use the Jinja2 template to generate the /etc/nginx/nginx.conf file on the target hosts. You can check the file to ensure that the variables have been replaced correctly:

server {
    listen 80;
    server_name example.com;

    location / {
        proxy_pass http://127.0.0.1:8080;
        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;
    }
}
                

Advanced Usage

Jinja2 templates support more advanced features such as loops and conditionals. Here is an example that includes a loop:

{% for server in upstream_servers %}
server {
    listen 80;
    server_name {{ server.name }};

    location / {
        proxy_pass http://{{ server.proxy_pass }};
        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;
    }
}
{% endfor %}
                    

Your playbook would then include a list of upstream servers:

---
- name: Configure Nginx
  hosts: webservers
  vars:
    upstream_servers:
      - name: example1.com
        proxy_pass: 127.0.0.1:8081
      - name: example2.com
        proxy_pass: 127.0.0.1:8082
  tasks:
    - name: Template out the Nginx configuration file
      template:
        src: nginx.conf.j2
        dest: /etc/nginx/nginx.conf
    - name: Ensure Nginx is running
      service:
        name: nginx
        state: restarted
                    

Conclusion

Using Jinja2 templates in Ansible allows you to dynamically generate configuration files and scripts based on variables and conditions. This tutorial covered the basics of creating and using Jinja2 templates within Ansible playbooks. With these skills, you can create more complex and dynamic configurations tailored to your needs.