Ansible Templates
Overview
Learn how to effectively use Jinja2 templates in Ansible for dynamic configuration management.
Basic Syntax
Simple Variable Substitution
# nginx.conf.j2
server {
listen {{ http_port }};
server_name {{ server_name }};
root {{ web_root }};
}
Loops and Conditionals
# vhosts.conf.j2
{% for vhost in virtual_hosts %}
server {
listen {{ vhost.port | default(80) }};
server_name {{ vhost.domain }};
{% if vhost.ssl | default(false) %}
listen 443 ssl;
ssl_certificate {{ vhost.ssl_cert }};
ssl_certificate_key {{ vhost.ssl_key }};
{% endif %}
root {{ vhost.root }};
{% for alias in vhost.aliases | default([]) %}
server_alias {{ alias }};
{% endfor %}
}
{% endfor %}
Advanced Features
Filters
# app.conf.j2
app_name: {{ application_name | upper }}
version: {{ version | default('1.0.0') }}
port: {{ port | string }}
memory_limit: {{ memory_limit | human_to_bytes }}
timestamp: {{ ansible_date_time.iso8601 }}
admin_email: {{ admin_email | regex_replace('@', ' at ') }}
Complex Data Structures
# config.yaml.j2
database:
host: {{ db.host }}
port: {{ db.port }}
credentials:
{% for user in db.users %}
- username: {{ user.name }}
permissions: {{ user.perms | join(', ') }}
{% endfor %}
cache:
{% for server in cache_servers %}
- host: {{ server.host }}
port: {{ server.port }}
weight: {{ server.weight | default(1) }}
{% endfor %}
Template Inheritance
{# base.conf.j2 #}
{% block server_config %}
server {
listen 80;
}
{% endblock %}
{# site.conf.j2 #}
{% extends "base.conf.j2" %}
{% block server_config %}
server {
listen {{ http_port }};
server_name {{ server_name }};
}
{% endblock %}
Security Features
Escaping Content
# security.conf.j2
# HTML Escaping
description: {{ user_input | escape }}
# Shell Command Escaping
command: {{ shell_command | quote }}
# JSON Escaping
json_data: {{ data | to_json }}
Handling Sensitive Data
# database.conf.j2
{% if vault_enabled %}
password: {{ db_password | vault }}
{% else %}
password: {{ db_password }}
{% endif %}
Best Practices
Template Organization
templates/
├── nginx/
│ ├── nginx.conf.j2
│ ├── vhost.conf.j2
│ └── ssl.conf.j2
├── mysql/
│ ├── my.cnf.j2
│ └── users.sql.j2
└── app/
├── config.yml.j2
└── environment.j2
Error Handling
# config.j2
{% if required_variable is defined %}
value: {{ required_variable }}
{% else %}
{% error "Required variable 'required_variable' is not defined" %}
{% endif %}
Documentation
{#
Template: nginx.conf.j2
Purpose: Main NGINX configuration file
Variables required:
- http_port: Port for HTTP traffic
- server_name: Server domain name
- ssl_enabled: Boolean for SSL configuration
#}
Common Patterns
Environment Configuration
# environment.j2
{% for key, value in environment_vars.items() %}
export {{ key }}={{ value }}
{% endfor %}
Multi-Environment Support
# app_config.j2
{% if environment == 'production' %}
log_level: ERROR
debug: false
{% elif environment == 'staging' %}
log_level: INFO
debug: true
{% else %}
log_level: DEBUG
debug: true
{% endif %}
Dynamic Service Discovery
# haproxy.cfg.j2
backend web_servers
{% for host in groups['webservers'] %}
server {{ host }} {{ hostvars[host]['ansible_host'] }}:80 check
{% endfor %}