如何在Ansible中引入其他Playbook并在对应角色主机上运行?
Ansible跨主机触发DNS更新的可行方案
问题场景
我的Ansible清单配置如下:
all: children: my_app_hosts: hosts: 192.168.0.1 dns_servers: hosts: 192.168.0.2 192.168.0.3
我需要在my_app_hosts组的主机上完成"my app"部署后,触发dns_servers组的两台服务器执行update_dns_entries任务(该任务位于dns_servers角色目录下,给定DNS数据可正常运行),告知它们应用可通过192.168.0.1访问。要求DNS更新任务必须在DNS服务器上执行,而非应用主机,但触发动作要从应用部署Playbook发起。
此前尝试的方法均失败:
- 在
include_role中直接使用delegate_to:不支持该用法 - 在
import_role中使用delegate_to:无法配合动态循环(如with_items: "{{ group['dns_servers'] }}") - 独立Playbook配合
include_tasks循环:执行失败
可行解决方案
方案1:拆分Play段(推荐,符合最佳实践)
在同一个Playbook中,先完成应用部署,再新增一个针对dns_servers组的Play,传入应用主机IP作为变量执行DNS更新。这种方式逻辑清晰,易于维护。
示例Playbook:
- name: 部署my app到应用主机 hosts: my_app_hosts tasks: - name: 执行应用部署操作 # 替换为你的实际部署任务 debug: msg: "完成my app部署到{{ inventory_hostname }}" # 记录应用主机IP,供后续DNS更新使用 - name: 保存应用服务器IP set_fact: app_server_ip: "{{ inventory_hostname }}" run_once: true - name: 更新DNS服务器记录 hosts: dns_servers vars: app_domain: "myapp.example.com" # 从应用主机的变量中获取IP app_target_ip: "{{ hostvars['192.168.0.1']['app_server_ip'] }}" tasks: - name: 调用DNS更新任务 include_role: name: dns_servers tasks_from: update_dns_entries vars: dns_record_name: "{{ app_domain }}" dns_record_ip: "{{ app_target_ip }}"
方案2:在应用部署Play中委托执行
如果不想拆分Play,可以在应用部署的最后一步,通过delegate_to循环遍历dns_servers组的所有主机,同时设置run_once: true避免在应用主机上重复执行。
示例代码:
- name: 部署my app到应用主机 hosts: my_app_hosts tasks: - name: 执行应用部署操作 debug: msg: "完成my app部署到{{ inventory_hostname }}" - name: 通知所有DNS服务器更新记录 include_role: name: dns_servers tasks_from: update_dns_entries vars: dns_record_name: "myapp.example.com" dns_record_ip: "{{ inventory_hostname }}" # 委托到每个DNS服务器执行 delegate_to: "{{ item }}" # 遍历dns_servers组的所有主机 loop: "{{ groups['dns_servers'] }}" # 确保只在应用主机上执行一次循环,避免重复触发 run_once: true
失败原因说明
include_role本身不支持将delegate_to作为其参数,但可以在include_role这个任务级别添加delegate_to,这正是方案2的核心思路import_role属于静态导入,在Playbook解析阶段就完成处理,无法配合动态循环(如with_items),而include_role是动态导入,支持循环和委托操作
内容的提问来源于stack exchange,提问作者ahuemmer
相关产品推荐
相关产品推荐

