@ -16,7 +16,7 @@
DOCUMENTATION = '''
DOCUMENTATION = '''
---
---
module: ec2_vpc
module: ec2_vpc
short_description: configure AWS virtual private clouds
short_description: configure AWS virtual private clouds
description:
description:
- Create or terminates AWS virtual private clouds. This module has a dependency on python-boto.
- Create or terminates AWS virtual private clouds. This module has a dependency on python-boto.
@ -59,7 +59,7 @@ options:
resource_tags:
resource_tags:
description:
description:
- 'A dictionary array of resource tags of the form: { tag1: value1, tag2: value2 }. Tags in this list are used in conjunction with CIDR block to uniquely identify a VPC in lieu of vpc_id. Therefore, if CIDR/Tag combination does not exits, a new VPC will be created. VPC tags not on this list will be ignored.'
- 'A dictionary array of resource tags of the form: { tag1: value1, tag2: value2 }. Tags in this list are used in conjunction with CIDR block to uniquely identify a VPC in lieu of vpc_id. Therefore, if CIDR/Tag combination does not exits, a new VPC will be created. VPC tags not on this list will be ignored.'
required: fals e
required: tru e
default: null
default: null
aliases: []
aliases: []
version_added: "1.6"
version_added: "1.6"
@ -96,13 +96,13 @@ options:
aliases: []
aliases: []
region:
region:
description:
description:
- region in which the resource exists.
- region in which the resource exists.
required: false
required: false
default: null
default: null
aliases: ['aws_region', 'ec2_region']
aliases: ['aws_region', 'ec2_region']
aws_secret_key:
aws_secret_key:
description:
description:
- AWS secret key. If not set then the value of the AWS_SECRET_KEY environment variable is used.
- AWS secret key. If not set then the value of the AWS_SECRET_KEY environment variable is used.
required: false
required: false
default: None
default: None
aliases: ['ec2_secret_key', 'secret_key' ]
aliases: ['ec2_secret_key', 'secret_key' ]
@ -143,7 +143,7 @@ EXAMPLES = '''
state: present
state: present
cidr_block: 172.22.0.0/16
cidr_block: 172.22.0.0/16
resource_tags: { "Environment":"Development" }
resource_tags: { "Environment":"Development" }
subnets:
subnets:
- cidr: 172.22.1.0/24
- cidr: 172.22.1.0/24
az: us-west-2c
az: us-west-2c
resource_tags: { "Environment":"Dev", "Tier" : "Web" }
resource_tags: { "Environment":"Dev", "Tier" : "Web" }
@ -155,10 +155,10 @@ EXAMPLES = '''
resource_tags: { "Environment":"Dev", "Tier" : "DB" }
resource_tags: { "Environment":"Dev", "Tier" : "DB" }
internet_gateway: True
internet_gateway: True
route_tables:
route_tables:
- subnets:
- subnets:
- 172.22.2.0/24
- 172.22.2.0/24
- 172.22.3.0/24
- 172.22.3.0/24
routes:
routes:
- dest: 0.0.0.0/0
- dest: 0.0.0.0/0
gw: igw
gw: igw
- subnets:
- subnets:
@ -173,8 +173,8 @@ EXAMPLES = '''
local_action:
local_action:
module: ec2_vpc
module: ec2_vpc
state: absent
state: absent
vpc_id: vpc-aaaaaaa
vpc_id: vpc-aaaaaaa
region: us-west-2
region: us-west-2
If you have added elements not managed by this module, e.g. instances, NATs, etc then
If you have added elements not managed by this module, e.g. instances, NATs, etc then
the delete will fail until those dependencies are removed.
the delete will fail until those dependencies are removed.
'''
'''
@ -215,7 +215,7 @@ def find_vpc(module, vpc_conn, vpc_id=None, cidr=None):
Returns:
Returns:
A VPC object that matches either an ID or CIDR and one or more tag values
A VPC object that matches either an ID or CIDR and one or more tag values
"""
"""
if vpc_id == None and cidr == None:
if vpc_id == None and cidr == None:
module.fail_json(
module.fail_json(
msg='You must specify either a vpc_id or a cidr block + list of unique tags, aborting'
msg='You must specify either a vpc_id or a cidr block + list of unique tags, aborting'
@ -228,10 +228,10 @@ def find_vpc(module, vpc_conn, vpc_id=None, cidr=None):
# Check for existing VPC by cidr_block or id
# Check for existing VPC by cidr_block or id
if vpc_id is not None:
if vpc_id is not None:
found_vpcs = vpc_conn.get_all_vpcs(None, {'vpc-id': vpc_id, 'state': 'available',})
found_vpcs = vpc_conn.get_all_vpcs(None, {'vpc-id': vpc_id, 'state': 'available',})
else:
else:
previous_vpcs = vpc_conn.get_all_vpcs(None, {'cidr': cidr, 'state': 'available'})
previous_vpcs = vpc_conn.get_all_vpcs(None, {'cidr': cidr, 'state': 'available'})
for vpc in previous_vpcs:
for vpc in previous_vpcs:
# Get all tags for each of the found VPCs
# Get all tags for each of the found VPCs
vpc_tags = dict((t.name, t.value) for t in vpc_conn.get_all_tags(filters={'resource-id': vpc.id}))
vpc_tags = dict((t.name, t.value) for t in vpc_conn.get_all_tags(filters={'resource-id': vpc.id}))
@ -259,9 +259,9 @@ def create_vpc(module, vpc_conn):
Returns:
Returns:
A dictionary with information
A dictionary with information
about the VPC and subnets that were launched
about the VPC and subnets that were launched
"""
"""
id = module.params.get('vpc_id')
id = module.params.get('vpc_id')
cidr_block = module.params.get('cidr_block')
cidr_block = module.params.get('cidr_block')
instance_tenancy = module.params.get('instance_tenancy')
instance_tenancy = module.params.get('instance_tenancy')
@ -270,6 +270,7 @@ def create_vpc(module, vpc_conn):
subnets = module.params.get('subnets')
subnets = module.params.get('subnets')
internet_gateway = module.params.get('internet_gateway')
internet_gateway = module.params.get('internet_gateway')
route_tables = module.params.get('route_tables')
route_tables = module.params.get('route_tables')
vpc_spec_tags = module.params.get('resource_tags')
wait = module.params.get('wait')
wait = module.params.get('wait')
wait_timeout = int(module.params.get('wait_timeout'))
wait_timeout = int(module.params.get('wait_timeout'))
changed = False
changed = False
@ -311,16 +312,15 @@ def create_vpc(module, vpc_conn):
# Done with base VPC, now change to attributes and features.
# Done with base VPC, now change to attributes and features.
# Add resource tags
# Add resource tags
vpc_spec_tags = module.params.get('resource_tags')
vpc_tags = dict((t.name, t.value) for t in vpc_conn.get_all_tags(filters={'resource-id': vpc.id}))
vpc_tags = dict((t.name, t.value) for t in vpc_conn.get_all_tags(filters={'resource-id': vpc.id}))
if vpc_spec_tags and not set(vpc_spec_tags.items()).issubset(set(vpc_tags.items())):
if not set(vpc_spec_tags.items()).issubset(set(vpc_tags.items())):
new_tags = {}
new_tags = {}
for (key, value) in set(vpc_spec_tags.items()):
for (key, value) in set(vpc_spec_tags.items()):
if (key, value) not in set(vpc_tags.items()):
if (key, value) not in set(vpc_tags.items()):
new_tags[key] = value
new_tags[key] = value
if new_tags:
if new_tags:
vpc_conn.create_tags(vpc.id, new_tags)
vpc_conn.create_tags(vpc.id, new_tags)
@ -335,9 +335,9 @@ def create_vpc(module, vpc_conn):
# Process all subnet properties
# Process all subnet properties
if subnets and not isinstance(subnets, list):
if subnets and not isinstance(subnets, list):
module.fail_json(msg='subnets needs to be a list of cidr blocks')
module.fail_json(msg='subnets needs to be a list of cidr blocks')
current_subnets = vpc_conn.get_all_subnets(filters={ 'vpc_id': vpc.id })
current_subnets = vpc_conn.get_all_subnets(filters={ 'vpc_id': vpc.id })
# First add all new subnets
# First add all new subnets
for subnet in subnets:
for subnet in subnets:
add_subnet = True
add_subnet = True
@ -361,7 +361,7 @@ def create_vpc(module, vpc_conn):
changed = True
changed = True
except EC2ResponseError, e:
except EC2ResponseError, e:
module.fail_json(msg='Unable to create subnet {0}, error: {1}'.format(subnet['cidr'], e))
module.fail_json(msg='Unable to create subnet {0}, error: {1}'.format(subnet['cidr'], e))
# Now delete all absent subnets
# Now delete all absent subnets
for csubnet in current_subnets:
for csubnet in current_subnets:
delete_subnet = True
delete_subnet = True
@ -378,7 +378,7 @@ def create_vpc(module, vpc_conn):
# Handle Internet gateway (create/delete igw)
# Handle Internet gateway (create/delete igw)
igw = None
igw = None
igws = vpc_conn.get_all_internet_gateways(filters={'attachment.vpc-id': vpc.id})
igws = vpc_conn.get_all_internet_gateways(filters={'attachment.vpc-id': vpc.id})
if len(igws) > 1:
if len(igws) > 1:
module.fail_json(msg='EC2 returned more than one Internet Gateway for id %s, aborting' % vpc.id)
module.fail_json(msg='EC2 returned more than one Internet Gateway for id %s, aborting' % vpc.id)
if internet_gateway:
if internet_gateway:
if len(igws) != 1:
if len(igws) != 1:
@ -412,7 +412,7 @@ def create_vpc(module, vpc_conn):
# allow control of the 'main' routing table.
# allow control of the 'main' routing table.
if route_tables and not isinstance(route_tables, list):
if route_tables and not isinstance(route_tables, list):
module.fail_json(msg='route tables need to be a list of dictionaries')
module.fail_json(msg='route tables need to be a list of dictionaries')
# Work through each route table and update/create to match dictionary array
# Work through each route table and update/create to match dictionary array
all_route_tables = []
all_route_tables = []
for rt in route_tables:
for rt in route_tables:
@ -463,7 +463,7 @@ def create_vpc(module, vpc_conn):
msg='Unable to create and associate route table {0}, error: ' \
msg='Unable to create and associate route table {0}, error: ' \
'{1}'.format(rt, e)
'{1}'.format(rt, e)
)
)
# Now that we are good to go on our new route tables, delete the
# Now that we are good to go on our new route tables, delete the
# old ones except the 'main' route table as boto can't set the main
# old ones except the 'main' route table as boto can't set the main
@ -490,11 +490,11 @@ def create_vpc(module, vpc_conn):
created_vpc_id = vpc.id
created_vpc_id = vpc.id
returned_subnets = []
returned_subnets = []
current_subnets = vpc_conn.get_all_subnets(filters={ 'vpc_id': vpc.id })
current_subnets = vpc_conn.get_all_subnets(filters={ 'vpc_id': vpc.id })
for sn in current_subnets:
for sn in current_subnets:
returned_subnets.append({
returned_subnets.append({
'resource_tags': dict((t.name, t.value) for t in vpc_conn.get_all_tags(filters={'resource-id': sn.id})),
'resource_tags': dict((t.name, t.value) for t in vpc_conn.get_all_tags(filters={'resource-id': sn.id})),
'cidr': sn.cidr_block,
'cidr': sn.cidr_block,
'az': sn.availability_zone,
'az': sn.availability_zone,
'id': sn.id,
'id': sn.id,
})
})
@ -520,9 +520,9 @@ def terminate_vpc(module, vpc_conn, vpc_id=None, cidr=None):
vpc_dict = {}
vpc_dict = {}
terminated_vpc_id = ''
terminated_vpc_id = ''
changed = False
changed = False
vpc = find_vpc(module, vpc_conn, vpc_id, cidr)
vpc = find_vpc(module, vpc_conn, vpc_id, cidr)
if vpc is not None:
if vpc is not None:
if vpc.state == 'available':
if vpc.state == 'available':
terminated_vpc_id=vpc.id
terminated_vpc_id=vpc.id
@ -571,7 +571,7 @@ def main():
subnets = dict(type='list', default=[]),
subnets = dict(type='list', default=[]),
vpc_id = dict(),
vpc_id = dict(),
internet_gateway = dict(type='bool', default=False),
internet_gateway = dict(type='bool', default=False),
resource_tags = dict(type='dict'),
resource_tags = dict(type='dict', required=True ),
route_tables = dict(type='list', default=[]),
route_tables = dict(type='list', default=[]),
state = dict(choices=['present', 'absent'], default='present'),
state = dict(choices=['present', 'absent'], default='present'),
)
)
@ -584,12 +584,12 @@ def main():
state = module.params.get('state')
state = module.params.get('state')
ec2_url, aws_access_key, aws_secret_key, region = get_ec2_creds(module)
ec2_url, aws_access_key, aws_secret_key, region = get_ec2_creds(module)
# If we have a region specified, connect to its endpoint.
# If we have a region specified, connect to its endpoint.
if region:
if region:
try:
try:
vpc_conn = boto.vpc.connect_to_region(
vpc_conn = boto.vpc.connect_to_region(
region,
region,
aws_access_key_id=aws_access_key,
aws_access_key_id=aws_access_key,
aws_secret_access_key=aws_secret_key
aws_secret_access_key=aws_secret_key
)
)
@ -597,7 +597,7 @@ def main():
module.fail_json(msg = str(e))
module.fail_json(msg = str(e))
else:
else:
module.fail_json(msg="region must be specified")
module.fail_json(msg="region must be specified")
if module.params.get('state') == 'absent':
if module.params.get('state') == 'absent':
vpc_id = module.params.get('vpc_id')
vpc_id = module.params.get('vpc_id')
cidr = module.params.get('cidr_block')
cidr = module.params.get('cidr_block')