如何正确构建 Ansible 清单

How to properly build an Ansible inventory

我想构建一个 Ansible 清单,但又不想把它弄得一团糟,而且我喜欢 DRY。 我查看了 Ansible Docs,但找不到以下信息:

我目前正在使用这种格式来构建清单。

[dev-postgres]
a1-dev-01 ansible_host=vm-1.my.internal.domain.com 
a1-dev-02 ansible_host=vm-2.my.internal.domain.com 

[dev-ldap]
a1-dev-02 ansible_host=vm-2.my.internal.domain.com 
a1-dev-03 ansible_host=vm-3.my.internal.domain.com 

[dev:children]
dev-ldap
dev-postgres

[dev:vars]
env=dev

[jumphost]
a2-jump-01 ansible_host=vm-0.my.internal.domain.com 

关于此设置我有三个问题:

使用constructed库存插件。参见

shell> ansible-doc -t inventory constructed

例如

shell> cat hosts-627/1-hosts
a1_dev_01 vm_x=vm-1
a1_dev_02 vm_x=vm-2
a1_dev_03 vm_x=vm-3
a2_jump_01 vm_x=vm-0

[dev_postgres]
a1_dev_01
a1_dev_02

[dev_ldap]
a1_dev_02
a1_dev_03

[dev:children]
dev_postgres
dev_ldap

[dev:vars]
env=dev

[jumphost]
a2_jump_01

[all:vars]
vm_domain=my.internal.domain.com
shell> cat hosts-627/2-constructed.yml 
plugin: constructed
strict: true
compose:
  ansible_host: vm_x ~ '.' ~ vm_domain

给予

shell> ansible-inventory -i hosts-627 --list --yaml
all:
  children:
    dev:
      children:
        dev_ldap:
          hosts:
            a1_dev_02:
              ansible_host: vm-2.my.internal.domain.com
              env: dev
              vm_domain: my.internal.domain.com
              vm_x: vm-2
            a1_dev_03:
              ansible_host: vm-3.my.internal.domain.com
              env: dev
              vm_domain: my.internal.domain.com
              vm_x: vm-3
        dev_postgres:
          hosts:
            a1_dev_01:
              ansible_host: vm-1.my.internal.domain.com
              env: dev
              vm_domain: my.internal.domain.com
              vm_x: vm-1
            a1_dev_02: {}
    jumphost:
      hosts:
        a2_jump_01:
          ansible_host: vm-0.my.internal.domain.com
          vm_domain: my.internal.domain.com
          vm_x: vm-0
    ungrouped: {}

下一个选项是将变量放入 group_vars。例如

shell> cat hosts-628/hosts
a1_dev_01 vm_x=vm-1
a1_dev_02 vm_x=vm-2
a1_dev_03 vm_x=vm-3
a2_jump_01 vm_x=vm-0

[dev_postgres]
a1_dev_01
a1_dev_02

[dev_ldap]
a1_dev_02
a1_dev_03

[dev:children]
dev_postgres
dev_ldap

[jumphost]
a2_jump_01
shell> cat group_vars/all.yml 
vm_domain: my.internal.domain.com
ansible_host: "{{ vm_x }}.{{ vm_domain }}"
shell> cat group_vars/dev.yml 
env: dev

给予

shell> ansible-inventory -i hosts-628 --list --yaml
all:
  children:
    dev:
      children:
        dev_ldap:
          hosts:
            a1_dev_02:
              ansible_host: '{{ vm_x }}.{{ vm_domain }}'
              env: dev
              vm_domain: my.internal.domain.com
              vm_x: vm-2
            a1_dev_03:
              ansible_host: '{{ vm_x }}.{{ vm_domain }}'
              env: dev
              vm_domain: my.internal.domain.com
              vm_x: vm-3
        dev_postgres:
          hosts:
            a1_dev_01:
              ansible_host: '{{ vm_x }}.{{ vm_domain }}'
              env: dev
              vm_domain: my.internal.domain.com
              vm_x: vm-1
            a1_dev_02: {}
    jumphost:
      hosts:
        a2_jump_01:
          ansible_host: '{{ vm_x }}.{{ vm_domain }}'
          vm_domain: my.internal.domain.com
          vm_x: vm-0
    ungrouped: {}

唯一的区别是表达式将按需计算。这意味着变量 vm_xvm_domain 将成为 precedence 的主题。例如剧本

shell> cat test-628.yml
- hosts: all
  gather_facts: false
  tasks:
    - debug:
        var: ansible_host

给出(删节)

ok: [a2_jump_01] => 
  ansible_host: vm-0.my.internal.domain.com
ok: [a1_dev_01] => 
  ansible_host: vm-1.my.internal.domain.com
ok: [a1_dev_02] => 
  ansible_host: vm-2.my.internal.domain.com
ok: [a1_dev_03] => 
  ansible_host: vm-3.my.internal.domain.com