如何解析具有特定属性的库存成员?

How can I resolve an inventory member who has a certain attribute?

我需要将清单中的特定主机作为参数传递给角色。主机是组的一部分,但由其他主机的 none 具有的变量划分。

片段:hosts.yml

  dbservers:
       hosts:
        pg01:
         ansible_host: pg01.domain.com
         master_slave: master
        pg02:
         ansible_host: pg02.domain.com
         master_slave: slave

我希望能够根据变量 master_slave 设置为 'master' 的事实来解析 pg01,这样我就可以调用这样的角色:

      - name: Do something
        include_role:
         name: a.database.role.to.run.on.master
        vars:
          master_database_host: {{ something that resolves to pg01 }}

如何从清单中解析出合适的主机?

您可以在 vars 中使用 if else 条件来赋值。 所以你的玩法应该是这样的。

  - name: Do something
    include_role:
     name: a.database.role.to.run.on.master
    vars:
      master_database_host: "{{ hostvars['pg01']['ansible_host'] if \"{{ hostvars['pg01']['master_slave'] }}\" == 'master' else 'default value goes here'}}"

确保使用正确的转义以使条件语句起作用。

之所以可行,是因为 ansible 在内部使用 python 来做事,这是在 python 中使用三元运算符的一种方式。

您可以混合使用filters来提取您需要的主机:

tasks:
- debug:
    msg: '{{groups["group_name"] | map("extract", hostvars) | selectattr("master_slave", "equalto", "master") | map(attribute="inventory_hostname") | list}}'

一步一步:

groups["group_name"] 是组 group_name.

中所有主机的列表

map("extract", hostvars) 采用 hostvars,一个将主机映射到其变量的字典,并提取 group_name(即 groups["group_name"])中的主机。这会生成一个列表,其中包含映射到其变量的 group_name 中的主机。

selectattr("master_slave", "equalto", "master") 选择属性 master_slave 等于 master 的所有主机。这会生成一个列表,其中包含映射到其变量的所有主机。

map(attribute="inventory_hostname") 将列表作为输入,returns 每个项目的 inventory_hostname 属性。这会生成一个包含所有主机的列表。

下面的戏(with json_query)

- hosts: dbservers
  tasks:
    - set_fact:
        master_database_host: "{{ groups['dbservers']|
                                  map('extract',hostvars)|
                                  list|
                                  json_query('[?master_slave==`master`].inventory_hostname')|
                                  first }}"
    - debug:
        var: master_database_host

给予

ok: [pg02] => {
    "master_database_host": "pg01"
}
ok: [pg01] => {
    "master_database_host": "pg01"
}

您还可以根据 master/slave 状态生成动态组:

---
 - name: Play to create dynamic groups
   hosts: dbservers
   gather_facts: false
   tasks:
    - name: Create groups based on variable master_slave
      group_by:
        key: "database-{{ hostvars[inventory_hostname]['master_slave'] }}"

 - name: Play to use the dynamic group database-master
   hosts: database-master
   gather_facts: false
   tasks:
    - name: Show hosts in group
      debug:
        msg: "This is {{ inventory_hostname }} from the dynamic database-master group."

第一个游戏使用所有数据库服务器并根据 master_slave 变量创建动态组。 动态组是:

  • database-master 包含 pg01
  • database-slave 包含 pg02

第二个剧本使用其中一个动态创建的组。

要使用 group_by 使用的变量必须存在于所有使用的主机。

这个概念最适用于通过 ansibles 设置收集的自动变量,例如ansible_distribution 根据发行版(Debian、Redhat、Ubuntu ...)或使用 ansible_distribution_version.

的发行版创建动态组