为什么在 Ansible 中,我不能在多个子组中拥有相同的密钥?

Why, in Ansible, I can't have same key in many children groups?

我想用我的 ansible 主机文件做一些干净的东西。

如果我使用ansible-playbook --limit calendar -i hosts update_common.yml

Ansible 在所有主机上执行我的剧本,甚至在其他组的主机名上。

显然,它似乎来自我的密钥 devprod :

all:
  children:
    gitlab:
      children:
        dev:
          hosts:
            gitlab-dev:  # Stretch
        prod:
          hosts:
            gitlab-A:   # Stretch
            gitlab-B:   # Stretch
            gitlab-C.mysociety.fr:
              ansible_port: 22
    intranet:
      children:
        dev:
          hosts:
            intra-dev:      # Buster
            wordpress-dev:  # Buster
        prod:
          hosts:
            intra-prod:     # Buster
    calendar:
      children:
        dev:
          hosts:
            calendar-dev:
        prod:
          hosts:
            calendar:

我相信 Ansible 对清单的解释略有不同。

您指定要在 calendar 组中的所有主机上执行的剧本。那个包含 children 组中的所有内容。由于 children 还包含 gitlabintranet...

问题很可能是您在许多不同的级别和位置使用关键字。如果这应该有效,您必须为剧本 运行 指定一个路径。似乎不是 Ansible 的设计方式。

组名必须是唯一的,这是 ansible 的工作方式。您可以使用相同的组名称创建单独的清单文件,并使用不同的清单或具有唯一的组名称调用您的剧本。

查看此问题 https://github.com/ansible/ansible/issues/32247 和一位开发者的评论:

This won't work as group names are unique, they are not based on their relationships with other groups.

I recommend creating parent1_subgroup1 named groups that have the hierarchy you want built in.

Ansible 不存储组的树。该结构是所有组的平面列表。每个组都包含一个累积的主机列表。如果你运行下面的玩法

- hosts: all
  tasks:
    - debug:
        msg: "{{ groups[item] }}"
      loop: "{{ groups.keys()|list }}"
      run_once: true

你会看到组 gitlabintranetcalendar 是相同的因为它们包含组 devprod 中的所有主机。接下来,您会看到组 dev 包含所有四台主机,组 prod 包含所有五台主机。


将结构展平以实现您想要的效果,例如

all:
  children:
    gitlab_dev:
      hosts:
        gitlab-dev:  # Stretch
    gitlab_prod:
      hosts:
        gitlab-A:   # Stretch
        gitlab-B:   # Stretch
        gitlab-C.mysociety.fr:
          ansible_port: 22
    intranet_dev:
      hosts:
        intra-dev:      # Buster
        wordpress-dev:  # Buster
    intranet_prod:
      hosts:
        intra-prod:     # Buster
    calendar_dev:
      hosts:
        calendar-dev:
    calendar_prod:
      hosts:
        calendar:

是的,当我做 ansible-inventory -i hosts --list

我们可以看到它是如何管理的,开发主机被分组在一起,产品也一样:(

    "all": {
        "children": [
            "calendar", 
            "gitlab", 
            "intranet", 
            "ungrouped"
        ]
    }, 
    "dev": {
        "hosts": [
            "calendar-dev", 
            "gitlab-test", 
            "intra-dev", 
            "wordpress-dev"
        ]
    }, 
    "fil-calendar": {
        "children": [
            "dev", 
            "prod"
        ]
    }, 
    "gitlab": {
        "children": [
            "dev", 
            "prod"
        ]
    }, 
    "intranet": {
        "children": [
            "dev", 
            "prod"
        ]
    }, 
    "prod": {
        "hosts": [
            "calendar", 
            "gitlab-A", 
            "gitlab-B", 
            "gitlab-C.mysociety.fr", 
            "intra-prod"
        ]
    }