Ansible 变量与模板:灵活配置管理
Ansible 变量与模板详解:灵活配置管理
变量基础
定义变量
# 在 Playbook 中定义
vars:
app_name: myapp
app_port: 8080
app_config:
debug: true
log_level: info
# 在 Inventory 中定义
[webservers]
web1 ansible_host=192.168.1.10 app_port=8080
web2 ansible_host=192.168.1.11 app_port=8081
# 在变量文件中定义
# vars/common.yml
---
app_name: myapp
app_port: 8080
使用变量
tasks:
- name: Display simple variable
debug:
msg: "App name: {{ app_name }}"
- name: Display nested variable
debug:
msg: "Log level: {{ app_config.log_level }}"
- name: Use variable in task
file:
path: "/opt/{{ app_name }}"
state: directory
变量优先级
Ansible 变量的优先级从低到高(后面的会覆盖前面的):
- Role defaults(角色默认值)
- Inventory file or script group vars
- Inventory group_vars/all
- Inventory group_vars/*
- Inventory file or script host vars
- Inventory host_vars/*
- Host facts / cached set_facts
- Play vars
- Play vars_prompt
- Play vars_files
- Role vars
- Block vars
- Task vars
- Include_vars
- Set_facts / registered vars
- Role params
- Extra vars(命令行参数)
变量文件
创建变量文件
group_vars/webservers.yml:
---
http_port: 80
https_port: 443
document_root: /var/www/html
worker_processes: 4
group_vars/all.yml:
---
ansible_user: ansible
ansible_ssh_private_key_file: ~/.ssh/id_rsa
ansible_python_interpreter: /usr/bin/python3
host_vars/web1.yml:
---
http_port: 8080
server_name: web1.example.com
在 Playbook 中使用
---
- name: Use variable files
hosts: webservers
vars_files:
- vars/common.yml
- vars/{{ ansible_os_family }}.yml
tasks:
- name: Display variables
debug:
msg: "HTTP Port: {{ http_port }}"
Jinja2 模板
基础语法
# 变量输出
{{ variable_name }}
# 条件判断
{% if condition %}
content
{% elif condition %}
content
{% else %}
content
{% endif %}
# 循环
{% for item in list %}
{{ item }}
{% endfor %}
# 过滤器
{{ variable | filter_name }}
# 注释
{# comment #}
模板示例
templates/nginx.conf.j2:
worker_processes {{ worker_processes | default(4) }};
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
server {
listen {{ http_port | default(80) }};
server_name {{ server_name | default('localhost') }};
root {{ document_root }};
index index.html index.htm;
location / {
try_files $uri $uri/ =404;
}
}
}
templates/app.conf.j2:
{% if debug_mode %}
DEBUG = True
{% else %}
DEBUG = False
{% endif %}
LOG_LEVEL = "{{ log_level | default('INFO') }}"
{% for server in servers %}
SERVERS.append({
'host': '{{ server.host }}',
'port': {{ server.port }}
})
{% endfor %}
使用模板
tasks:
- name: Copy Nginx config from template
template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
owner: root
group: root
mode: '0644'
backup: yes
notify: Restart Nginx
- name: Copy app config
template:
src: app.conf.j2
dest: /opt/myapp/config.conf
常用过滤器
# 字符串过滤器
{{ "hello" | upper }} # HELLO
{{ "HELLO" | lower }} # hello
{{ " hello " | trim }} # hello
{{ "hello world" | replace(' ', '_') }} # hello_world
{{ var | default('default_value') }}
# 数字过滤器
{{ 3.14159 | round(2) }} # 3.14
{{ 10 | int }} # 10
{{ "10" | int }} # 10
# 列表过滤器
{{ [1, 2, 3] | length }} # 3
{{ list | first }} # 第一个元素
{{ list | last }} # 最后一个元素
{{ list | sort }} # 排序
{{ list | unique }} # 去重
{{ list | join(', ') }} # 用逗号连接
# 字典过滤器
{{ dict | items() }} # 获取所有键值对
# IP 地址过滤器
{{ "192.168.1.1" | ipaddr }} # 验证 IP 地址
{{ "192.168.1.0/24" | ipaddr('network') }} # 192.168.1.0
动态变量
用户输入
---
- name: Prompt for variables
hosts: all
vars_prompt:
- name: "app_name"
prompt: "Enter application name"
private: no
- name: "db_password"
prompt: "Enter database password"
private: yes
confirm: yes
tasks:
- name: Display inputs
debug:
msg: "App: {{ app_name }} Pass: {{ db_password }}"
注册变量
tasks:
- name: Get disk usage
command: df -h /
register: disk_usage
- name: Display disk usage
debug:
var: disk_usage.stdout_lines
- name: Check if service is running
command: systemctl status nginx
register: service_status
failed_when: false
- name: Display service status
debug:
msg: "Service is {{ 'running' if service_status.rc == 0 else 'not running' }}"
Set Facts
tasks:
- name: Set fact
set_fact:
app_configured: true
install_path: "/opt/{{ app_name }}"
- name: Use fact
debug:
msg: "Install path: {{ install_path }}"
高级技巧
动态变量名
tasks:
- name: Set dynamic variables
set_fact:
"{{ item }}_value": "{{ item }}"
loop:
- foo
- bar
- name: Display dynamic variables
debug:
msg: "{{ foo_value }} {{ bar_value }}"
组合过滤器
# 多个过滤器组合使用
{{ long_list | default([]) | unique | sort | join(', ') }}
条件模板
{% if nginx_ssl_enabled %}
listen {{ nginx_ssl_port }} ssl;
ssl_certificate {{ ssl_cert_path }};
ssl_certificate_key {{ ssl_key_path }};
{% else %}
listen {{ nginx_http_port }};
{% endif %}
最佳实践
- 分层管理: 使用 group_vars 和 host_vars 管理变量
- 默认值: 使用 default 过滤器提供默认值
- 模板化: 使用 Jinja2 模板生成配置文件
- 敏感信息: 使用 Ansible Vault 加密敏感变量
- 命名规范: 使用清晰的变量名
总结
变量和模板是 Ansible 配置管理的核心。通过本文的学习,你已经掌握了变量定义、变量优先级、Jinja2 模板、过滤器等知识。灵活使用变量和模板可以让你的 Playbook 更加灵活和可维护。接下来可以深入学习 Roles、条件判断等内容。
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。







