管理 Ansible YAML 库存文件中的“嵌套”组

2023-12-09

我正在管理多个集群,并且希望将多个清单文件合并到一个清单中,该清单实际上如下所示:

all:
  children:
    cluster_one:
      children:
        controller:
          hosts:
            host1:
            host2:
            host3:
        compute:
          hosts:
            host4:
            host5:
            host6:
    cluster_two:
      children:
        controller:
          hosts:
            host11:
            host12:
            host13:

我期待这最终会像这样解析:

[cluster_one]
host1
host2
host3
host4
host5
host6

[cluster_two]
host11
host12
host13

[controller]
host1
host2
host3
host11
host12
host13

[compute]
host4
host5
host6

有了这个结构,我就可以要求“控制器” cluster_one”与主机模式cluster_one:&controller, 或者如果 我想要所有集群中的所有控制器,我可以要求controller。方便的!

不幸的是,它实际上是这样解析的:

[cluster_one]
host1
host2
host3
host4
host5
host6

[cluster_two]
host11
host12
host13

[controller]
host1
host2
host3
host11
host12
host13

[compute]
host4
host5
host6

[cluster_one:children]
controller
compute

[cluster_two:children]
controller

请注意底部的两个额外条目controller and compute将尊敬的“父母”的孩子分组 YAML 文件,而不是只制作他们的hosts的成员 父母。

例如,如果我跑ansible -i example.yml --list-hosts cluster_one, I get:

  hosts (9):
    host1
    host2
    host3
    host11
    host12
    host13
    host4
    host5
    host6

这是出乎我意料的,让我感到难过。我显然可以重组 inventory 以便其工作(例如,通过使用 INI 格式 inventory 此处所示,或重新构造 YAML 以获得类似的结构),但是 这些解决方案涉及多次列出每个主机,这意味着 事情可能会不同步。

有没有一种方法可以构建库存,让我能够进行分组 想要无需显式列出多个组中的主机吗?


根据 @larsk 的最新答案中的输入进行构建constructed库存插件。原答案如下


如果您对集群组/子组保持相同的命名约定,则可以使用构建的插件进行更多的干燥,从而无需在组中引入额外的变量。

请注意,在库存目录中使用文件名约定也允许库存源的自然加载顺序,而无需修改ansible.cfg

给定以下最小inventories/cluster/cluster.yml静态库存来源:

---
all:
  children:
    cluster_one:
      children:
        cluster_one_controller:
          hosts:
            host1:
            host2:
            host3:
        cluster_one_compute:
          hosts:
            host4:
            host5:
            host6:
    cluster_two:
      children:
        cluster_two_controller:
          hosts:
            host11:
            host12:
            host13:

以及相应的inventories/cluster/cluster_constructed.yml基于现有组名检测的动态库存源:

---
plugin: constructed
strict: false
groups:
  controller: group_names | select('match', '^.*_controller$') | length > 0
  compute: group_names | select('match', '^.*_compute$') | length > 0

我们使用复合库存目录得到了预期的结果

$ ansible-inventory -i inventories/cluster --list
{
    "_meta": {
        "hostvars": {}
    },
    "all": {
        "children": [
            "cluster_one",
            "cluster_two",
            "compute",
            "controller",
            "ungrouped"
        ]
    },
    "cluster_one": {
        "children": [
            "cluster_one_compute",
            "cluster_one_controller"
        ]
    },
    "cluster_one_compute": {
        "hosts": [
            "host4",
            "host5",
            "host6"
        ]
    },
    "cluster_one_controller": {
        "hosts": [
            "host1",
            "host2",
            "host3"
        ]
    },
    "cluster_two": {
        "children": [
            "cluster_two_controller"
        ]
    },
    "cluster_two_controller": {
        "hosts": [
            "host11",
            "host12",
            "host13"
        ]
    },
    "compute": {
        "hosts": [
            "host4",
            "host5",
            "host6"
        ]
    },
    "controller": {
        "hosts": [
            "host1",
            "host11",
            "host12",
            "host13",
            "host2",
            "host3"
        ]
    }
}

原答案


我对这让你感到难过@larks 深感抱歉。不幸的是,正如您刚刚经历的那样:

  • 该组的内容不取决于您定义它的位置,并且最终将合并所有主机/子定义。
  • 任何地方定义为子级的组将包含其他地方定义的所有主机。

我能想到的唯一一个最接近您的初始要求并尽可能尊重 DRY 原则的静态 yaml 库存定义是:

---
all:
  children:
    cluster_one:
      children:
        cluster_one_controller:
          hosts:
            host1:
            host2:
            host3:
        cluster_one_compute:
          hosts:
            host4:
            host5:
            host6:
    cluster_two:
      children:
        cluster_two_controller:
          hosts:
            host11:
            host12:
            host13:
    controller:
      children:
        cluster_one_controller:
        cluster_two_controller:
    compute:
      children:
        controller_one_compute:

这将允许您选择以下任何模式(非详尽列表):

  • 一个完整的集群,例如cluster_one
  • 集群的所有控制器,例如cluster_two_controller or cluster_two:&controller
  • 跨集群的所有计算节点,例如compute
  • ...

希望这能帮助你照亮你的一天(或夜晚......)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

管理 Ansible YAML 库存文件中的“嵌套”组 的相关文章

随机推荐