Ansible传多appname时如何基于inventory用add_host构建动态主机组
多appname参数动态构建主机组实现方案
核心思路
传入的appname是逗号分隔的多值字符串,无法直接匹配inventory中的单个组名,因此拆分为两步实现:
- 先通过前置任务拆分参数,遍历所有目标app对应的inventory组,收集所有需要操作的主机
- 用
add_host模块把收集到的主机统一加入自定义动态组,后续业务任务直接针对这个动态组执行即可
修改后的完整playbook(main.yml)
--- # 前置任务:构建动态目标主机组 - name: 构建动态业务主机组 hosts: localhost gather_facts: no tasks: - name: 拆分逗号分隔的appname为列表 set_fact: app_list: "{{ appname.split(',') }}" dynamic_group: "app_targets" - name: 初始化目标主机空列表 set_fact: target_hosts: [] - name: 遍历所有app组收集主机 set_fact: target_hosts: "{{ target_hosts + groups[ENV ~ '_' ~ item ~ '_app'] | default([]) }}" loop: "{{ app_list }}" - name: 将收集到的主机加入动态组 add_host: name: "{{ host_item }}" groups: "{{ dynamic_group }}" # 继承原inventory中配置的连接用户等主机变量 ansible_user: "{{ hostvars[host_item].ansible_user }}" loop: "{{ target_hosts | unique }}" loop_control: loop_var: host_item # 业务任务:在动态组上执行原有操作 - name: 执行业务部署任务 hosts: app_targets tasks: - name: 确保apache为最新版本 yum: name: httpd state: latest
执行方式
直接使用原命令执行即可:
ansible-playbook -i inventory.hosts main.yml -e ENV=dev -e appname="flipkart,amazon"
执行时会自动匹配dev_flipkart_app、dev_amazon_app两个组下的主机,最终动态组包含myhost6、myhost9、myhost1三台,和预期结果完全一致,原inventory配置的ansible_user连接参数会自动继承,不需要额外重复配置。
注意事项
- 收集主机后通过
unique过滤器去重,避免同一主机属于多个传入app组时被重复添加,导致任务重复执行 - 组匹配逻辑加了
default([])兜底,如果传入的appname对应不存在的inventory组,不会直接报错中断,会自动跳过无效项 add_host生成的动态组是内存级的,仅在本次playbook运行周期内生效,不会修改本地的inventory.hosts原文件
内容的提问来源于stack exchange,提问作者Ashar
相关产品推荐
相关产品推荐

