选择基于传递的变量版本的三个环境的多个 hosts.ini 中的清单文件。

huangapple go评论68阅读模式
英文:

Ansible : Select inventory file out of multiple hosts.ini for three environments based on the version passed as a variable

问题

我有一个任务,在这个任务中,我需要从放置在inventories/目录下不同文件夹中的多个清单文件中选择目标环境/主机。选择是基于作为变量传递的版本。

inventories/
           preprod/
                  group_vars/
                  hosts.ini
                  ...
           systest/
                  group_vars/
                  hosts.ini
                  ...
           uat/
                  group_vars/
                  hosts.ini
                  ...

因此,如果版本变量是1.x.x,则应选择preprod下的hosts.ini;如果是2.x.x,则应选择systest下的hosts.ini;如果是3.x.x,则应选择uat下的hosts.ini。

---
- name: 根据传递的版本从多个清单中选择主机
  hosts: all
  vars:
    version: '1.0'
  tasks:
    - name: 从第一个清单获取主机
      set_fact:
        hosts_1: "{{ groups['inventory_1'] | selectattr('version', 'equalto', version) | map(attribute='hostname') | list }}"
    - name: 从第二个清单获取主机
      set_fact:
        hosts_2: "{{ groups['inventory_2'] | selectattr('version', 'equalto', version) | map(attribute='hostname') | list }}"
    - name: 合并来自两个清单的主机
      set_fact:
        hosts: "{{ hosts_1 + hosts_2 }}"
    - name: 使用主机运行任务
      debug:
        msg: "{{ item }}"
      loop: "{{ hosts }}"
英文:

I have a task , in which I need to select the target environment/hosts amongst the multiple inventory files placed in different folders under inventories/ directory. The selection is based on the version passed as a variable.

inventories/
           preprod/
                  group_vars/
                  hosts.ini
                  ...
           systest/
                  group_vars/
                  hosts.ini
                  ...
           uat/
                  group_vars/
                  hosts.ini
                  ...

So if the version varaiable is 1.x.x then the hosts.ini under preprod should be selected, if its 2.x.x then the hosts.ini under systest should be selected and if its 3.x.x the hosts.ini under uat should be selected.

---
- name: Select hosts from multiple inventories based on version passed as a variable
  hosts: all
  vars:
    version: '1.0'
  tasks:
  - name: Get hosts from first inventory
    set_fact:
      hosts_1: "{{ groups['inventory_1'] | selectattr('version', 'equalto', version) | map(attribute='hostname') | list }}"
  - name: Get hosts from second inventory
    set_fact:
      hosts_2: "{{ groups['inventory_2'] | selectattr('version', 'equalto', version) | map(attribute='hostname') | list }}"
  - name: Merge hosts from both inventories
    set_fact:
      hosts: "{{ hosts_1 + hosts_2 }}"
  - name: Run tasks with hosts
    debug:
      msg: "{{ item }}"
    loop: "{{ hosts }}"

答案1

得分: 2

短回答:在第一个任务中复制清单文件,refresh_inventory,并在第二个任务中使用。不幸的是,这不会从目录中刷新 group_vars。作为解决方法,将 group_vars 放入清单文件中。

详细信息:给定用于测试的项目

shell> tree .
.
├── ansible.cfg
├── hosts.env
├── inventory
│   ├── preprod
│   │   └── hosts.ini
│   ├── systest
│   │   └── hosts.ini
│   └── uat
│       └── hosts.ini
└── pb.yml

4 directories, 6 files

group_vars 放入清单文件

shell> cat inventory/preprod/hosts.ini 
[all]
preprod1
preprod2
preprod3

[all:vars]
env_gv=preprod
shell> cat inventory/systest/hosts.ini 
systest1
systest2
systest3

[all:vars]
env_gv=systest
shell> cat inventory/uat/hosts.ini 
[all]
uat1
uat2
uat3

[all:vars]
env_gv=uat

playbook

shell> cat pb.yml
- hosts: localhost
  vars:
    envs:
      1: preprod
      2: systest
      3: uat
    env: "{{ envs[version.split('.').0|int] }}"
  tasks:
    - debug:
        msg: "Use environment: {{ env }}"
    - copy:
        src: "{{ playbook_dir }}/inventory/{{ env }}/hosts.ini"
        dest: "{{ playbook_dir }}/hosts.env"
    - meta: refresh_inventory

- hosts: all
  tasks:
    - block:
        - debug:
            var: ansible_play_hosts_all
        - debug:
            var: env_gv
      run_once: true

给出

<sup>

version=1.0 在环境 preprod 中运作

shell&gt; ansible-playbook -i hosts.env -e version=1.0 pb.yml

PLAY [localhost] ****************************************************************************************

TASK [debug] ********************************************************************************************
ok: [localhost] =&gt; 
  msg: &#39;Use environment: preprod&#39;

TASK 点击复制 *********************************************************************************************
changed: [localhost]

TASK [meta] *********************************************************************************************

PLAY [all] **********************************************************************************************

TASK [debug] ********************************************************************************************
ok: [preprod1] =&gt; 
  ansible_play_hosts_all:
  - preprod1
  - preprod2
  - preprod3

TASK [debug] ********************************************************************************************
ok: [preprod1] =&gt; 
  env_gv: preprod

PLAY RECAP **********************************************************************************************
localhost: ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
preprod1: ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

version=2.0 在环境 systest 中运作

shell&gt; ansible-playbook -i hosts.env -e version=2.0 pb.yml

PLAY [localhost] ****************************************************************************************

任务 [debug] ********************************************************************************************
ok: [localhost] =&gt; 
  msg: &#39;Use environment: systest&#39;

任务 点击复制 *********************************************************************************************
changed: [localhost]

任务 [meta] *********************************************************************************************

PLAY [all] **********************************************************************************************

任务 [debug] ********************************************************************************************
ok: [systest1] =&gt; 
  ansible_play_hosts_all:
  - systest1
  - systest2
  - systest3

任务 [debug] ********************************************************************************************
ok: [systest1] =&gt; 
  env_gv: systest

PLAY RECAP **********************************************************************************************
localhost: ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
systest1: ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

version=3.0 在环境 uat 中运作

shell&gt; ansible-playbook -i hosts.env -e version=3.0 pb.yml

PLAY [localhost] ****************************************************************************************

任务 [debug] ********************************************************************************************
ok: [localhost] =&gt; 
  msg: &#39;Use environment: uat&#39;

任务 点击复制 *********************************************************************************************
changed: [localhost]

任务 [meta] *********************************************************************************************

PLAY [all] **********************************************************************************************

任务 [debug] ********************************************************************************************
ok: [uat1] =&gt; 
  ansible_play_hosts_all:
  - uat1
  - uat2
  - uat3

任务 [debug] ********************************************************************************************
ok: [uat1] =&gt; 
  env_gv: uat

PLAY RECAP **********************************************************************************************
localhost: ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
uat1: ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

<hr>

示例。 group_vars 的优先级。YAML 格式。

shell&gt; tree .
.
├── ansible.cfg
├── group_vars
│&#160;&#160; └── all.yml
├── hosts
├── inventories
│&#160;&#160; ├── preprod
│&#160;&#160; │&#160;&#160; └── hosts
│&#160;&#160; ├── systest
│&#160;&#160; │&#160;&#160; └── hosts
│&#160;&#160; └── uat
│&#160;&#160;     └── hosts
├── inventory
│&#160;&#160; ├── group_vars
│&#160;&#160; │&#160;&#160; └── all.yml
│&#160;&#160; └── hosts
└── pb.yml

7 directories, 9 files
shell&gt; cat group_vars/all.yml 
env_gv3: playbook group_vars/all
shell&gt; cat inventory/group_vars/all.yml 


<details>
<summary>英文:</summary>

Short answer: Copy the inventory file in the first play, [*refresh_inventory*](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/meta_module.html#ansible-builtin-meta-module-execute-ansible-actions), and use it in the second play. Unfortunately, this does not refresh *group_vars* from the directories. As a workaround put the *group_vars* into the inventory files.

Details: Given the project for testing

```bash
shell&gt; tree .
.
├── ansible.cfg
├── hosts.env
├── inventory
│&#160;&#160; ├── preprod
│&#160;&#160; │&#160;&#160; └── hosts.ini
│&#160;&#160; ├── systest
│&#160;&#160; │&#160;&#160; └── hosts.ini
│&#160;&#160; └── uat
│&#160;&#160;     └── hosts.ini
└── pb.yml

4 directories, 6 files

Put the group_vars into the inventory files

shell&gt; cat inventory/preprod/hosts.ini 
[all]
preprod1
preprod2
preprod3

[all:vars]
env_gv=preprod
shell&gt; cat inventory/systest/hosts.ini 
systest1
systest2
systest3

[all:vars]
env_gv=systest
shell&gt; cat inventory/uat/hosts.ini 
[all]
uat1
uat2
uat3

[all:vars]
env_gv=uat

The playbook

shell&gt; cat pb.yml
- hosts: localhost
  vars:
    envs:
      1: preprod
      2: systest
      3: uat
    env: &quot;{{ envs[version.split(&#39;.&#39;).0|int] }}&quot;
  tasks:
    - debug:
        msg: &quot;Use environment: {{ env }}&quot;
    - copy:
        src: &quot;{{ playbook_dir }}/inventory/{{ env }}/hosts.ini&quot;
        dest: &quot;{{ playbook_dir }}/hosts.env&quot;
    - meta: refresh_inventory

- hosts: all
  tasks:
    - block:
        - debug:
            var: ansible_play_hosts_all
        - debug:
            var: env_gv
      run_once: true

gives

<sup>

version=1.0 works in the environment preprod

shell&gt; ansible-playbook -i hosts.env -e version=1.0 pb.yml

PLAY [localhost] ****************************************************************************************

TASK [debug] ********************************************************************************************
ok: [localhost] =&gt; 
  msg: &#39;Use environment: preprod&#39;

TASK 点击复制 *********************************************************************************************
changed: [localhost]

TASK [meta] *********************************************************************************************

PLAY [all] **********************************************************************************************

TASK [debug] ********************************************************************************************
ok: [preprod1] =&gt; 
  ansible_play_hosts_all:
  - preprod1
  - preprod2
  - preprod3

TASK [debug] ********************************************************************************************
ok: [preprod1] =&gt; 
  env_gv: preprod

PLAY RECAP **********************************************************************************************
localhost: ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
preprod1: ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

version=2.0 works in the environment systest

shell&gt; ansible-playbook -i hosts.env -e version=2.0 pb.yml

PLAY [localhost] ****************************************************************************************

TASK [debug] ********************************************************************************************
ok: [localhost] =&gt; 
  msg: &#39;Use environment: systest&#39;

TASK 点击复制 *********************************************************************************************
changed: [localhost]

TASK [meta] *********************************************************************************************

PLAY [all] **********************************************************************************************

TASK [debug] ********************************************************************************************
ok: [systest1] =&gt; 
  ansible_play_hosts_all:
  - systest1
  - systest2
  - systest3

TASK [debug] ********************************************************************************************
ok: [systest1] =&gt; 
  env_gv: systest

PLAY RECAP **********************************************************************************************
localhost: ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
systest1: ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

version=3.0 works in the environment uat

shell&gt; ansible-playbook -i hosts.env -e version=3.0 pb.yml

PLAY [localhost] ****************************************************************************************

TASK [debug] ********************************************************************************************
ok: [localhost] =&gt; 
  msg: &#39;Use environment: uat&#39;

TASK 点击复制 *********************************************************************************************
changed: [localhost]

TASK [meta] *********************************************************************************************

PLAY [all] **********************************************************************************************

TASK [debug] ********************************************************************************************
ok: [uat1] =&gt; 
  ansible_play_hosts_all:
  - uat1
  - uat2
  - uat3

TASK [debug] ********************************************************************************************
ok: [uat1] =&gt; 
  env_gv: uat

PLAY RECAP **********************************************************************************************
localhost: ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
uat1: ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

<hr>

Example. Precedence of group_vars. YAML format.

shell&gt; tree .
.
├── ansible.cfg
├── group_vars
│&#160;&#160; └── all.yml
├── hosts
├── inventories
│&#160;&#160; ├── preprod
│&#160;&#160; │&#160;&#160; └── hosts
│&#160;&#160; ├── systest
│&#160;&#160; │&#160;&#160; └── hosts
│&#160;&#160; └── uat
│&#160;&#160;     └── hosts
├── inventory
│&#160;&#160; ├── group_vars
│&#160;&#160; │&#160;&#160; └── all.yml
│&#160;&#160; └── hosts
└── pb.yml

7 directories, 9 files
shell&gt; cat group_vars/all.yml 
env_gv3: playbook group_vars/all
shell&gt; cat inventory/group_vars/all.yml 
env_gv2: inventory group_vars/all
shell&gt; cat inventories/preprod/hosts 
all:
  hosts:
    preprod1:
    preprod2:
    preprod3:
  vars:
    env_gv1: preprod1 inventory file group_vars
    env_gv2: preprod2 inventory file group_vars
    env_gv3: preprod3 inventory file group_vars
shell&gt; cat inventories/systest/hosts 
all:
  hosts:
    systest1:
    systest2:
    systest3:
  vars:
    env_gv1: systest1 inventory file group_vars
    env_gv2: systest2 inventory file group_vars
    env_gv3: systest3 inventory file group_vars
shell&gt; cat inventories/uat/hosts 
all:
  hosts:
    uat1:
    uat2:
    uat3:
  vars:
    env_gv1: uat1 inventory file group_vars
    env_gv2: uat2 inventory file group_vars
    env_gv3: uat3 inventory file group_vars
shell&gt; cat pb.yml 
- hosts: localhost
  vars:
    envs:
      1: preprod
      2: systest
      3: uat
    env: &quot;{{ envs[version.split(&#39;.&#39;).0|int] }}&quot;
  tasks:
    - debug:
        msg: &quot;Use environment: {{ env }}&quot;
    - copy:
        src: &quot;{{ playbook_dir }}/inventories/{{ env }}/hosts&quot;
        dest: &quot;{{ playbook_dir }}/inventory/hosts&quot;
    - meta: refresh_inventory

- hosts: all
  tasks:
    - block:
        - debug:
            var: ansible_play_hosts_all
        - debug:
            msg: |
              env_gv1: {{ env_gv1 }}
              env_gv2: {{ env_gv2 }}
              env_gv3: {{ env_gv3 }}              
      run_once: true
shell&gt; ansible-playbook -i inventory/hosts -e version=2.0 pb.yml

shows that variable precedence:

  1. inventory file or script group vars
  2. inventory group_vars/all
  3. playbook group_vars/all

works as expected

PLAY [localhost] ****************************************************************************************

TASK [debug] ********************************************************************************************
ok: [localhost] =&gt; 
  msg: &#39;Use environment: systest&#39;

TASK 点击复制 *********************************************************************************************
changed: [localhost]

TASK [meta] *********************************************************************************************

PLAY [all] **********************************************************************************************

TASK [debug] ********************************************************************************************
ok: [systest1] =&gt; 
  ansible_play_hosts_all:
  - systest1
  - systest2
  - systest3

TASK [debug] ********************************************************************************************
ok: [systest1] =&gt; 
  msg: |-
    env_gv1: systest1 inventory file group_vars
    env_gv2: inventory group_vars/all
    env_gv3: playbook group_vars/all    

PLAY RECAP **********************************************************************************************
localhost: ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
systest1: ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

</sup>

huangapple
  • 本文由 发表于 2023年2月10日 04:51:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/75404307.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定