AWS ec2_vpc_net: Enable ipv6 CIDR assignment (#60983)

* AWS ec2_vpc_net: Enable ipv6 CIDR assignment

Enable IPv6 CIDRs in ec2_vpc_net, and fix ec2_vpc_subnet tests that
were depending on the aws cli for CIDR assignment.

Related to: #27800
This commit is contained in:
Jill R 2019-09-10 16:25:36 -07:00 committed by Sloane Hertel
parent 983f0ad5a0
commit 414d844ed2
4 changed files with 77 additions and 31 deletions

View file

@ -0,0 +1,2 @@
minor_changes:
- ec2_vpc_net - Enable IPv6 CIDR assignment

View file

@ -31,6 +31,13 @@ options:
- The primary CIDR of the VPC. After 2.5 a list of CIDRs can be provided. The first in the list will be used as the primary CIDR - The primary CIDR of the VPC. After 2.5 a list of CIDRs can be provided. The first in the list will be used as the primary CIDR
and is used in conjunction with the C(name) to ensure idempotence. and is used in conjunction with the C(name) to ensure idempotence.
required: yes required: yes
ipv6_cidr:
description:
- Request an Amazon-provided IPv6 CIDR block with /56 prefix length. You cannot specify the range of IPv6 addresses,
or the size of the CIDR block.
default: False
type: bool
version_added: '2.10'
purge_cidrs: purge_cidrs:
description: description:
- Remove CIDRs that are associated with the VPC and are not specified in C(cidr_block). - Remove CIDRs that are associated with the VPC and are not specified in C(cidr_block).
@ -91,6 +98,14 @@ EXAMPLES = '''
module: ec2_vpc_net module: ec2_vpc_net
this: works this: works
tenancy: dedicated tenancy: dedicated
- name: create a VPC with dedicated tenancy and request an IPv6 CIDR
ec2_vpc_net:
name: Module_dev2
cidr_block: 10.10.0.0/16
ipv6_cidr: True
region: us-east-1
tenancy: dedicated
''' '''
RETURN = ''' RETURN = '''
@ -138,6 +153,20 @@ vpc:
returned: always returned: always
type: str type: str
sample: default sample: default
ipv6_cidr_block_association_set:
description: IPv6 CIDR blocks associated with the VPC
returned: success
type: list
sample:
"ipv6_cidr_block_association_set": [
{
"association_id": "vpc-cidr-assoc-97aeeefd",
"ipv6_cidr_block": "2001:db8::/56",
"ipv6_cidr_block_state": {
"state": "associated"
}
}
]
is_default: is_default:
description: indicates whether this is the default VPC description: indicates whether this is the default VPC
returned: always returned: always
@ -337,6 +366,7 @@ def main():
argument_spec = dict( argument_spec = dict(
name=dict(required=True), name=dict(required=True),
cidr_block=dict(type='list', required=True), cidr_block=dict(type='list', required=True),
ipv6_cidr=dict(type='bool', default=False),
tenancy=dict(choices=['default', 'dedicated'], default='default'), tenancy=dict(choices=['default', 'dedicated'], default='default'),
dns_support=dict(type='bool', default=True), dns_support=dict(type='bool', default=True),
dns_hostnames=dict(type='bool', default=True), dns_hostnames=dict(type='bool', default=True),
@ -354,6 +384,7 @@ def main():
name = module.params.get('name') name = module.params.get('name')
cidr_block = get_cidr_network_bits(module, module.params.get('cidr_block')) cidr_block = get_cidr_network_bits(module, module.params.get('cidr_block'))
ipv6_cidr = module.params.get('ipv6_cidr')
purge_cidrs = module.params.get('purge_cidrs') purge_cidrs = module.params.get('purge_cidrs')
tenancy = module.params.get('tenancy') tenancy = module.params.get('tenancy')
dns_support = module.params.get('dns_support') dns_support = module.params.get('dns_support')
@ -395,7 +426,21 @@ def main():
if len(cidr_block) > 1: if len(cidr_block) > 1:
for cidr in to_add: for cidr in to_add:
changed = True changed = True
connection.associate_vpc_cidr_block(CidrBlock=cidr, VpcId=vpc_id) try:
connection.associate_vpc_cidr_block(CidrBlock=cidr, VpcId=vpc_id)
except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
module.fail_json_aws(e, "Unable to associate CIDR {0}.".format(ipv6_cidr))
if ipv6_cidr:
if 'Ipv6CidrBlockAssociationSet' in vpc_obj.keys():
module.warn("Only one IPv6 CIDR is permitted per VPC, {0} already has CIDR {1}".format(
vpc_id,
vpc_obj['Ipv6CidrBlockAssociationSet'][0]['Ipv6CidrBlock']))
else:
try:
connection.associate_vpc_cidr_block(AmazonProvidedIpv6CidrBlock=ipv6_cidr, VpcId=vpc_id)
changed = True
except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
module.fail_json_aws(e, "Unable to associate CIDR {0}.".format(ipv6_cidr))
if purge_cidrs: if purge_cidrs:
for association_id in to_remove: for association_id in to_remove:

View file

@ -63,6 +63,7 @@
- name: create a VPC - name: create a VPC
ec2_vpc_net: ec2_vpc_net:
cidr_block: 20.0.0.0/24 cidr_block: 20.0.0.0/24
ipv6_cidr: True
name: "{{ resource_prefix }}" name: "{{ resource_prefix }}"
state: present state: present
<<: *aws_connection_info <<: *aws_connection_info
@ -78,6 +79,7 @@
assert: assert:
that: that:
- '"cidr_block" in result.vpc' - '"cidr_block" in result.vpc'
- '"ipv6_cidr_block_association_set" in result.vpc'
- '"classic_link_enabled" in result.vpc' - '"classic_link_enabled" in result.vpc'
- '"dhcp_options_id" in result.vpc' - '"dhcp_options_id" in result.vpc'
- '"id" in result.vpc' - '"id" in result.vpc'
@ -86,9 +88,10 @@
- '"state" in result.vpc' - '"state" in result.vpc'
- '"tags" in result.vpc' - '"tags" in result.vpc'
- name: set the first VPC as a fact for comparison and cleanup - name: set the first VPC's details as facts for comparison and cleanup
set_fact: set_fact:
vpc_1: "{{ result.vpc.id }}" vpc_1: "{{ result.vpc.id }}"
vpc_1_ipv6_cidr: "{{ result.vpc.ipv6_cidr_block_association_set.0.ipv6_cidr_block }}"
- name: save default dhcp_options_id for later comparison - name: save default dhcp_options_id for later comparison
set_fact: set_fact:
@ -96,9 +99,28 @@
# ============================================================ # ============================================================
- name: Try to add IPv6 CIDR when one already exists
ec2_vpc_net:
cidr_block: 20.0.0.0/24
ipv6_cidr: True
name: "{{ resource_prefix }}"
state: present
multi_ok: no
<<: *aws_connection_info
register: result
- name: Assert no changes made
assert:
that:
- '"Only one IPv6 CIDR is permitted per VPC, {{ result.vpc.id }} already has CIDR {{ vpc_1_ipv6_cidr }}" in result.warnings'
- 'not result.changed'
# ============================================================
- name: test check mode creating an identical VPC - name: test check mode creating an identical VPC
ec2_vpc_net: ec2_vpc_net:
cidr_block: 20.0.0.0/24 cidr_block: 20.0.0.0/24
ipv6_cidr: True
name: "{{ resource_prefix }}" name: "{{ resource_prefix }}"
state: present state: present
multi_ok: yes multi_ok: yes
@ -117,6 +139,7 @@
ec2_vpc_net: ec2_vpc_net:
cidr_block: 20.0.0.0/24 cidr_block: 20.0.0.0/24
name: "{{ resource_prefix }}" name: "{{ resource_prefix }}"
ipv6_cidr: True
tenancy: dedicated tenancy: dedicated
state: present state: present
multi_ok: yes multi_ok: yes
@ -136,6 +159,7 @@
- name: attempt to create another VPC with the same CIDR and name without multi_ok - name: attempt to create another VPC with the same CIDR and name without multi_ok
ec2_vpc_net: ec2_vpc_net:
cidr_block: 20.0.0.0/24 cidr_block: 20.0.0.0/24
ipv6_cidr: True
name: "{{ resource_prefix }}" name: "{{ resource_prefix }}"
state: present state: present
multi_ok: no multi_ok: no

View file

@ -21,11 +21,15 @@
name: "{{ resource_prefix }}-vpc" name: "{{ resource_prefix }}-vpc"
state: present state: present
cidr_block: "10.232.232.128/26" cidr_block: "10.232.232.128/26"
ipv6_cidr: True
tags: tags:
Name: "{{ resource_prefix }}-vpc" Name: "{{ resource_prefix }}-vpc"
Description: "Created by ansible-test" Description: "Created by ansible-test"
register: vpc_result register: vpc_result
- set_fact:
vpc_ipv6_cidr: "{{ vpc_result.vpc.ipv6_cidr_block_association_set[0].ipv6_cidr_block }}"
# ============================================================ # ============================================================
- name: create subnet (expected changed=true) (CHECK MODE) - name: create subnet (expected changed=true) (CHECK MODE)
ec2_vpc_subnet: ec2_vpc_subnet:
@ -371,35 +375,6 @@
that: that:
- result is changed - result is changed
# ============================================================
# FIXME - Replace by creating IPv6 enabled VPC once ec2_vpc_net module supports it.
# See Also https://github.com/ansible/ansible/pull/60983
- name:
set_fact:
aws_connection_env:
AWS_ACCESS_KEY_ID: "{{ aws_access_key }}"
AWS_SECRET_ACCESS_KEY: "{{ aws_secret_key }}"
AWS_SESSION_TOKEN: "{{ security_token | default(omit) }}"
AWS_DEFAULT_REGION: "{{ aws_region }}"
no_log: yes
- name: install aws cli - FIXME temporary this should go for a lighterweight solution
command: pip install awscli
- name: Assign an Amazon provided IPv6 CIDR block to the VPC
command: aws ec2 associate-vpc-cidr-block --amazon-provided-ipv6-cidr-block --vpc-id '{{ vpc_result.vpc.id }}'
environment: '{{ aws_connection_env }}'
- name: wait for the IPv6 CIDR to be assigned
command: sleep 5
- name: Get the assigned IPv6 CIDR
command: aws ec2 describe-vpcs --vpc-ids '{{ vpc_result.vpc.id }}'
environment: '{{ aws_connection_env }}'
register: vpc_ipv6
- set_fact:
vpc_ipv6_cidr: "{{ vpc_ipv6.stdout | from_json | json_query('Vpcs[0].Ipv6CidrBlockAssociationSet[0].Ipv6CidrBlock') }}"
# ============================================================ # ============================================================
- name: create subnet with IPv6 (expected changed=true) (CHECK MODE) - name: create subnet with IPv6 (expected changed=true) (CHECK MODE)