Ansible如何根据服务器文件值确定脚本执行主机?
解决Ansible中根据服务器状态赋值active_hostname和passive_hostname的问题
核心思路
利用Ansible的set_fact模块结合Jinja2筛选器,从已获取的主机状态数据中精准提取ACTIVE、PASSIVE状态对应的主机名,直接赋值到目标全局变量。以下是具体实现步骤:
1. 确认主机状态已存入主机变量
假设你已经通过任务获取了每台服务器的状态,并将状态值存入了对应主机的node_status变量(比如通过command+register后写入hostvars)。如果还没完成这一步,参考示例任务:
- name: 读取服务器状态文件 command: cat /etc/cluster/status register: status_output delegate_to: "{{ item }}" loop: "{{ groups['your_server_group'] }}" - name: 将状态写入主机变量 set_fact: node_status: "{{ status_output.results | selectattr('item', 'equalto', inventory_hostname) | first | json_query('stdout') | trim }}" loop: "{{ groups['your_server_group'] }}"
2. 提取并赋值ACTIVE/PASSIVE主机名
通过一次set_fact任务批量完成两个变量的赋值,无需循环遍历:
- name: 提取ACTIVE和PASSIVE主机名 set_fact: active_hostname: >- {{ groups['your_server_group'] | map('extract', hostvars) | selectattr('node_status', 'equalto', 'ACTIVE') | map(attribute='inventory_hostname') | first }} passive_hostname: >- {{ groups['your_server_group'] | map('extract', hostvars) | selectattr('node_status', 'equalto', 'PASSIVE') | map(attribute='inventory_hostname') | first }}
代码说明:
groups['your_server_group']:替换为你实际的目标服务器组名称map('extract', hostvars):提取组内每台主机的变量集合selectattr(...):筛选出状态匹配的主机对象map(attribute='inventory_hostname'):从匹配对象中提取主机名first:取第一个匹配结果(适用于单ACTIVE/单PASSIVE场景,多实例场景可替换为list转为列表)
3. 验证变量有效性(可选)
为避免后续任务执行异常,可添加断言检查主机数量是否符合预期:
- name: 验证ACTIVE主机数量 assert: that: - "{{ (groups['your_server_group'] | map('extract', hostvars) | selectattr('node_status', 'equalto', 'ACTIVE') | list | length) == 1 }}" fail_msg: "发现{{ (groups['your_server_group'] | map('extract', hostvars) | selectattr('node_status', 'equalto', 'ACTIVE') | list | length) }}台ACTIVE服务器,预期仅1台" - name: 验证PASSIVE主机数量 assert: that: - "{{ (groups['your_server_group'] | map('extract', hostvars) | selectattr('node_status', 'equalto', 'PASSIVE') | list | length) == 1 }}" fail_msg: "发现{{ (groups['your_server_group'] | map('extract', hostvars) | selectattr('node_status', 'equalto', 'PASSIVE') | list | length) }}台PASSIVE服务器,预期仅1台"
4. 使用变量执行任务
现在可以直接用active_hostname和passive_hostname指定任务执行目标:
- name: 在ACTIVE服务器执行脚本 command: /opt/scripts/active_task.sh delegate_to: "{{ active_hostname }}" - name: 在PASSIVE服务器执行脚本 command: /opt/scripts/passive_task.sh delegate_to: "{{ passive_hostname }}"
内容的提问来源于stack exchange,提问作者ZmirBurger
相关产品推荐
相关产品推荐

