Ansible Automation

Dynamic Configs with Templates

Lesson 8 of 12 · 8 min · Intermediate

In Ansible, a template is a text file that allows dynamic content generation. Stop maintaining 50 separate configuration files for 50 servers; build one template and let Ansible inject the unique variables at runtime.

Why Use Templates?

Deploying identical files to every server is easy with the copy module. But when a file needs to differ slightly per host (like injecting specific IP addresses or unique hostnames), you need a template.

Reduces Duplication

One single template file can serve your entire infrastructure, automatically adjusting itself to fit the specific server it is deployed to.

Ensures Consistency

By using a single source of truth, you ensure standard configurations across the fleet while still allowing for dynamic variations.

Template Files & Syntax

apache.conf.j2
# Dynamically injected Hostname
ServerName {{ ansible_hostname }}

# Dynamically injected IP Address
Listen {{ ansible_default_ipv4.address }}:80

What is a Template?

A template is simply a normal text file that contains placeholders. These placeholders are written using Jinja2 syntax, which is recognized by double curly braces {{ }}.

The .j2 Extension

Templates typically use the .j2 file extension (e.g., apache.conf.j2). While the extension is not strictly mandatory, it is the universal Ansible standard and helps text editors apply the correct syntax highlighting.

The Template Module

To deploy a template to a managed node, you use the template module inside your playbook. It works very similarly to the copy module, but it processes the Jinja2 variables before transferring the file.

deploy.yml
---
- name: Deploy Web Configuration
  hosts: webservers
  tasks:
    - name: Deploy Apache configuration via template
      template:
        src: apache.conf.j2
        dest: /etc/apache2/apache.conf

Advanced Features (Logic)

Programming Logic

Jinja2 isn't just for variable substitution. It is a fully-featured templating engine that allows you to use programming logic like Conditionals and Loops directly inside your configuration files.

  • {% if %} Write configuration blocks that only appear if certain conditions (like the OS family) are met.
  • {% for %} Iterate over lists of variables (like an array of IPs or packages) to generate repeated config lines automatically.

advanced.conf.j2 JINJA2

# Condition Example
$ {% if ansible_os_family == "Debian" %}
# PackageManager apt
# Loop Example
$ {% for pkg in packages %}
# Install {{ pkg }}

Final Summary