Ansible中Playbook与Role间循环创建Nginx虚拟主机报错解决
解决geerlingguy.nginx角色创建虚拟主机时'item'未定义的问题
问题根源
你在host_vars.yml中直接使用{{ item.name }}等循环变量是错误的——item变量仅存在于with_items/loop任务的执行上下文中,全局变量文件(如host_vars)加载时没有这个上下文,因此会抛出未定义错误。
正确配置方式
1. 修正host_vars.yml中的nginx_vhosts变量
直接定义虚拟主机的具体参数,不要用item变量,示例:
# host_vars.yml nginx_vhosts: - name: example.com server_name: example.com www.example.com root: /var/www/example.com index: index.html index.htm - name: test.com server_name: test.com root: /var/www/test.com
2. 简化Playbook调用逻辑
geerlingguy.nginx角色本身已经通过with_items: "{{ nginx_vhosts }}"遍历虚拟主机列表,你不需要额外在playbook里用include_tasks循环调用vhosts.yml,直接调用角色即可:
# Playbook.yml - name: Configure Nginx hosts: web_servers roles: - role: geerlingguy.nginx
3. 自定义vhost任务的正确姿势(可选)
如果要覆盖角色默认的vhost任务,确保自定义的vhosts.yml中正确绑定循环上下文:
# vhosts.yml - name: Create Nginx vhost configs template: src: vhost.j2 dest: /etc/nginx/sites-available/{{ item.name }}.conf with_items: "{{ nginx_vhosts }}" notify: reload nginx - name: Enable Nginx vhosts file: src: /etc/nginx/sites-available/{{ item.name }}.conf dest: /etc/nginx/sites-enabled/{{ item.name }}.conf state: link with_items: "{{ nginx_vhosts }}" notify: reload nginx
此时在vhost.j2模板中可以正常使用{{ item.name }}、{{ item.server_name }}等变量,因为模板是在循环任务的上下文里渲染的。
关键注意事项
- 全局变量文件(host_vars/group_vars)里只能定义静态值或引用全局已存在的变量,不能引用循环上下文专属的
item。 - geerlingguy.nginx角色的默认逻辑已经支持通过
nginx_vhosts变量批量创建虚拟主机,无需额外手动循环调用任务。
内容的提问来源于stack exchange,提问作者Eduardo Saverin
相关产品推荐
相关产品推荐

