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.