如何根据 set_facts 将多个 ansible 条件合并为一个 [英] How to Club multiple ansible condition into one based on the set_facts

查看:20
本文介绍了如何根据 set_facts 将多个 ansible 条件合并为一个的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在浏览 SO post ansible 配方,我在使用 set_fact 和不同的条件检查时很有趣.但是,我根据我的方法在帖子中回答了但是,我仍然看到可以改进将多个条件用于类似任务,例如确定 location resource group 和 <代码>vnet.

While going through one of the SO post for ansible recipe, I got it interesting while using set_fact with different conditional checks. However, I answered on the post based on my approach However, I still see there can be an improvement to club multiple conditions for similar task like determine the location resource group and vnet.

下面是playbook和变量文件azure_vars.yml

---
- name: create azure vm
  hosts: localhost
  connection: local
  tasks:
   -  include_vars: azure_vars.yml

   - set_fact:
      host: "{{ azure_vm_name.split('.') }}"

   - set_fact:
       domain: "{{ host.1 }}.{{ host.2 }}"

   - name: Domain
     debug:
      msg: "{{ domain }}"

   - set_fact:
      location: "{{ azure_location[0] }}"
     when: 'domain == azure_domain[0]'

   - set_fact:
      location: "{{ azure_location[1] }}"
     when: 'domain == azure_domain[1]'

   - set_fact:
      location: "{{ azure_location[2] }}"
     when: 'domain == azure_domain[2]'

   - name: Location
     debug:
      msg: "{{ location }}"

   - set_fact:
      res_group: "{{ azure_res_group[0] }}"
     when: 'domain == azure_domain[0]'

   - set_fact:
      res_group: "{{ azure_res_group[1] }}"
     when: 'domain == azure_domain[1]'

   - set_fact:
      res_group: "{{ azure_res_group[2] }}"
     when: 'domain == azure_domain[2]'

   - name: Resource Group
     debug:
      msg: "{{ res_group }}"

   - set_fact:
      vnet: "{{ azure_nprod_vnet }}"
     when: 'domain == azure_domain[0]'

   - set_fact:
      vnet: "{{ azure_prod03_vnet }}"
     when: 'domain == azure_domain[2]'

   - set_fact:
      vnet: "{{ azure_prod02_vnet }}"
     when: 'domain == azure_domain[1]'

   - name: Vnet
     debug:
      msg: "{{ vnet }}"

变量文件

此文件包含将成为 playbook 的一部分并在任务部分下作为 include_vars 导入的所有变量.

Variable Files

This file contains all the variable which will be a part of playbook and imported as include_vars under task section.

$ cat azure_vars.yml
---
azure_nprod_vnet: "/subscriptions/XXXXXXXX-XXX-XXXX-XXXX-XXXXXXXXXXXX/resourceGroups/rg001/providers/Microsoft.Network/virtualNetworks/vnet"
azure_prod02_vnet: "/subscriptions/XXXXXXXX-XXX-XXXX-XXXX-XXXXXXXXXXXX/resourceGroups/rg003/providers/Microsoft.Network/virtualNetworks/vnet"
azure_prod03_vnet: "/subscriptions/XXXXXXXX-XXX-XXXX-XXXX-XXXXXXXXXXXX/resourceGroups/rg002/providers/Microsoft.Network/virtualNetworks/vnet"

    
# Azure domain
azure_domains:
  - us-sea01
  - us-azrc2
  - eu-azrc1


# Resource group
azure_res_group:
  - rg001
  - rg002
  - rg003

# Azure locations
azure_location:
  - westus2
  - southcentralus
  - westeurope
...

预计将低于三合一条件:

   - set_fact:
      location: "{{ azure_location[0] }}"
     when: 'domain == azure_domain[0]'

   - set_fact:
      location: "{{ azure_location[1] }}"
     when: 'domain == azure_domain[1]'

   - set_fact:
      location: "{{ azure_location[2] }}"
     when: 'domain == azure_domain[2]'

可能是这样的:

   - set_fact:
      location:
        - azure_location[0]
        - azure_location[1]
        - azure_location[2]
     when:
       - 'domain == azure_domain[0]
       - 'domain == azure_domain[1]
       - 'domain == azure_domain[2]

推荐答案

您可以使用 loopzip 过滤器,或以较旧的方式,带有 with_together — 不再推荐,如果您想以后使用 —证明你的剧本.

You can solve this using a loop and zip filter, or in the older fashion way, with a with_together — not recommended anymore, if you want to future-proof your playbooks.

给定剧本:

- hosts: all
  vars:
    azure_vm_name: foo.bar.us-sea01.whatever.example.org

  tasks:
    - include_vars: azure_vars.yml

    - set_fact:
        host: "{{ azure_vm_name.split('.') }}"

    - set_fact:
        domain: "{{ host.2 }}"

    - name: Domain
      debug:
        msg: "{{ domain }}"

    - set_fact:
        location: "{{ item.1 }}"
      loop: "{{ azure_domains | zip(azure_location) | list }}"
      when: 'domain == item.0'

    - name: Location
      debug:
       msg: "{{ location }}"

和变量文件azure_vars.yml:

azure_domains:
  - us-sea01
  - us-azrc2
  - eu-azrc1

azure_location:
  - westus2
  - southcentralus
  - westeurope

总结如下:

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

TASK [Gathering Facts] *******************************************************************************************
ok: [localhost]

TASK [include_vars] **********************************************************************************************
ok: [localhost]

TASK [set_fact] **************************************************************************************************
ok: [localhost]

TASK [set_fact] **************************************************************************************************
ok: [localhost]

TASK [Domain] ****************************************************************************************************
ok: [localhost] => {
    "msg": "us-sea01"
}

TASK [set_fact] **************************************************************************************************
ok: [localhost] => (item=['us-sea01', 'westus2'])
skipping: [localhost] => (item=['us-azrc2', 'southcentralus']) 
skipping: [localhost] => (item=['eu-azrc1', 'westeurope']) 

TASK [Location] **************************************************************************************************
ok: [localhost] => {
    "msg": "westus2"
}

PLAY RECAP *******************************************************************************************************
localhost                  : ok=7    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   


这表示还有另一种可能性,即使用 Python 的 Ansible 能力.您可以使用 index() 列表的方法,用于定位与 azure_domains 中的 domain 相同位置的 azure_location 的元素.
例如如果domain 位于azure_domains2 位置,您将在 中获得位置2 的元素>azure_location.


This said there is another possibility, using Python's capacities of Ansible. You could use the index() method of a list to target the element of azure_location being at the same position as domain in azure_domains.
e.g. if the domain is at position 2 of azure_domains, you'll get the element of position 2 in azure_location.

给定剧本:

- hosts: all
  vars:
    azure_vm_name: foo.bar.us-sea01.whatever.example.org

  tasks:
    - include_vars: azure_vars.yml

    - set_fact:
        host: "{{ azure_vm_name.split('.') }}"

    - set_fact:
        domain: "{{ host.2 }}"

    - name: Domain
      debug:
        msg: "{{ domain }}"

    - set_fact:
        location: "{{ azure_location[azure_domains.index(domain)] }}"

    - name: Location
      debug:
       msg: "{{ location }}"

和相同的变量文件 azure_vars.yml,这产生了回顾:

And the same variable file azure_vars.yml, this yields the recap:

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

TASK [Gathering Facts] ******************************************************************************************************
ok: [localhost]

TASK [include_vars] *********************************************************************************************************
ok: [localhost]

TASK [set_fact] *************************************************************************************************************
ok: [localhost]

TASK [set_fact] *************************************************************************************************************
ok: [localhost]

TASK [Domain] ***************************************************************************************************************
ok: [localhost] => {
    "msg": "us-sea01"
}

TASK [set_fact] *************************************************************************************************************
ok: [localhost]

TASK [Location] *************************************************************************************************************
ok: [localhost] => {
    "msg": "westus2"
}

PLAY RECAP ******************************************************************************************************************
localhost                  : ok=7    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

没有使用循环,所以更容易回顾.

Which is not using a loop, so makes an easier recap.

这篇关于如何根据 set_facts 将多个 ansible 条件合并为一个的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆