Ansible inventory:使用多个标准对主机进行分类

Ansible inventory: Categorize hosts with multiple criteria

我是 Ansible 的新手,所以我仍在为它的工作方式而苦苦挣扎...我有一个清单文件,其中包含按环境和功能排序的多个主机:

[PRO-OSB]
host-1
host-2
[PRO-WL]
host-3
host-4
[PRO:children]
PRO-OSB
PRO-WL

但我认为有时我可能需要 运行 剧本指定更多,即关注环境、它的功能、主机集群和主机上的应用程序 运行。所以在简历中每个主机必须有 4 "categories":环境、功能、集群和应用程序。 我怎样才能做到这一点而不必不断重复输入?

How could I achieve this without having to constantly repeat entries?

你不能。您必须在每个需要的组中声明属于它的机器。因此,如果一台机器属于 4 个不同的组(不考虑父组),则必须在 4 个相关组中声明该主机。

A​​nsible 可以选择相反的方式(即为每个主机列出它所属的组)但这不是保留的解决方案,它会很冗长。

为了让事情变得更简单并让 IMO 更安全一些,您可以将您的清单分成几个环境清单(产品、开发......),这样您就可以在每个清单中消除一个级别的复杂性。缺点是您不能使用这样的设置一次定位所有环境。

如果您的库存很大并且针对某种 cluster/cloud 环境(vsphere、aws...),dynamic inventories 可以提供帮助。

Q: "Every host must have 4 "categories": environment, function, cluster and app. How could I achieve this without having to constantly repeat entries?"

A: 可以在 [*:vars] 部分声明默认选项并用主机的特定选项覆盖它。参见 How variables are merged。例如库存

$ cat hosts
[PRO_OSB]
test_01 my_cluster='cluster_A'
test_02
[PRO_WL]
test_03 my_cluster='cluster_A'
test_04
[PRO:children]
PRO_OSB
PRO_WL
[PRO:vars]
my_environment='default_env'
my_function='default_fnc
my_cluster='default_cluster'
my_app='default_app'

与剧本

- hosts: PRO
  gather_facts: false
  tasks:
    - debug:
        msg: "{{ inventory_hostname }}
              {{ my_environment }}
              {{ my_function }}
              {{ my_cluster }}
              {{ my_app }}"

给出(test_01 和 test_03 的 my_cluster 变量被主机的值覆盖)

"msg": "test_01 default_env 'default_fnc cluster_A default_app"
"msg": "test_02 default_env 'default_fnc default_cluster default_app"
"msg": "test_04 default_env 'default_fnc default_cluster default_app"
"msg": "test_03 default_env 'default_fnc cluster_A default_app"

Q: "Run playbooks specifying even more, i.e attending to the environment, its function, cluster of hosts and application."

可以根据需要使用模块 add_host 和主机 select 创建动态组。例如在第一个游戏中创建新组 cluster_A 并在下一个游戏中使用它

- hosts: all
  tasks:
    - add_host:
        name: "{{ item }}"
        group: cluster_A
      loop: "{{ hostvars|
                dict2items|
                json_query('[?value.my_cluster == `cluster_A`].key') }}"
      delegate_to: localhost
      run_once: true

- hosts: cluster_A
  tasks:
    - debug:
        var: inventory_hostname

给予

ok: [test_01] => {
    "inventory_hostname": "test_01"
}
ok: [test_03] => {
    "inventory_hostname": "test_03"
}

对于可能需要这样的东西的人 --

当我尝试为每个主机建立多个变量以根据角色或团队传送文件时,我最终将这种格式用于我的清单文件。

inventory/support/hosts

support:
  hosts: 
    qahost:
      host_role: 
        waiter
        dishwasher
      host_teams: 
        ops
        sales
    awshost:
      host_role:
        waiter
      host_teams:
        dev
    testhost1:
      host_role:
        dishwasher
      host_teams:
        ops
        dev
    testhost2:
      host_role:
        dishwasher
        boss
      host_teams:
        ops
        dev
        sales

并在这部剧中引用了他们:

- name: parse inventory file host variables
  debug:
    msg: |
      - "role attribute of host: {{ item }} is {{ hostvars[item]['host_role'] }}"
      - "team attribute of host: {{ item }} is {{ hostvars[item]['host_teams'] }}"
  with_items: "{{ inventory_hostname }}"
  when: hostvars[item]['host_teams'] is contains (team_name)

带有自定义 extra_var 的 ansible 命令被传递到剧本并在清单中与 when 条件匹配:

ansible-playbook -i inventory/support/hosts -e 'team_name="sales"' playbook.yml