如何在循环中选择某些字段而不需要大量“跳过”行

问题描述 投票:0回答:1

我尝试在 Ansible 中创建一个数组,其中包含我的账户中启用的支持 FSx for NetApp ONTAP (FSxN) 的所有 AWS 区域。我知道我可以使用以下命令来获取我的帐户上启用的区域列表:

    - name: Get all the opted in regions.
      amazon.aws.aws_region_info:
      register: region_info

    - name: Just get region names
      set_fact:
        opted_in_regions: "{{ [item.region_name] + opted_in_regions }}"
      loop: "{{ region_info.regions }}"

但有时,通常是当新区域上线时,某些区域不支持 FSxN。我发现了解哪些区域支持特定服务的唯一方法是从

https://api.regional-table.region-services.aws.a2z.com/index.json
下载价格指南,并查找将“Amazon FSx for NetApp ONTAP”作为“aws:serviceName”的区域。该文件的格式是:

{
  "prices": [
    {
      "attributes": {
        "aws:region": "ap-east-1",
        "aws:serviceName": "Amazon Translate",
        "aws:serviceUrl": "https://aws.amazon.com/translate/"
      },
      "id": "translate:ap-east-1"
    },
    {
      "attributes": {
        "aws:region": "ap-northeast-1",
        "aws:serviceName": "Amazon Translate",
        "aws:serviceUrl": "https://aws.amazon.com/translate/"
      },
      "id": "translate:ap-northeast-1"
    },

所以,我所做的是使用文件的内容创建变量:

    - name: Get the capabilities of all regions.
      set_fact:
        regions_capabilities: "{{lookup('ansible.builtin.url', 'https://api.regional-table.region-services.aws.a2z.com/index.json', split_lines=false)}}"

然后下一个“任务”是循环遍历所有值并将 aws:serviceName 字段中具有特定字符串的值添加到另一个数组中。

    - name: Get the intersection of opted in regions and regions that support FSxN.
      when: item['attributes']['aws:serviceName'] == "Amazon FSx for NetApp ONTAP" and item['attributes']['aws:region'] in opted_in_regions
      set_fact:
        fsxnRegions: "{{ [item['attributes']['aws:region']] + fsxnRegions }}"
      loop: "{{ regions_capabilities.prices }}"

虽然有效,但“when:”语句会在输出中生成大量(数千)“skipping...”行。而且,速度慢得令人痛苦。

那么,问题是,有没有更好的方法来创建支持 FSxN 的区域数组?如果不是,我怎样才能抑制“跳过”消息,但仅限于此任务?

这是整个 Ansible 剧本:

# Title: generate report
---
- hosts: localhost
  collections:
    - amazon.aws
  gather_facts: false
  name: Playbook to generate a report on all the FSxNs
  vars:
    fsxnRegions: []
    opted_in_regions: []

  tasks:
    - name: Get all the opted in regions.
      amazon.aws.aws_region_info:
      register: region_info

    - name: Just get region names
      set_fact:
        opted_in_regions: "{{ [item.region_name] + opted_in_regions }}"
      loop: "{{ region_info.regions }}"

    - name: Get the capabilities of all regions.
      set_fact:
        regions_capabilities: "{{lookup('ansible.builtin.url', 'https://api.regional-table.region-services.aws.a2z.com/index.json', split_lines=false)}}"

    - name: Get the intersection of opted in regions and regions that support FSxN.
      when: item['attributes']['aws:serviceName'] == "Amazon FSx for NetApp ONTAP" and item['attributes']['aws:region'] in opted_in_regions
      set_fact:
        fsxnRegions: "{{ [item['attributes']['aws:region']] + fsxnRegions }}"
      loop: "{{ regions_capabilities.prices }}"

    - name: Output
      debug:
        msg: "fsxnRegions={{ fsxnRegions }}"
ansible
1个回答
0
投票

如果我理解正确,你可以尝试使用 selectattr 而不使用循环

# Title: generate report
---
- hosts: localhost
  collections:
    - amazon.aws
  gather_facts: false
  name: Playbook to generate a report on all the FSxNs
  vars:
    fsxnRegions: []
    opted_in_regions: []

  tasks:
    - name: Get all the opted-in regions
      amazon.aws.aws_region_info:
      register: region_info

    - name: Get region names
      set_fact:
        opted_in_regions: "{{ region_info.regions | map(attribute='region_name') | list }}"

    - name: Get the capabilities of all regions
      set_fact:
        regions_capabilities: "{{ lookup('ansible.builtin.url', 'https://api.regional-table.region-services.aws.a2z.com/index.json', split_lines=false) }}"

    - name: Filter regions that support FSxN and are opted-in
      set_fact:
        fsxnRegions: >-
          {{
            regions_capabilities.prices
            | selectattr("attributes.aws:serviceName", "equalto", "Amazon FSx for NetApp ONTAP")
            | selectattr("attributes.aws:region", "in", opted_in_regions)
            | map(attribute="attributes.aws:region")
            | list
          }}

    - name: Output the FSxN regions
      debug:
        msg: "fsxnRegions={{ fsxnRegions }}"
© www.soinside.com 2019 - 2024. All rights reserved.