2. 使用变量和模板动态生成配置文件
任务目标
编写一个Ansible Playbook,使用变量结合Jinja2模板,为不同主机动态生成Nginx站点配置文件。要求根据每台主机的inventory_hostname自动设置server_name,并将模板渲染后的文件部署到目标主机的Nginx配置目录。
环境准备
- 控制端已安装Ansible 2.9+
- 目标主机为Linux,已安装Nginx(本例仅生成配置文件,不执行服务重启)
- 控制端与目标主机已配置SSH免密或使用密码参数
目录结构
nginx_vars_demo/
├── ansible.cfg
├── inventory.ini
├── playbook.yml
└── templates/
└── nginx_site.conf.j2
关键完整代码
1. inventory.ini — 定义两台主机,分别设置不同的server_port变量:
[web_servers]
web1 ansible_host=192.168.1.101 server_port=8080
web2 ansible_host=192.168.1.102 server_port=9090
2. templates/nginx_site.conf.j2 — Jinja2模板,使用主机名和端口变量:
server {
listen {{ server_port }};
server_name {{ inventory_hostname }}.example.com;
location / {
root /usr/share/nginx/html;
index index.html;
}
}
3. playbook.yml — 核心Playbook,渲染模板并部署:
---
- name: Generate Nginx config from template
hosts: web_servers
become: yes
vars:
nginx_conf_dir: /etc/nginx/conf.d
tasks:
- name: Ensure conf.d directory exists
file:
path: "{{ nginx_conf_dir }}"
state: directory
- name: Deploy templated Nginx site config
template:
src: nginx_site.conf.j2
dest: "{{ nginx_conf_dir }}/{{ inventory_hostname }}.conf"
owner: root
group: root
mode: '0644'
register: deploy_result
- name: Show generated config content
debug:
msg: "{{ lookup('template', 'nginx_site.conf.j2') }}"
when: deploy_result.changed
4. ansible.cfg — 最小配置,指定清单文件:
[defaults]
inventory = inventory.ini
host_key_checking = False
运行方式
cd nginx_vars_demo
ansible-playbook playbook.yml
验证方法
- Playbook执行结果:观察每个task是否显示
ok或changed,无failed。 - 目标主机文件检查:登录web1执行
cat /etc/nginx/conf.d/web1.conf,应看到server_name web1.example.com;和listen 8080;;登录web2执行同样命令,应看到server_name web2.example.com;和listen 9090;。 - 语法校验:在目标主机执行
nginx -t,输出syntax is ok且test is successful即通过。
预期输出示例
当Playbook执行成功后,web1上生成的/etc/nginx/conf.d/web1.conf内容为:
server {
listen 8080;
server_name web1.example.com;
location / {
root /usr/share/nginx/html;
index index.html;
}
}
常见问题
- 模板未生效:确认
templates/目录与playbook.yml同级,且模板文件名与src一致。 - 变量未定义:若主机未在inventory中设置
server_port,可在playbook的vars中提供默认值,或使用default()过滤器。 - 权限不足:写入
/etc/nginx/conf.d需要root权限,已通过become: yes处理。