3

对于从 ansible 中的寄存器正确选择数据,我真的很感激。以下代码几乎可以工作...... :)

我在这里创建了一个 AWS VPC,我在“vpc”中注册了信息。然后我指的是vpc。

  - name: Create VPC and Subnets
    ec2_vpc:
      state: present
      cidr_block: '{{ ip-range}}'
      resource_tags: { "Name": "{{ vpc_name }}" }
      region: '{{ region }}'
      subnets:
        - cidr: '{{ pub-subneta }}'
          az: '{{ region }}a'
          resource_tags: { "Name": "Public Subnet 1" }

        - cidr: '{{ pub-subnetb }}'
          az: '{{ region }}b'
          resource_tags: { "Name": "Public Subnet 2" }

        - cidr: '{{ priv-subnet1 }}'
          az: '{{ region }}a'
          resource_tags: { "Name": "Private Subnet 1" }

        - cidr: '{{ priv-subnet2 }}'
          az: '{{ region }}b'
          resource_tags: { "Name": "Private Subnet 2" }
      internet_gateway: True
    register: vpc

效果很好。它创建具有 4 个子网的 VPC。然后,我想在特定子网中启动一个 NAT 实例,我尝试通过指定子网来执行以下操作:

- name: Create NAT instance
  ec2:
    state: present
    key_name: '{{ ssh_key_name }}'
    instance_type: '{{ nat_instance_type }}'
    image: '{{ nat_ami }}'
    region: '{{ region }}'
    wait: yes
    instance_tags:
      Name: "natsrv01"
      Description: "NAT Server"
    assign_public_ip: yes
    source_dest_check: false
    vpc_subnet_id: '{{ vpc.subnets[0].id }}'

这是它无法按预期工作的地方。我假设寄存器将按照定义/创建的顺序包含信息,但事实并非如此。

使用调试我可以看到 4 个子网在寄存器中的顺序是随机的。例如,在一次尝试中,“公共子网 2”被 'vpc.subnets[0].id' 识别,而在另一次尝试中,“私有子网 2”是列表中的第一个。

有人可以建议我如何可靠地重复从注册表中选择“公共子网 1”吗?

vpc 寄存器的完整输出为:

 ok: [localhost] => {
 "vpc": {
     "changed": true,
     "invocation": {
         "module_args": "",
         "module_name": "ec2_vpc"
     },
     "subnets": [
         {
             "az": "eu-west-1b",
             "cidr": REDACTED,
             "id": "subnet-REDACTED",
             "resource_tags": {
                 "Name": "Private Subnet B"
             }
         },
         {
             "az": "eu-west-1c",
             "cidr": REDACTED,
             "id": "subnet-REDACTED",
             "resource_tags": {
                 "Name": "Private Subnet C"
             }
         },
         {
             "az": "eu-west-1a",
             "cidr": REDACTED,
             "id": "subnet-REDACTED",
             "resource_tags": {
                 "Name": "Public Subnet A"
             } 
         },
         {
             "az": "eu-west-1c",
             "cidr": REDACTED,
             "id": "subnet-REDACTED",
             "resource_tags": {
                 "Name": "Public Subnet C"
             }
         },
         {
             "az": "eu-west-1b",
             "cidr": REDACTED,
             "id": "subnet-REDACTED",
             "resource_tags": {
                 "Name": "Public Subnet B"
             }
         },
         {
             "az": "eu-west-1a",
             "cidr": REDACTED,
             "id": "subnet-REDACTED",
             "resource_tags": {
                 "Name": "Private Subnet A"
             }
         }
     ], 
     "vpc": {
         "cidr_block": "REDACTED",
         "dhcp_options_id": "dopt-53eb0f36",
         "id": "vpc-REDACTED",
         "region": "eu-west-1",
         "state": "pending"
     },
     "vpc_id": "vpc-REDACTED"
 }
}
4

2 回答 2

2

像这样的东西可能会起作用:

- name: Find the first public subnet
  set_fact: vpc_subnet_id="{{ item.id }}"
  when: item.resource_tags.Name == "Public Subnet 1"
  with_items: vpc.subnets
于 2015-04-16T15:43:12.557 回答
2

您还可以尝试编写子网过滤器,如下所示:

vpc_subnet_id: "{{ vpc.subnets | subnet_name_filter() }}"

用这个创建一个文件 /ansible_plugins/filter_plugins/core.py :

def subnet_name_filter(list):
  return [x for x in list if x.resource_tags.Name == "Public Subnet 1"]

class FilterModule(object):
  def filters(self):
    return {          
      'subnet_name_filter': subnet_name_filter
    }

编辑 ansible.cfg,并取消注释我们启用自定义 filter_plugins 的行。该路径可以是相对的,ansible 将查找相对于 ansible.cfg 所在位置的插件。例如,我的 ansible.cfg 和所有插件都签入了我的 git 存储库。

编辑:

如果您重构如下,您还可以删除自定义插件中的硬编码:

def subnet_name_filter(list, restagname):
  return [x for x in list if x.resource_tags.Name == restagname]

并使用

vpc_subnet_id: "{{ vpc.subnets | subnet_name_filter('Public Subnet 1') }}"
于 2015-04-16T17:08:59.053 回答