Ansible:遍历多个单独的列表
Ansible: Iterating through multiple separate lists
我正在尝试使用 ansible-zabbix 模块向 Zabbix 服务器添加代理
我有收集 IP addresses/hostnames of servers/proxies/agents
的变量
我需要去每个 zabbix 服务器并添加我拥有的所有代理。
我尝试了几种不同的 "with_XXX" 循环,其中 none 似乎有效。
环境:CentOS7、Ansible2.8、Python2.7、Zabbix4.2
---
- name: Install and configure Zabbix Proxy + Agent
hosts: zabbix-proxy
become: true
gather_facts: true
vars:
proxy_env:
http_proxy: proxy_used_in_different_tasks
https_proxy: proxy_used_in_different_tasks
servervars:
ip: "{{ groups['zabbix-server'] | map('extract', hostvars, ['ansible_default_ipv4', 'address']) | join(',') }}" # server nodes IPs as a comma delimited string, for configs
ip_list: "{{ groups['zabbix-server'] | map('extract', hostvars, ['ansible_default_ipv4', 'address']) | list }}" # server nodes IPs as a list, for ansible
hostname: "{{ groups['zabbix-server'] | map('extract', hostvars, 'ansible_hostname') | list }}" #server nodes hostnames as a list
proxyvars:
ip: "{{ groups['zabbix-proxy'] | map('extract', hostvars, ['ansible_default_ipv4', 'address']) | join(',') }}" # proxy nodes IPs as a comma delimited string, for configs
ip_list: "{{ groups['zabbix-proxy'] | map('extract', hostvars, ['ansible_default_ipv4', 'address']) | list }}" # proxy nodes IPs as a list, for ansible
hostname: "{{ groups['zabbix-proxy'] | map('extract', hostvars, 'ansible_hostname') | list }}" #proxy nodes hostnames as a list
agentvars:
ip_list: "{{ groups['zabbix-agent-only'] | map('extract', hostvars, ['ansible_default_ipv4', 'address']) | list }}" # agent nodes IPs as a list, for ansible
hostname: "{{ groups['zabbix-agent-only'] | map('extract', hostvars, 'ansible_hostname') | list }}" #agent nodes hostnames as a list
tasks:
### below works fine - shows all facts I need
- debug:
msg:
- TEST 1
- "{{ servervars }}"
- TEST 2
- "{{ proxyvars }}"
- TEST 3
- "{{ agentvars }}"
- name: Create proxies on the server
local_action:
module: zabbix_proxy
server_url: "http://{{ item.0.hostname }}.net.local"
login_user: Admin
login_password: zabbix
proxy_name: "{{ item.1.hostname }}"
description: Proxy
status: active
state: present
interface:
type: 0
main: 1
useip: 0
ip: "{{ item.1.ip_list }}"
dns: "{{ item.1.hostname }}"
port: 10050
with_list:
- "{{ servervars }}"
- "{{ proxyvars }}"
预期:在服务器上创建代理(当前设置为 1xServer、1xProxy、2xAgent 作为测试环境)
实际结果:大部分我得到错误:
"FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: dict object has no element 0\n\nThe error appears to have been in '/root/proxy.yml': line 41, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n - name: Create proxies in the server\n ^ here\n\nexception type: <class 'ansible.errors.AnsibleUndefinedVariable'>\nexception: dict object has no element 0"}"
我觉得你需要with_nested
而不是 with_list
https://docs.ansible.com/ansible/latest/user_guide/playbooks_loops.html#with-nested-with-cartesian
有效
我用嵌套 loop
替换了 with_XXX
,但我也稍微更改了我的变量结构
最终版本如下所示:
---
- name: Install and configure Zabbix Proxy + Agent
hosts: zabbix-proxy
become: true
vars:
proxy_env:
http_proxy: proxy_used_in_different_tasks
https_proxy: proxy_used_in_different_tasks
allvars:
servervars:
ip: "{{ groups['zabbix-server'] | map('extract', hostvars, ['ansible_default_ipv4', 'address']) | join(',') }}" # server nodes IPs as a comma delimited string, for configs
ip_list: "{{ groups['zabbix-server'] | map('extract', hostvars, ['ansible_default_ipv4', 'address']) | list }}" # server nodes IPs as a list, for ansible
hostname: "{{ groups['zabbix-server'] | map('extract', hostvars, 'ansible_hostname') | list }}" #server nodes hostnames as a list
proxyvars:
ip: "{{ groups['zabbix-proxy'] | map('extract', hostvars, ['ansible_default_ipv4', 'address']) | join(',') }}" # proxy nodes IPs as a comma delimited string, for configs
ip_list: "{{ groups['zabbix-proxy'] | map('extract', hostvars, ['ansible_default_ipv4', 'address']) | list }}" # proxy nodes IPs as a list, for ansible
hostname: "{{ groups['zabbix-proxy'] | map('extract', hostvars, 'ansible_hostname') | list }}" #proxy nodes hostnames as a list
agentvars:
ip_list: "{{ groups['zabbix-agent-only'] | map('extract', hostvars, ['ansible_default_ipv4', 'address']) | list }}" # agent nodes IPs as a list, for ansible
hostname: "{{ groups['zabbix-agent-only'] | map('extract', hostvars, 'ansible_hostname') | list }}" #agent nodes hostnames as a list
tasks:
- name: Create proxies in the server
local_action:
module: zabbix_proxy
server_url: "http://{{ item.0 }}.net.local/zabbix/"
login_user: Admin
login_password: zabbix
proxy_name: "{{ item.1 }}"
description: Proxy
status: active
state: present
interface:
type: 0
main: 1
useip: 0
ip: "{{ item.2 }}"
dns: "{{ item.1 }}"
port: 10050
loop: "{{ allvars.servervars.hostname|product(allvars.proxyvars.hostname, allvars.proxyvars.ip_list)|list }}"
我正在尝试使用 ansible-zabbix 模块向 Zabbix 服务器添加代理
我有收集 IP addresses/hostnames of servers/proxies/agents
的变量我需要去每个 zabbix 服务器并添加我拥有的所有代理。
我尝试了几种不同的 "with_XXX" 循环,其中 none 似乎有效。 环境:CentOS7、Ansible2.8、Python2.7、Zabbix4.2
---
- name: Install and configure Zabbix Proxy + Agent
hosts: zabbix-proxy
become: true
gather_facts: true
vars:
proxy_env:
http_proxy: proxy_used_in_different_tasks
https_proxy: proxy_used_in_different_tasks
servervars:
ip: "{{ groups['zabbix-server'] | map('extract', hostvars, ['ansible_default_ipv4', 'address']) | join(',') }}" # server nodes IPs as a comma delimited string, for configs
ip_list: "{{ groups['zabbix-server'] | map('extract', hostvars, ['ansible_default_ipv4', 'address']) | list }}" # server nodes IPs as a list, for ansible
hostname: "{{ groups['zabbix-server'] | map('extract', hostvars, 'ansible_hostname') | list }}" #server nodes hostnames as a list
proxyvars:
ip: "{{ groups['zabbix-proxy'] | map('extract', hostvars, ['ansible_default_ipv4', 'address']) | join(',') }}" # proxy nodes IPs as a comma delimited string, for configs
ip_list: "{{ groups['zabbix-proxy'] | map('extract', hostvars, ['ansible_default_ipv4', 'address']) | list }}" # proxy nodes IPs as a list, for ansible
hostname: "{{ groups['zabbix-proxy'] | map('extract', hostvars, 'ansible_hostname') | list }}" #proxy nodes hostnames as a list
agentvars:
ip_list: "{{ groups['zabbix-agent-only'] | map('extract', hostvars, ['ansible_default_ipv4', 'address']) | list }}" # agent nodes IPs as a list, for ansible
hostname: "{{ groups['zabbix-agent-only'] | map('extract', hostvars, 'ansible_hostname') | list }}" #agent nodes hostnames as a list
tasks:
### below works fine - shows all facts I need
- debug:
msg:
- TEST 1
- "{{ servervars }}"
- TEST 2
- "{{ proxyvars }}"
- TEST 3
- "{{ agentvars }}"
- name: Create proxies on the server
local_action:
module: zabbix_proxy
server_url: "http://{{ item.0.hostname }}.net.local"
login_user: Admin
login_password: zabbix
proxy_name: "{{ item.1.hostname }}"
description: Proxy
status: active
state: present
interface:
type: 0
main: 1
useip: 0
ip: "{{ item.1.ip_list }}"
dns: "{{ item.1.hostname }}"
port: 10050
with_list:
- "{{ servervars }}"
- "{{ proxyvars }}"
预期:在服务器上创建代理(当前设置为 1xServer、1xProxy、2xAgent 作为测试环境)
实际结果:大部分我得到错误:
"FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: dict object has no element 0\n\nThe error appears to have been in '/root/proxy.yml': line 41, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n - name: Create proxies in the server\n ^ here\n\nexception type: <class 'ansible.errors.AnsibleUndefinedVariable'>\nexception: dict object has no element 0"}"
我觉得你需要with_nested
而不是 with_list
https://docs.ansible.com/ansible/latest/user_guide/playbooks_loops.html#with-nested-with-cartesian
有效
我用嵌套 loop
替换了 with_XXX
,但我也稍微更改了我的变量结构
最终版本如下所示:
---
- name: Install and configure Zabbix Proxy + Agent
hosts: zabbix-proxy
become: true
vars:
proxy_env:
http_proxy: proxy_used_in_different_tasks
https_proxy: proxy_used_in_different_tasks
allvars:
servervars:
ip: "{{ groups['zabbix-server'] | map('extract', hostvars, ['ansible_default_ipv4', 'address']) | join(',') }}" # server nodes IPs as a comma delimited string, for configs
ip_list: "{{ groups['zabbix-server'] | map('extract', hostvars, ['ansible_default_ipv4', 'address']) | list }}" # server nodes IPs as a list, for ansible
hostname: "{{ groups['zabbix-server'] | map('extract', hostvars, 'ansible_hostname') | list }}" #server nodes hostnames as a list
proxyvars:
ip: "{{ groups['zabbix-proxy'] | map('extract', hostvars, ['ansible_default_ipv4', 'address']) | join(',') }}" # proxy nodes IPs as a comma delimited string, for configs
ip_list: "{{ groups['zabbix-proxy'] | map('extract', hostvars, ['ansible_default_ipv4', 'address']) | list }}" # proxy nodes IPs as a list, for ansible
hostname: "{{ groups['zabbix-proxy'] | map('extract', hostvars, 'ansible_hostname') | list }}" #proxy nodes hostnames as a list
agentvars:
ip_list: "{{ groups['zabbix-agent-only'] | map('extract', hostvars, ['ansible_default_ipv4', 'address']) | list }}" # agent nodes IPs as a list, for ansible
hostname: "{{ groups['zabbix-agent-only'] | map('extract', hostvars, 'ansible_hostname') | list }}" #agent nodes hostnames as a list
tasks:
- name: Create proxies in the server
local_action:
module: zabbix_proxy
server_url: "http://{{ item.0 }}.net.local/zabbix/"
login_user: Admin
login_password: zabbix
proxy_name: "{{ item.1 }}"
description: Proxy
status: active
state: present
interface:
type: 0
main: 1
useip: 0
ip: "{{ item.2 }}"
dns: "{{ item.1 }}"
port: 10050
loop: "{{ allvars.servervars.hostname|product(allvars.proxyvars.hostname, allvars.proxyvars.ip_list)|list }}"