【问题标题】:How do I add routes to a VPC's default/main route table with Ansible ec2_vpc_route_table?如何使用 Ansible ec2_vpc_route_table 将路由添加到 VPC 的默认/主路由表?
【发布时间】:2016-12-13 21:00:28
【问题描述】:

我在使用 Ansible 和 ec2_vpc_route_table 模块的 NAT 场景中向新创建的 VPC 的默认路由表添加额外路由时遇到了真正的麻烦。我的剧本的相关摘录是......

创建 VPC

- name: Create Production VPC
  ec2_vpc:
    region: "{{ aws.region }}"
    aws_access_key: "{{ aws.access_key }}"
    aws_secret_key: "{{ aws.secret_key }}"
    state: present
    cidr_block: 10.0.0.0/16
    resource_tags: { "Name":"Production" }
    internet_gateway: yes
    dns_hostnames: yes
    dns_support: yes
    subnets: 
      - cidr: 10.0.10.0/24
        resource_tags: { "Name":"A - NAT" }
      - cidr: 10.0.20.0/24
        resource_tags: { "Name":"B - Public" }
      - cidr: 10.0.30.0/24
        resource_tags: { "Name":"C - Private" }
    wait: yes
  register: prod_vpc

收集事实并添加新路线

- name: Gather default Route Table facts
  ec2_vpc_route_table_facts:
    region: "{{ aws.region }}"
    filters:
      vpc-id: "{{ prod_vpc.vpc.id }}"
  register: vpc_default_route

- name: Add NAT routes
  ec2_vpc_route_table:
    aws_access_key: "{{ aws.access_key }}"
    aws_secret_key: "{{ aws.secret_key }}"
    vpc_id: "{{ prod_vpc.vpc.id }}"
    region: "{{ aws.region }}"
    route_table_id: "{{ vpc_default_route.route_tables[0].id }}"
    lookup: id
    tags:
      Name: NAT
    subnets: 
      - '10.0.10.0/24'
    routes:
      - dest: 0.0.0.0/0
        gateway_id: igw

首先,我尝试在ec2_vpc 任务中包含路由的创建,但实际上最终创建了第二个路由表,而不是在默认表中包含路由。

首先,为什么要创建第二个表而不是添加默认路由?

因为在 vpc 创建中包含它不起作用,所以我回到上面,它只是识别默认值,或 main 路由表。现在的问题是,当我尝试使用ec2_vpc_route_table 添加 NAT 路由时,Ansible 失败并出现以下错误...

fatal: [localhost]: FAILED! => {"changed": false, "failed": true, "msg": "Unable to associate subnets for route table RouteTable:rtb-..., error: EC2ResponseError: 400 Bad Request\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Response><Errors><Error><Code>InvalidParameterValue</Code><Message>cannot disassociate the main route table association rtbassoc-...</Message></Error></Errors><RequestID>...</RequestID></Response>"}

这个错误听起来像是,尽管我明确提供route_table_idlookup: id,它没有更新现有表,但它基本上是重新创建它,试图删除原始表(这是main路由表)在处理中。

如何将其他路由附加到现有的 main 路由表?

到目前为止,我能够使用的唯一解决方法是通过 command: ... 方法调用 EC2 CLI,但这显然并不理想。

我们在Ansible 2.3.0 (devel 14a2757116)

任何帮助将不胜感激!

【问题讨论】:

  • 源码中有一些notes说明boto还不能设置主表。不确定它是否仍然是一个有效的声明。
  • @KonstantinSuvorov 感谢您指出这一点,这说明了一点。麻烦的是,我并不是真的想删除它,我想追加它,但似乎行为是删除和重建。

标签: amazon-ec2 routing ansible ansible-playbook ansible-2.x


【解决方案1】:

我已经设法通过查找主路由表来更新它,然后使用route_table_id 对其进行修改。

- name: Lookup VPC facts
  ec2_vpc_net_facts:
    region: "{{ region }}"
    filters:
      "tag:Name": "{{ vpc_name }}"
  register: vpc_group

- name: Create vgw 
  ec2_vpc_vgw:
    region: "{{ region }}"
    vpc_id: "{{ vpc_group.vpcs[0].id }}"
    name: "{{ vpc_name }}"
    type: ipsec.1
    state: present
    validate_certs: no
  register: vpc_vgw

- name: Create igw 
  ec2_vpc_igw:
    region: "{{ region }}"
    vpc_id: "{{ vpc_group.vpcs[0].id }}"
    state: present
    validate_certs: no
  register: igw 

- name: Lookup route tables
  ec2_vpc_route_table_facts:
    region: "{{ region }}"
    filters:
      vpc-id: "{{ vpc_group.vpcs[0].id }}"
  register: vpc_route_tables

- name: Setup route tables
  ec2_vpc_route_table:
    region: "{{ region }}"
    vpc_id: "{{ vpc_group.vpcs[0].id }}"
    lookup: id
    purge_subnets: false
    route_table_id: "{{ vpc_route_tables.route_tables[0].id }}"
    subnets: "{{ subnet_ids }}"
    routes:
      - dest: 10.0.0.0/8
        gateway_id: "{{ vpc_vgw.vgw.id }}"
      - dest: 0.0.0.0/0
        gateway_id: "{{ igw.gateway_id }}"

注意:您需要禁用清除子网,否则当 ansible 尝试从主路由表中删除默认子网关联时,您会收到错误消息。

【讨论】:

  • 您已经查找了路由表,然后调用了找到的第一个路由表,使用:route_table_id: "{{ vpc_route_tables.route_tables[0].id }}"。但是,如果这返回多个路由表,那么您实际上是在选择结果中恰好是第一个的随机路由表。我试图自己弄清楚如何指定我想要 main 路由表。在查找路由表的游戏中,我尝试设置一个额外的过滤器,如下所示:"association.main": true,但它不起作用。它在命令行上用作过滤器,但在 Ansible 模块中不起作用。嗯。
  • @ToddWalton 如果我像这样引用true "association.main": "true",它似乎可以工作
【解决方案2】:

来自http://docs.ansible.com/ansible/ec2_vpc_route_table_module.html#options

通过标签或路由表 ID 查找路由表。非唯一标签查找将失败。 如果没有指定标签,则不查找现有路由表,将创建一个新的路由表。要更改路由表的标签或删除路由表,必须按 id 查找.

尝试使用lookup: tag 而不是lookup: id。 应该可以的。

【讨论】:

    猜你喜欢
    • 2019-01-21
    • 2014-04-09
    • 2019-07-21
    • 2020-08-31
    • 1970-01-01
    • 1970-01-01
    • 2022-12-13
    • 1970-01-01
    • 2016-09-10
    相关资源
    最近更新 更多