如何在Ansible的不同库存之间共享group_vars?

时间:2016-11-15 09:59:33

标签: ansible

Ansible最佳实践文档recommends用于分离库存:

inventories/
   production/
      hosts.ini           # inventory file for production servers
      group_vars/
         group1           # here we assign variables to particular groups
         group2           # ""
      host_vars/
         hostname1        # if systems need specific variables, put them here
         hostname2        # ""

   staging/
      hosts.ini           # inventory file for staging environment
      group_vars/
         group1           # here we assign variables to particular groups
         group2           # ""
      host_vars/
         stagehost1       # if systems need specific variables, put them here
         stagehost2       # ""

我的登台和制作环境的结构相同。我在两个环境中都有相同的组。事实证明,我对同一组也有相同的group_vars。这意味着我想消除的冗余。

有没有办法在不同的库存之间共享一些group_vars?

作为一种解决方法,我开始将共享的group_vars放入角色中。

my_var:
  my_group:
    - { var1: 1, var2: 2 }

这样就可以通过将主机组与定义的var相交来迭代某些变量:

with_items: "{{group_names | intersect(my_var.keys())}}"

但要理解这一点有点复杂,我认为角色不应该对群体有任何了解。

我想将大部分库存分开,但是以易于理解的方式分享一些group_vars。是否可以将全局group_vars与特定于库存的group_vars合并?

3 个答案:

答案 0 :(得分:3)

您也可以将group_vars放在playbook目录中。 More info

Ansible将为所有库存提取它们。

答案 1 :(得分:3)

这里的简单选项(以及我们所做的)只是符号链接通用组vars文件。

例如,对于像NGINX这样的东西,我们可能会有一个通用的角色,然后是该角色的一些具体用例。在这种情况下,我们创建一个组vars文件,该文件对每个具体用例使用NGINX角色,然后简单地将这些组vars文件符号链接到相应的文件夹中。

我们的项目文件夹结构可能看起来像这样(大大简化):

.
├── inventories
│   ├── bar-dev
│   │   ├── group_vars
│   │   │   ├── bar.yml -> ../../shared/bar.yml
│   │   │   └── dev.yml -> ../../shared/dev.yml
│   │   └── inventory
│   ├── bar-prod
│   │   ├── group_vars
│   │   │   ├── bar.yml -> ../../shared/bar.yml
│   │   │   └── prod.yml -> ../../shared/prod.yml
│   │   └── inventory
│   ├── bar-test
│   │   ├── group_vars
│   │   │   ├── bar.yml -> ../../shared/bar.yml
│   │   │   └── test.yml -> ../../shared/test.yml
│   │   └── inventory
│   ├── foo-dev
│   │   ├── group_vars
│   │   │   ├── dev.yml -> ../../shared/dev.yml
│   │   │   └── foo.yml -> ../../shared/foo.yml
│   │   └── inventory
│   ├── foo-prod
│   │   ├── group_vars
│   │   │   ├── foo.yml -> ../../shared/foo.yml
│   │   │   └── prod.yml -> ../../shared/prod.yml
│   │   └── inventory
│   ├── foo-test
│   │   ├── group_vars
│   │   │   ├── foo.yml -> ../../shared/foo.yml
│   │   │   └── test.yml -> ../../shared/test.yml
│   │   └── inventory
│   └── shared
│       ├── bar.yml
│       ├── dev.yml
│       ├── foo.yml
│       ├── prod.yml
│       └── test.yml
└── roles
    └── nginx
        ├── defaults
        │   └── main.yml
        ├── meta
        │   └── main.yml
        ├── tasks
        │   └── main.yml
        └── templates
            └── main.yml

现在,我们的库存文件可以让主机使用这些共享组变量,只需将主机放在正确的组中即可。

答案 2 :(得分:3)

我抓住了想法,遵循Ansible的建议。一年后,我确信Ansible的建议对我的要求没有用。相反,我认为尽可能在不同阶段之间分享是很重要的。

现在我将所有库存放在同一目录中:

production.ini
reference.ini

我注意每个广告资源都会定义一个群组,其中包括所有具有舞台名称的主机。

文件production.ini包含组production

[production:children]
all_production_hosts

文件reference.ini包含组reference

[reference:children]
all_reference_hosts

我只有一个group_vars目录,我在其中为每个分段组定义一个文件:

group_vars/production.yml
group_vars/reference.yml

每个文件定义一个stage变量。文件production.yml定义了这个:

---
stage: production

文件reference.yml定义:

---
stage: reference

这使得可以在生产和参考之间共享其他所有内容。但主人完全不同。通过使用正确的库存,playbook可以在生产或参考主机上运行:

ansible-playbook -i production.ini site.yml
ansible-playbook -i reference.ini site.yml

如果site.yml或角色在生产和参考环境中的行为略有不同,则可以使用stage变量来使用条件。但我尽量避免这样做。因为最好将所有差异移到暂存文件production.ymlreference.yml中的等效定义中。

例如,如果group_vars/all.yml定义了一些用户:

users:
  - alice
  - bob
  - mallory

我想在两个环境中创建用户,但我想从生产环境中排除mallory,我可以定义一个名为effective_users的新组。在reference.yml中,它与users列表相同:

effective_users: >-
  {{ users }}

但在production.yml我可以排除mallory

effective_users: >-
  {{ users | difference(['mallory']) }}

剧本或角色不需要区分这两个阶段,他们可以简单地使用组effective_users。只需选择库存,该组就会自动包含正确的用户列表。