【问题标题】:How to find a free VPC CIDR block with Ansible?如何使用 Ansible 找到免费的 VPC CIDR 块?
【发布时间】:2015-09-17 22:24:02
【问题描述】:

我在 AWS 中有一组现有的 VPC,每个都有自己的 CIDR 块:

vpc1:20.0.0.0/16 vpc2:20.10.0.0/16

现在,我正在尝试编写一个剧本,它会提取现有的 VPC 列表,然后找到一个可用的 CIDR(例如,在上面的示例中,下一个可用的 CIDR 将是 20.20.0.0/16,尽管我'我不太关心保持顺序)。

我知道这样做适用于两个列表:

- name: Loop over all possible CIDRs
    debug: msg="Found a free CIDR {{ item }}"
    with_items: all_potential_cidrs
    when: "\"{{ item }}\" not in {{ currently_used_cidrs }}"

但是,我获取现有 CIDR 列表的方式是:

- name: Get list of VPCs and their CIDR blocks
  command: aws ec2 describe-vpcs --output json
  register: cli_output

- name: Register variables
  set_fact:
  current_vpcs: "{{ cli_output.stdout | from_json }}"

该命令返回以下数据(JSON 格式):

{
    "Vpcs": [
        {
            "VpcId": "vpc-4aad0c23",
            "InstanceTenancy": "default",
            "Tags": [
                {
                    "Value": "vpc1",
                    "Key": "Name"
                }
            ],
            "State": "available",
            "DhcpOptionsId": "dopt-ff6b238f",
            "CidrBlock": "20.0.0.0/16",
            "IsDefault": false
        },
        {
            "VpcId": "vpc-d4101abc",
            "InstanceTenancy": "default",
            "Tags": [
                {
                    "Value": "vpc2",
                    "Key": "Name"
                }
            ],
            "State": "available",
            "DhcpOptionsId": "dopt-eaaab38c",
            "CidrBlock": "20.10.0.0/16",
            "IsDefault": false
        }
    ]
}

这允许获取所有 CIDR 块,如下所示:

- name: Print filtered VPCs and their subnets
  debug: msg="VPC ID {{ item.VpcId }}, VPC CIDR block {{ item.CidrBlock }}"
  with_items: current_vpcs.Vpcs

但是,由于“CidrBlock”是列表项的属性,我无法在需要列表的“when”语句中使用它:

when: "{{ item }}" not in {{ list_of_cidrs }}"

如何获取每个“Vpcs”项目的“CidrBlock”属性并将其转换为自己的列表,以便将其传递给“何时:...不在...”语句?

【问题讨论】:

    标签: python yaml ansible cidr vpc


    【解决方案1】:

    您可以使用 Jinja's map filter 将 VPC items 列表转换为仅包含 CIDR 块的列表。

    我不完全确定您要完成此剧本的目的,但这里有一个示例,可让您将“Vpcs”项目列表转换为每个 vpc 的 CidrBlock 的字符串列表项目。

    你可以看到它在:

    - name: Print just the CIDRS
      debug: msg='{{ current_vpcs.Vpcs|map(attribute="CidrBlock")|list }}'
    

    假设你设置了current_vpcs,上面的行输出

    TASK: [Print just the CIDRS] **************************************************
    ok: [localhost] => {
        "msg": "[u'20.0.0.0/16', u'20.10.0.0/16']"
     }
    

    完整的工作示例:

    ---
    - name: ok
      hosts: localhost
      gather_facts: no
    
      vars:
        all_available_cidrs:
          - "20.0.0.0/16"
          - "20.10.0.0/16"
          - "20.20.0.0/16"
    
      tasks:
    
        - name: Get list of VPCs and their CIDR blocks
          command: aws ec2 describe-vpcs --output json
          register: cli_output
    
        - name: Register variables
          set_fact:
            current_vpcs: "{{ cli_output.stdout | from_json }}"
    
        - name: Print VPCs and their subnets
          debug: msg="VPC ID {{ item.VpcId }}, VPC CIDR block {{ item.CidrBlock }}"
          with_items: current_vpcs.Vpcs
    
        - name: extract list_of_cidrs into fact
          set_fact: 
            list_of_cidrs: '{{ current_vpcs.Vpcs|map(attribute="CidrBlock")|list|to_json }}'
    
        - name: Print just the CIDRS
          debug: var=list_of_cidrs
    
        - name: Print available unused cidrs
          debug: msg="available unused VPC CIDR block {{ item }}"
          with_items: all_available_cidrs
          when: '"{{ item }}" not in {{ list_of_cidrs }}'
    

    current_vpcs.Vpcs 变成["20.0.0.0/16", "20.10.0.0/16"] 列表的行是:

    set_fact: 
      list_of_cidrs: '{{ current_vpcs.Vpcs|map(attribute="CidrBlock")|list|to_json }}'
    

    注意:必须使用|list|to_json 才能让Jinja 正确模板化in 语句。 map 返回一个生成器,其表示不能用作 Jinja in 语句的参数。可能有更清洁的方法可以做到这一点,但使用|list|to_json 是人们在This ticket 中找到的解决方案


    编辑:添加变量all_available_cidrs 使完整示例更接近原始问题

    【讨论】:

    • 太棒了!我不知道 Jinja 的“地图”或“列表”过滤器。非常感谢你,我已经绞尽脑汁想办法做到这一点了好几个小时。
    猜你喜欢
    • 2020-11-09
    • 1970-01-01
    • 1970-01-01
    • 2019-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-21
    相关资源
    最近更新 更多