Applying Multiple Variable Sets with Ansible Template Module: From Fundamentals to Advanced Practices

Dec 04, 2025 · Programming · 10 views · 7.8

Keywords: Ansible Template Module | Variable Management | Automated Configuration

Abstract: This article provides an in-depth exploration of various methods for applying different variable sets to the same template file using Ansible's template module. By comparing direct variable definition via the vars parameter in Ansible 2.x, workaround solutions using include and set_fact for Ansible 1.x compatibility, and advanced applications with with_items loops, it systematically analyzes the core mechanisms of dynamic template variable configuration. With detailed code examples, the article explains the implementation principles, applicable scenarios, and best practices for each approach, helping readers select the most appropriate template variable management strategy based on their specific requirements.

Core Requirements for Dynamic Template Variable Configuration

In automated configuration management scenarios, there is often a need to generate multiple configuration files with different content based on the same template file. Ansible's template module provides powerful support for this, but how to efficiently specify different variable values for each generated file becomes a critical issue in practical applications. This article systematically explores multiple solutions from fundamental to advanced levels.

Direct Variable Definition in Ansible 2.x

Starting from Ansible 2.x, the template module natively supports defining local variables directly for each task through the vars parameter. This method is concise and intuitive, particularly suitable for scenarios with few variables and simple logic.

- name: Generate first configuration file
  template:
    src: config_template.j2
    dest: /etc/app/config1.conf
  vars:
    app_name: "Application One"
    port_number: 8080
    log_level: "INFO"

- name: Generate second configuration file
  template:
    src: config_template.j2
    dest: /etc/app/config2.conf
  vars:
    app_name: "Application Two"
    port_number: 8081
    log_level: "DEBUG"

The advantage of this approach lies in its clear variable scope—each task's variable definitions are independent, preventing unexpected variable pollution. The template file config_template.j2 can contain variable placeholders such as {{ app_name }} and {{ port_number }}. Ansible will replace these with the corresponding variable values when executing each task.

Compatibility Solutions for Ansible 1.x

For environments still using Ansible 1.x, where the template module does not support direct variable passing, workaround solutions are necessary. Below are two validated effective methods:

Method 1: Parameter Passing via Include Statements

By encapsulating the template task in a separate YAML file and using the include statement to pass parameters, similar functionality can be achieved:

# template_task.yml
- name: Template generation task
  template:
    src: "{{ template_src }}"
    dest: "{{ output_dest }}"

# main_playbook.yml
- include: template_task.yml
  template_src: "config_template.j2"
  output_dest: "/etc/app/config1.conf"
  app_name: "Application One"
  port_number: 8080

- include: template_task.yml
  template_src: "config_template.j2"
  output_dest: "/etc/app/config2.conf"
  app_name: "Application Two"
  port_number: 8081

Although this method increases the complexity of file organization, it maintains code reusability, making it particularly suitable for scenarios where the same template logic needs to be reused in multiple places.

Method 2: Dynamic Variable Setting with set_fact

Another approach is to redefine variables before each template task using the set_fact module:

- set_fact:
    app_name: "Application One"
    port_number: 8080

- name: Generate first configuration file
  template:
    src: config_template.j2
    dest: /etc/app/config1.conf

- set_fact:
    app_name: "Application Two"
    port_number: 8081

- name: Generate second configuration file
  template:
    src: config_template.j2
    dest: /etc/app/config2.conf

This method requires attention to variable scope issues, as variables set by set_fact remain effective throughout the playbook execution and may affect subsequent tasks. It is recommended to reset variables using set_fact after task completion or employ local variable management strategies.

Advanced Application: Batch Processing with with_items

For scenarios requiring the generation of multiple similar files from the same template, the with_items loop offers a more elegant solution. This method is particularly suitable for handling multiple configuration items with similar structures but different parameters.

- name: Batch generate Supervisor configuration files
  template:
    src: supervisor_config.j2
    dest: "/etc/supervisor/conf.d/{{ item.name }}.conf"
    owner: root
    group: root
    mode: 0644
  with_items:
    - { name: "web_server", memory: "512m", instances: 3 }
    - { name: "queue_worker", memory: "256m", instances: 5 }
    - { name: "cache_service", memory: "128m", instances: 2 }
  notify: Restart Supervisor service

The corresponding template file supervisor_config.j2 can be designed as follows:

[program:{{ item.name }}]
command=/usr/bin/{{ item.name }} --memory {{ item.memory }}
numprocs={{ item.instances }}
autostart=true
autorestart=true
stdout_logfile=/var/log/{{ item.name }}.log

The advantage of this method lies in its concise code and ease of maintenance. When new configuration items need to be added, simply include a new dictionary in the with_items list. Ansible automatically executes the template task for each list item, generating the corresponding configuration file.

Best Practices and Performance Considerations

In practical applications, selecting the appropriate method requires considering multiple factors:

  1. Ansible Version Compatibility: If the environment supports Ansible 2.x, prioritize direct definition via the vars parameter, as it is the most concise and aligns with Ansible's design philosophy.
  2. Variable Complexity: For scenarios with numerous or structurally complex variables, consider using dictionary or list data structures combined with with_items or with_dict loops.
  3. Code Maintainability: When template logic needs to be reused across multiple playbooks, consider organizing code using include statements or roles.
  4. Performance Optimization: For scenarios requiring the generation of a large number of files, with_items loops are generally more efficient than multiple independent tasks, as they reduce task scheduling overhead.

A comprehensive best practice example:

# Define base configurations in group_vars or host_vars
app_configs:
  primary:
    name: "Primary Application"
    port: 8080
    threads: 50
  secondary:
    name: "Secondary Application"
    port: 8081
    threads: 30

# Use loops in the playbook for processing
- name: Generate all application configurations
  template:
    src: app_config.j2
    dest: "/etc/{{ item.key }}/config.conf"
  vars:
    app_settings: "{{ item.value }}"
  with_dict: "{{ app_configs }}"
  when: app_settings.enabled | default(true)

Common Issues and Debugging Techniques

When working with template variables, the following common issues may arise:

By appropriately selecting and applying these methods, the full potential of Ansible's template module can be leveraged to achieve flexible and efficient configuration file management, providing a solid foundation for automated operations.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.