在Ansible playbook中将多个组指定为来自不同目录的主机

在Ansible playbook中将多个组指定为来自不同目录的主机,ansible,Ansible,我正在寻找一种方法,在Ansible playbook中指定多个组作为主机,当这些组位于单独的清单中时(这类似于,但不同,因为该问题假设一个清单) 假设我有一本叫做《改变事物》的剧本。有时我想改变开发,有时qa,有时生产,等等: ansible playbook-i development-i production change\u things.yml 假设有单独的库存,大致如下所示: # development inventory [development] 10.0.0.1 10.0.0

我正在寻找一种方法,在Ansible playbook中指定多个组作为主机,当这些组位于单独的清单中时(这类似于,但不同,因为该问题假设一个清单)

假设我有一本叫做《改变事物》的剧本。有时我想改变
开发
,有时
qa
,有时
生产
,等等:

ansible playbook-i development-i production change\u things.yml

假设有单独的库存,大致如下所示:

# development inventory

[development]
10.0.0.1
10.0.0.2
如果未明确指定
主机
,则上述playbook无法运行

我有几个问题:

  • 使用
    hosts:all
    似乎有害。如果用户忘记显式声明清单,我可以想象Ansible继承自
    /etc/Ansible/hosts
    中的任何内容
  • 硬编码主机组(
    hosts:development:production
    )是不可取的,因为我可能希望将来运行类似于
    ansible playbook-I development-I qa change\u things.yml的东西

  • 我正在寻找一种方法来维护主机的单独清单,但创建剧本的方式应确保它们可以针对主机组的多个组合执行。我不知道如何告诉Ansible“从这些清单中使用这些组”。

    如果您确实要在不同的清单中分离不同的服务器,那么您可以使用一些常见的名称来命名这些组,如
    服务器

    然后你的库存就会跟进

    ## this is development inventory 
    [servers]
    node1.dev.example.org
    node2.dev.example.org
    
    所以你的剧本将从

    -主机:服务器
    
    你可以用它来运行

    ansible剧本-i开发-i qa剧本.yml
    

    另一种方法,但我必须说,我发现这是一个过于复杂的场景,即使用特殊变量,然后将库存文件的名称与主机组对齐:

    ## this is development inventory 
    [development]
    node1.dev.example.org
    node2.dev.example.org
    
    所以剧本会有一个可怕的结局:

    -hosts:“{{ansible_inventory_sources}map('basename')| map('regex_replace','^([^\\.]*)*).','\\1')| list | join(':')}”
    
    在哪里

    • 将获取文件名,例如
      inventory.yml
    • regex\u replace
      ,在您的用例中并不是真正需要的,但是@Zeitounator借用了它,如果您有清单文件扩展名,比如
      development.yml
      ,它允许删除任何文件扩展名。由于我的清单确实有
      .yml
      扩展名,这一点值得注意
    • 然后,用冒号(
      )将列表添加到后面的问题上
    因此,再次使用

    ansible剧本-i开发-i qa剧本.yml
    
    将生成主机组模式
    development:qa


    这是一个演示(为了演示,使用
    debug
    ,但是,由于变量也可以在
    host
    中使用,这是相同的):

    -hosts:localhost
    收集事实:不
    任务:
    -调试:
    msg:“{ansible_inventory_sources}map('basename')| map('regex_replace','^([^\\.]*)*).','\\1')| list | join(':')}”
    
    概述一下:

    PLAY[localhost]**************************************************************************************************
    任务[调试]******************************************************************************************************
    确定:[本地主机]=>{
    “msg”:“开发:qa”
    }
    重演********************************************************************************************************
    localhost:ok=1已更改=0无法访问=0失败=0跳过=0已获救=0已忽略=0
    
    Q:告诉Ansible‘使用这些库存中的这些组’

    答:在第一个游戏中动态创建一组新的主机,然后使用它。比如说

    shell>cat pb.yml
    -主机:本地主机
    任务:
    -添加\u主机:
    名称:“{{item}}”
    小组:我的小组
    循环:{my_groups | from_yaml | map('extract',groups)| flatten}
    -主持人:我的团队
    任务:
    -调试:
    var:inventory\u主机名
    
    考虑到库存

    shell>cat主机\u产品
    [产品]
    产品1
    产品2
    prod3
    外壳>cat主机
    [qaA]
    qa1
    qa2
    [qaB]
    qa3
    外壳>cat主机\u-devel
    [德维拉]
    devel1
    devel2
    [develB]
    发展
    
    命令

    ansible playbook pb.yml-i hosts\u prod-i hosts\u qa-i hosts\u devel-e“我的团队=[develA,qaB]”
    
    给出(节略)

    播放[我的团队]**********************************************
    任务[调试]**************************************************
    确定:[devel2]=>
    目录\u主机名:devel2
    确定:[devel1]=>
    目录\u主机名:devel1
    确定:[qa3]=>
    清单u主机名:qa3
    

    在命令行上定义库存和my_组的任意组合。

    隔离开发和生产。身体上!通过版本系统共享公共工件(剧本、角色、库存、变量…。@VladimirBotka这只是一个人为的例子,以说明我绝对希望强制执行这种隔离-您可以将它们视为
    red
    服务器和
    green
    服务器。我不想维护多个具有不同默认主机但内容完全相同的剧本。Ansible的版本系统是什么?非常感谢!
    [servers]
    的想法非常优雅。另一方面,我实际上最终选择了一条单独的路径,并在运行时提示主机/组。考虑到隔离主机/资源清册的必要性,我认为提示符可以作为一种额外的故障保护。谢谢-这是一种非常有趣的方法。
    ## this is development inventory 
    [development]
    node1.dev.example.org
    node2.dev.example.org
    
    ## this is qa inventory 
    [qa]
    node1.qa.example.org
    node2.qa.example.org