Ansible跨主机访问已定义变量:如何过滤未定义循环项?
问题描述
我有一个运行在集群组节点上的Ansible Playbook,会根据条件设置变量(例如当节点是集群主节点时,设置变量为"Master")。相关Play代码如下:
- name: Determine master node in the cluster hosts: cluster gather_facts: no tasks: - name: Get the Master node hostname shell: <command> register: host_info - set_fact: master_node: "{{ host_info.stdout }}" when: host_info.stdout is search("master") # 示例条件,仅作理解用
我需要在其他主机上访问这个master_node变量,于是编写了如下Play:
- name: Add async standby node hosts: new_node become: yes tasks: - debug: var: hostvars[item]['master_node'] loop: "{{ groups['cluster'] }}"
Inventory配置为:
[cluster] cluster_01 cluster_02 [new_node] new_node_01
执行后debug任务输出如下:
TASK [debug] ********************************************************************************************************************************************************************************* ok: [new_node_01] => (item=cluster_01) => { "ansible_loop_var": "item", "hostvars[item]['primary_node']": "cluster_01", "item": "cluster_01" } ok: [new_node_01] => (item=cluster_02) => { "ansible_loop_var": "item", "hostvars[item]['primary_node']": "VARIABLE IS NOT DEFINED!", "item": "cluster_02" }
请问如何只访问循环中已定义变量的项?
解决方案
方法1:筛选已定义变量的主机列表
通过selectattr过滤器结合defined测试,提前筛选出集群组中存在master_node变量的主机,再循环该列表:
- name: Add async standby node hosts: new_node become: yes tasks: - debug: var: hostvars[item]['master_node'] loop: "{{ groups['cluster'] | selectattr('master_node', 'defined') | list }}"
方法2:在循环任务中添加条件判断
如果不需要修改循环列表,可直接给debug任务添加when条件,仅当变量存在时执行输出:
- name: Add async standby node hosts: new_node become: yes tasks: - debug: var: hostvars[item]['master_node'] loop: "{{ groups['cluster'] }}" when: hostvars[item]['master_node'] is defined
方法3:将主节点设为全局变量(更高效)
在第一个Play中,把主节点信息存储为全局可用变量,后续Play无需遍历集群组,直接调用即可:
- name: Determine master node in the cluster hosts: cluster gather_facts: no tasks: - name: Get the Master node hostname shell: <command> register: host_info - set_fact: master_node: "{{ host_info.stdout }}" when: host_info.stdout is search("master") delegate_to: localhost run_once: yes # 仅执行一次,避免重复设置
在new_node的Play中直接使用变量:
- name: Add async standby node hosts: new_node become: yes tasks: - debug: var: master_node
内容的提问来源于stack exchange,提问作者Mukesh Tanuku
相关产品推荐
相关产品推荐

