Ansible Playbook跨Play传变量实现服务器重启自动化
解决Ansible跨Play传递变量及自动重启流程问题
原代码的核心问题
- set_fact语法错误:你写的
hostvars.localhost.host_a_reboot_required = true不符合Ansible键值对语法规范。 - 跨Play变量传递方式错误:默认
set_fact定义的变量仅在当前Play的主机组内生效,要实现跨Play共享,需将变量存储到localhost的hostvars中。 - EMQX状态检查逻辑错误:用
systemd: state=started是尝试启动服务,而非检查服务是否正在运行,会导致不必要的服务操作。
修正后的完整Playbook
--- - name: 检查HostA是否需要重启 hosts: HostA remote_user: ansible tasks: - name: 检测重启标记文件是否存在 stat: path: /var/run/reboot-required register: reboot_required - name: 将HostA重启需求状态同步到localhost set_fact: host_a_reboot_required: "{{ reboot_required.stat.exists }}" delegate_to: localhost delegate_facts: true - name: 检查冗余节点HostB、HostC的EMQX状态 hosts: [HostB, HostC] remote_user: ansible vars: host_a_needs_reboot: "{{ hostvars.localhost.host_a_reboot_required }}" tasks: - name: 跳过检查(HostA无需重启时) debug: msg: "HostA无需重启,跳过EMQX状态检查" when: not host_a_needs_reboot run_once: true - name: 收集系统服务状态信息 ansible.builtin.service_facts: when: host_a_needs_reboot - name: 标记当前节点EMQX运行状态 set_fact: emqx_running: "{{ ansible_facts.services['emqx.service'].state == 'running' }}" when: host_a_needs_reboot - name: 汇总所有冗余节点EMQX状态到localhost set_fact: all_emqx_running: "{{ groups['HostB'] | map('extract', hostvars, 'emqx_running') | all and groups['HostC'] | map('extract', hostvars, 'emqx_running') | all }}" delegate_to: localhost delegate_facts: true run_once: true when: host_a_needs_reboot - name: 执行HostA重启操作(满足条件时) hosts: HostA remote_user: ansible vars: host_a_needs_reboot: "{{ hostvars.localhost.host_a_reboot_required }}" all_redundant_emqx_ok: "{{ hostvars.localhost.all_emqx_running | default(false) }}" tasks: - name: 跳过重启(HostA无重启需求) debug: msg: "HostA无需重启" when: not host_a_needs_reboot - name: 跳过重启(冗余节点EMQX未全部正常运行) debug: msg: "HostB/HostC的EMQX服务未全部正常运行,无法重启HostA" when: host_a_needs_reboot and not all_redundant_emqx_ok - name: 重启HostA ansible.builtin.reboot: msg: "系统更新完成,自动重启HostA" connect_timeout: 5 reboot_timeout: 600 pre_reboot_delay: 30 when: host_a_needs_reboot and all_redundant_emqx_ok
关键逻辑说明
- 跨Play变量传递:通过
delegate_to: localhost和delegate_facts: true,将需共享的变量存储到localhost的hostvars中,后续Play直接从hostvars.localhost读取即可。 - EMQX状态检查:用
service_facts模块收集服务状态,通过判断emqx.service的state字段确认服务是否运行,避免误启动操作。 - 冗余节点状态校验:用
map+extract提取所有冗余节点的EMQX状态,再用all过滤器判断是否全部正常,确保冗余集群可用才允许重启HostA。 - 分支逻辑清晰:每个环节都添加了条件判断和提示信息,便于排查不同场景下的执行情况。
内容的提问来源于stack exchange,提问作者aleccmedina
相关产品推荐
相关产品推荐

