You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 20:42:44