# template-debugging.yml
---
- name: 模板调试示例
hosts: localhost
vars:
debug_template: true
complex_data:
users:
- name: alice
role: admin
permissions: [read, write, delete]
- name: bob
role: user
permissions: [read]
settings:
timeout: 30
retries: 3
endpoints:
api: "https://api.example.com"
auth: "https://auth.example.com"
tasks:
# 调试变量内容
- name: 显示复杂数据结构
debug:
var: complex_data
when: debug_template
# 调试模板渲染结果
- name: 预览模板渲染结果
debug:
msg: |
{% for user in complex_data.users %}
用户: {{ user.name }}
角色: {{ user.role }}
权限: {{ user.permissions | join(', ') }}
{% endfor %}
when: debug_template
# 使用临时文件调试模板
- name: 生成调试模板
template:
src: debug-template.j2
dest: /tmp/debug-output.txt
when: debug_template
- name: 显示调试模板内容
slurp:
src: /tmp/debug-output.txt
register: debug_content
when: debug_template
- name: 输出调试内容
debug:
msg: "{{ debug_content.content | b64decode }}"
when: debug_template
# 验证模板语法
- name: 验证模板语法
template:
src: complex-config.j2
dest: /tmp/syntax-check.conf
check_mode: yes
register: template_syntax
- name: 报告语法检查结果
debug:
msg: "模板语法检查通过"
when: template_syntax is succeeded
# 条件调试输出
- name: 条件调试信息
debug:
msg: |
环境: {{ environment | default('未设置') }}
调试模式: {{ debug_mode | default(false) }}
主机组: {{ group_names | join(', ') }}
变量定义状态:
- app_name: {{ 'defined' if app_name is defined else 'undefined' }}
- database: {{ 'defined' if database is defined else 'undefined' }}
- cache: {{ 'defined' if cache is defined else 'undefined' }}
when: debug_template or debug_mode | default(false)
{# templates/debug-template.j2 #}
{# 调试模板示例 #}
=== 模板调试输出 ===
生成时间: {{ ansible_date_time.iso8601 }}
主机信息: {{ inventory_hostname }} ({{ ansible_default_ipv4.address | default('N/A') }})
=== 变量信息 ===
{% for key, value in vars.items() %}
{% if not key.startswith('ansible_') and not key.startswith('hostvars') %}
{{ key }}: {{ value | to_nice_json }}
{% endif %}
{% endfor %}
=== 主机事实 ===
操作系统: {{ ansible_distribution }} {{ ansible_distribution_version }}
CPU 核心数: {{ ansible_processor_vcpus }}
内存总量: {{ ansible_memtotal_mb }} MB
磁盘信息:
{% for mount in ansible_mounts %}
{{ mount.mount }}: {{ mount.size_total | filesizeformat }} ({{ mount.fstype }})
{% endfor %}
=== 网络信息 ===
{% for interface in ansible_interfaces %}
{% set interface_facts = hostvars[inventory_hostname]['ansible_' + interface] %}
{% if interface_facts.ipv4 is defined %}
{{ interface }}: {{ interface_facts.ipv4.address }}/{{ interface_facts.ipv4.netmask }}
{% endif %}
{% endfor %}
=== 复杂数据处理 ===
{% if complex_data is defined %}
用户列表:
{% for user in complex_data.users %}
- {{ user.name }} ({{ user.role }}): {{ user.permissions | join(', ') }}
{% endfor %}
设置信息:
{% for key, value in complex_data.settings.items() %}
{{ key }}: {{ value }}
{% endfor %}
{% endif %}
=== 条件测试 ===
{% set test_conditions = [
('environment == "production"', environment == 'production'),
('debug_mode is true', debug_mode | default(false)),
('ansible_memtotal_mb > 1024', ansible_memtotal_mb > 1024),
('"webservers" in group_names', 'webservers' in group_names)
] %}
{% for condition, result in test_conditions %}
{{ condition }}: {{ result }}
{% endfor %}
=== 过滤器测试 ===
{% set test_string = "Hello World" %}
原始字符串: {{ test_string }}
大写: {{ test_string | upper }}
小写: {{ test_string | lower }}
反转: {{ test_string | reverse }}
长度: {{ test_string | length }}
Base64: {{ test_string | b64encode }}
{% set test_list = [3, 1, 4, 1, 5, 9, 2, 6] %}
原始列表: {{ test_list }}
排序: {{ test_list | sort }}
去重: {{ test_list | unique | sort }}
最大值: {{ test_list | max }}
最小值: {{ test_list | min }}
平均值: {{ (test_list | sum / test_list | length) | round(2) }}
=== 模板结束 ===
6.7 高级变量技巧
6.7.1 动态变量生成
# dynamic-variables.yml
---
- name: 动态变量生成示例
hosts: all
vars:
base_config:
app_name: myapp
version: "1.0.0"
port: 8080
environment_overrides:
development:
debug: true
log_level: debug
workers: 1
production:
debug: false
log_level: warning
workers: "{{ ansible_processor_vcpus * 2 }}"
tasks:
# 动态合并配置
- name: 生成环境特定配置
set_fact:
app_config: "{{ base_config | combine(environment_overrides[environment]) }}"
vars:
environment: "{{ target_environment | default('development') }}"
# 基于主机信息动态生成变量
- name: 生成主机特定配置
set_fact:
host_config:
hostname: "{{ inventory_hostname }}"
ip_address: "{{ ansible_default_ipv4.address }}"
memory_mb: "{{ ansible_memtotal_mb }}"
cpu_cores: "{{ ansible_processor_vcpus }}"
disk_space: "{{ ansible_mounts | selectattr('mount', 'equalto', '/') | map(attribute='size_total') | first }}"
recommended_workers: "{{ [ansible_processor_vcpus * 2, 8] | min }}"
max_memory_usage: "{{ (ansible_memtotal_mb * 0.8) | int }}M"
# 动态生成服务发现配置
- name: 生成服务发现配置
set_fact:
service_discovery:
web_servers: |
{%- set servers = [] -%}
{%- for host in groups['webservers'] | default([]) -%}
{%- set _ = servers.append({
'name': host,
'ip': hostvars[host]['ansible_default_ipv4']['address'],
'port': hostvars[host]['app_port'] | default(8080)
}) -%}
{%- endfor -%}
{{ servers }}
database_servers: |
{%- set servers = [] -%}
{%- for host in groups['databases'] | default([]) -%}
{%- set _ = servers.append({
'name': host,
'ip': hostvars[host]['ansible_default_ipv4']['address'],
'port': hostvars[host]['db_port'] | default(3306),
'role': hostvars[host]['db_role'] | default('replica')
}) -%}
{%- endfor -%}
{{ servers }}
# 动态生成负载均衡配置
- name: 生成负载均衡器配置
set_fact:
load_balancer_config:
upstream_servers: |
{%- set upstreams = {} -%}
{%- for group_name in ['webservers', 'api_servers', 'worker_servers'] -%}
{%- if groups[group_name] is defined -%}
{%- set servers = [] -%}
{%- for host in groups[group_name] -%}
{%- set server_config = {
'server': hostvars[host]['ansible_default_ipv4']['address'] + ':' + (hostvars[host]['app_port'] | default(8080) | string),
'weight': hostvars[host]['server_weight'] | default(1),
'max_fails': hostvars[host]['max_fails'] | default(3),
'fail_timeout': hostvars[host]['fail_timeout'] | default('30s')
} -%}
{%- set _ = servers.append(server_config) -%}
{%- endfor -%}
{%- set _ = upstreams.update({group_name: servers}) -%}
{%- endif -%}
{%- endfor -%}
{{ upstreams }}
# 显示动态生成的变量
- name: 显示动态配置
debug:
msg: |
应用配置: {{ app_config | to_nice_json }}
主机配置: {{ host_config | to_nice_json }}
服务发现: {{ service_discovery | to_nice_json }}
负载均衡: {{ load_balancer_config | to_nice_json }}
6.7.2 变量继承和覆盖
# variable-inheritance.yml
---
- name: 变量继承和覆盖示例
hosts: all
vars:
# 基础配置(最低优先级)
default_config:
app:
name: myapp
version: "1.0.0"
port: 8080
workers: 4
timeout: 30
database:
host: localhost
port: 3306
pool_size: 10
cache:
enabled: false
ttl: 300
logging:
level: info
format: standard
# 环境特定配置(中等优先级)
environment_config:
development:
app:
workers: 1
timeout: 60
database:
host: dev-db.example.com
pool_size: 5
cache:
enabled: false
logging:
level: debug
production:
app:
workers: 8
timeout: 15
database:
host: prod-db.example.com
pool_size: 20
cache:
enabled: true
ttl: 3600
logging:
level: warning
# 主机特定配置(最高优先级)
host_specific_config:
web1.example.com:
app:
port: 8081
workers: 6
web2.example.com:
app:
port: 8082
workers: 4
db1.example.com:
database:
port: 3307
pool_size: 30
tasks:
# 多层配置合并
- name: 合并配置层次
set_fact:
final_config: |
{%- set config = default_config -%}
{%- if environment is defined and environment in environment_config -%}
{%- set config = config | combine(environment_config[environment], recursive=True) -%}
{%- endif -%}
{%- if inventory_hostname in host_specific_config -%}
{%- set config = config | combine(host_specific_config[inventory_hostname], recursive=True) -%}
{%- endif -%}
{{ config }}
vars:
environment: "{{ target_environment | default('development') }}"
# 显示最终配置
- name: 显示最终配置
debug:
msg: "{{ final_config | to_nice_json }}"
# 基于角色的配置继承
- name: 基于角色的配置
set_fact:
role_config: |
{%- set config = {} -%}
{%- for role in group_names -%}
{%- if role in role_configurations -%}
{%- set config = config | combine(role_configurations[role], recursive=True) -%}
{%- endif -%}
{%- endfor -%}
{{ config }}
vars:
role_configurations:
webservers:
nginx:
worker_processes: "{{ ansible_processor_vcpus }}"
worker_connections: 1024
php:
memory_limit: 256M
max_execution_time: 30
databases:
mysql:
innodb_buffer_pool_size: "{{ (ansible_memtotal_mb * 0.7) | int }}M"
max_connections: 200
loadbalancers:
haproxy:
maxconn: 4096
timeout_connect: 5000
timeout_client: 50000
timeout_server: 50000
# 条件配置覆盖
- name: 条件配置覆盖
set_fact:
conditional_config: |
{%- set config = final_config -%}
{%- if ansible_memtotal_mb < 2048 -%}
{%- set memory_config = {
'app': {'workers': 2},
'database': {'pool_size': 5}
} -%}
{%- set config = config | combine(memory_config, recursive=True) -%}
{%- endif -%}
{%- if ansible_processor_vcpus < 2 -%}
{%- set cpu_config = {
'app': {'workers': 1}
} -%}
{%- set config = config | combine(cpu_config, recursive=True) -%}
{%- endif -%}
{{ config }}
6.8 本章总结
本章深入介绍了 Ansible 的变量和模板系统,主要内容包括:
- 变量系统概述:变量类型、优先级和作用域
- 变量文件管理:组织结构和环境特定配置
- 变量过滤器和测试:内置过滤器、自定义过滤器和变量测试
- Jinja2 模板系统:基础语法、控制结构和宏定义
- 模板使用实践:最佳实践、调试技巧和实际应用
- 高级变量技巧:动态生成、继承和覆盖
掌握变量和模板是编写灵活、可维护的 Ansible Playbook 的关键技能。
6.9 练习题
基础练习
变量定义和使用
- 创建多层次的变量结构
- 实现变量的条件赋值
- 使用变量过滤器处理数据
模板编写
- 编写 Nginx 配置模板
- 创建应用程序配置模板
- 实现条件和循环逻辑
进阶练习
复杂模板
- 设计可重用的模板宏
- 实现模板继承和包含
- 创建动态配置生成
变量管理
- 设计环境特定的变量结构
- 实现变量加密和安全管理
- 创建动态变量生成逻辑
实战练习
- 完整配置管理
- 设计多环境配置管理方案
- 实现配置模板的版本控制
- 创建配置验证和测试机制
返回目录:Ansible 自动化运维教程