* Port ec2_vpc_net to boto3 and add support to expand existing VPCs * Add s-hertel as an author for ec2_vpc_net * Update ec2_vpc_net test for new error triggered by lack of credentials Fix backwards compatibility Document new return value * Fix pep8 and return documentation
This commit is contained in:
parent
465ace4c14
commit
cae14e16ac
2 changed files with 139 additions and 110 deletions
|
@ -16,61 +16,63 @@ DOCUMENTATION = '''
|
||||||
module: ec2_vpc_net
|
module: ec2_vpc_net
|
||||||
short_description: Configure AWS virtual private clouds
|
short_description: Configure AWS virtual private clouds
|
||||||
description:
|
description:
|
||||||
- Create or terminate AWS virtual private clouds. This module has a dependency on python-boto.
|
- Create, modify, and terminate AWS virtual private clouds.
|
||||||
version_added: "2.0"
|
version_added: "2.0"
|
||||||
author: Jonathan Davila (@defionscode)
|
author:
|
||||||
|
- Jonathan Davila (@defionscode)
|
||||||
|
- Sloane Hertel (@s-hertel)
|
||||||
options:
|
options:
|
||||||
name:
|
name:
|
||||||
description:
|
description:
|
||||||
- The name to give your VPC. This is used in combination with the cidr_block parameter to determine if a VPC already exists.
|
- The name to give your VPC. This is used in combination with C(cidr_block) to determine if a VPC already exists.
|
||||||
required: yes
|
required: yes
|
||||||
cidr_block:
|
cidr_block:
|
||||||
description:
|
description:
|
||||||
- The CIDR of the VPC
|
- 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.
|
||||||
required: yes
|
required: yes
|
||||||
|
purge_cidrs:
|
||||||
|
description:
|
||||||
|
- Remove CIDRs that are associated with the VPC and are not specified in C(cidr_block).
|
||||||
|
default: no
|
||||||
|
choices: [ 'yes', 'no' ]
|
||||||
|
version_added: '2.5'
|
||||||
tenancy:
|
tenancy:
|
||||||
description:
|
description:
|
||||||
- Whether to be default or dedicated tenancy. This cannot be changed after the VPC has been created.
|
- Whether to be default or dedicated tenancy. This cannot be changed after the VPC has been created.
|
||||||
required: false
|
|
||||||
default: default
|
default: default
|
||||||
choices: [ 'default', 'dedicated' ]
|
choices: [ 'default', 'dedicated' ]
|
||||||
dns_support:
|
dns_support:
|
||||||
description:
|
description:
|
||||||
- Whether to enable AWS DNS support.
|
- Whether to enable AWS DNS support.
|
||||||
required: false
|
|
||||||
default: yes
|
default: yes
|
||||||
choices: [ 'yes', 'no' ]
|
choices: [ 'yes', 'no' ]
|
||||||
dns_hostnames:
|
dns_hostnames:
|
||||||
description:
|
description:
|
||||||
- Whether to enable AWS hostname support.
|
- Whether to enable AWS hostname support.
|
||||||
required: false
|
|
||||||
default: yes
|
default: yes
|
||||||
choices: [ 'yes', 'no' ]
|
choices: [ 'yes', 'no' ]
|
||||||
dhcp_opts_id:
|
dhcp_opts_id:
|
||||||
description:
|
description:
|
||||||
- the id of the DHCP options to use for this vpc
|
- the id of the DHCP options to use for this vpc
|
||||||
default: null
|
|
||||||
required: false
|
|
||||||
tags:
|
tags:
|
||||||
description:
|
description:
|
||||||
- The tags you want attached to the VPC. This is independent of the name value, note if you pass a 'Name' key it would override the Name of
|
- The tags you want attached to the VPC. This is independent of the name value, note if you pass a 'Name' key it would override the Name of
|
||||||
the VPC if it's different.
|
the VPC if it's different.
|
||||||
default: None
|
|
||||||
required: false
|
|
||||||
aliases: [ 'resource_tags' ]
|
aliases: [ 'resource_tags' ]
|
||||||
state:
|
state:
|
||||||
description:
|
description:
|
||||||
- The state of the VPC. Either absent or present.
|
- The state of the VPC. Either absent or present.
|
||||||
default: present
|
default: present
|
||||||
required: false
|
|
||||||
choices: [ 'present', 'absent' ]
|
choices: [ 'present', 'absent' ]
|
||||||
multi_ok:
|
multi_ok:
|
||||||
description:
|
description:
|
||||||
- By default the module will not create another VPC if there is another VPC with the same name and CIDR block. Specify this as true if you want
|
- By default the module will not create another VPC if there is another VPC with the same name and CIDR block. Specify this as true if you want
|
||||||
duplicate VPCs created.
|
duplicate VPCs created.
|
||||||
default: false
|
default: false
|
||||||
required: false
|
requirements:
|
||||||
|
- boto3
|
||||||
|
- botocore
|
||||||
extends_documentation_fragment:
|
extends_documentation_fragment:
|
||||||
- aws
|
- aws
|
||||||
- ec2
|
- ec2
|
||||||
|
@ -133,17 +135,30 @@ vpc.is_default:
|
||||||
returned: success
|
returned: success
|
||||||
type: boolean
|
type: boolean
|
||||||
sample: false
|
sample: false
|
||||||
|
vpc.cidr_block_association_set:
|
||||||
|
description: IPv4 CIDR blocks associated with the VPC
|
||||||
|
returned: success
|
||||||
|
type: list
|
||||||
|
sample:
|
||||||
|
"cidr_block_association_set": [
|
||||||
|
{
|
||||||
|
"association_id": "vpc-cidr-assoc-97aeeefd",
|
||||||
|
"cidr_block": "20.0.0.0/24",
|
||||||
|
"cidr_block_state": {
|
||||||
|
"state": "associated"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
'''
|
'''
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import boto.vpc
|
import botocore
|
||||||
from boto.exception import BotoServerError, NoAuthHandlerFound
|
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass # Taken care of by ec2.HAS_BOTO
|
pass # Handled by AnsibleAWSModule
|
||||||
|
|
||||||
from ansible.module_utils.basic import AnsibleModule
|
from ansible.module_utils.aws.core import AnsibleAWSModule
|
||||||
from ansible.module_utils.ec2 import (HAS_BOTO, AnsibleAWSError, boto_exception, connect_to_aws,
|
from ansible.module_utils.ec2 import boto3_conn, get_aws_connection_info, ec2_argument_spec, ansible_dict_to_boto3_tag_list, camel_dict_to_snake_dict
|
||||||
ec2_argument_spec, get_aws_connection_info)
|
from ansible.module_utils.six import string_types
|
||||||
|
|
||||||
|
|
||||||
def vpc_exists(module, vpc, name, cidr_block, multi):
|
def vpc_exists(module, vpc, name, cidr_block, multi):
|
||||||
|
@ -151,95 +166,102 @@ def vpc_exists(module, vpc, name, cidr_block, multi):
|
||||||
with a CIDR, it will check for matching tags to determine if it is a match
|
with a CIDR, it will check for matching tags to determine if it is a match
|
||||||
otherwise it will assume the VPC does not exist and thus return None.
|
otherwise it will assume the VPC does not exist and thus return None.
|
||||||
"""
|
"""
|
||||||
matched_vpc = None
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
matching_vpcs = vpc.get_all_vpcs(filters={'tag:Name': name, 'cidr-block': cidr_block})
|
matching_vpcs = vpc.describe_vpcs(Filters=[{'Name': 'tag:Name', 'Values': [name]}, {'Name': 'cidr-block', 'Values': cidr_block}])['Vpcs']
|
||||||
except Exception as e:
|
# If an exact matching using a list of CIDRs isn't found, check for a match with the first CIDR as is documented for C(cidr_block)
|
||||||
e_msg = boto_exception(e)
|
if not matching_vpcs:
|
||||||
module.fail_json(msg=e_msg)
|
matching_vpcs = vpc.describe_vpcs(Filters=[{'Name': 'tag:Name', 'Values': [name]}, {'Name': 'cidr-block', 'Values': [cidr_block[0]]}])['Vpcs']
|
||||||
|
except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
|
||||||
|
module.fail_json_aws(e, msg="Failed to describe VPCs")
|
||||||
|
|
||||||
if multi:
|
if multi:
|
||||||
return None
|
return None
|
||||||
elif len(matching_vpcs) == 1:
|
elif len(matching_vpcs) == 1:
|
||||||
matched_vpc = matching_vpcs[0]
|
return matching_vpcs[0]['VpcId']
|
||||||
elif len(matching_vpcs) > 1:
|
elif len(matching_vpcs) > 1:
|
||||||
module.fail_json(msg='Currently there are %d VPCs that have the same name and '
|
module.fail_json(msg='Currently there are %d VPCs that have the same name and '
|
||||||
'CIDR block you specified. If you would like to create '
|
'CIDR block you specified. If you would like to create '
|
||||||
'the VPC anyway please pass True to the multi_ok param.' % len(matching_vpcs))
|
'the VPC anyway please pass True to the multi_ok param.' % len(matching_vpcs))
|
||||||
|
return None
|
||||||
return matched_vpc
|
|
||||||
|
|
||||||
|
|
||||||
def update_vpc_tags(vpc, module, vpc_obj, tags, name):
|
def get_vpc(module, connection, vpc_id):
|
||||||
|
try:
|
||||||
|
vpc_obj = connection.describe_vpcs(VpcIds=[vpc_id])['Vpcs'][0]
|
||||||
|
classic_link = connection.describe_vpc_classic_link(VpcIds=[vpc_id])['Vpcs'][0].get('ClassicLinkEnabled')
|
||||||
|
vpc_obj['ClassicLinkEnabled'] = classic_link
|
||||||
|
except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
|
||||||
|
module.fail_json_aws(e, msg="Failed to describe VPCs")
|
||||||
|
|
||||||
|
return vpc_obj
|
||||||
|
|
||||||
|
|
||||||
|
def update_vpc_tags(connection, module, vpc_id, tags, name):
|
||||||
|
|
||||||
if tags is None:
|
if tags is None:
|
||||||
tags = dict()
|
tags = dict()
|
||||||
|
|
||||||
tags.update({'Name': name})
|
tags.update({'Name': name})
|
||||||
try:
|
try:
|
||||||
current_tags = dict((t.name, t.value) for t in vpc.get_all_tags(filters={'resource-id': vpc_obj.id}))
|
current_tags = dict((t['Key'], t['Value']) for t in connection.describe_tags(Filters=[{'Name': 'resource-id', 'Values': [vpc_id]}])['Tags'])
|
||||||
if tags != current_tags:
|
if tags != current_tags:
|
||||||
if not module.check_mode:
|
if not module.check_mode:
|
||||||
vpc.create_tags(vpc_obj.id, tags)
|
tags = ansible_dict_to_boto3_tag_list(tags)
|
||||||
|
connection.create_tags(Resources=[vpc_id], Tags=tags)
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
except Exception as e:
|
except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
|
||||||
e_msg = boto_exception(e)
|
module.fail_json_aws(e, msg="Failed to update tags")
|
||||||
module.fail_json(msg=e_msg)
|
|
||||||
|
|
||||||
|
|
||||||
def update_dhcp_opts(connection, module, vpc_obj, dhcp_id):
|
def update_dhcp_opts(connection, module, vpc_obj, dhcp_id):
|
||||||
|
if vpc_obj['DhcpOptionsId'] != dhcp_id:
|
||||||
if vpc_obj.dhcp_options_id != dhcp_id:
|
|
||||||
if not module.check_mode:
|
if not module.check_mode:
|
||||||
connection.associate_dhcp_options(dhcp_id, vpc_obj.id)
|
try:
|
||||||
|
connection.associate_dhcp_options(DhcpOptionsId=dhcp_id, VpcId=vpc_obj['VpcId'])
|
||||||
|
except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
|
||||||
|
module.fail_json_aws(e, msg="Failed to associate DhcpOptionsId {0}".format(dhcp_id))
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def get_vpc_values(vpc_obj):
|
def create_vpc(connection, module, cidr_block, tenancy):
|
||||||
|
try:
|
||||||
if vpc_obj is not None:
|
if not module.check_mode:
|
||||||
vpc_values = vpc_obj.__dict__
|
vpc_obj = connection.create_vpc(CidrBlock=cidr_block, InstanceTenancy=tenancy)
|
||||||
if "region" in vpc_values:
|
|
||||||
vpc_values.pop("region")
|
|
||||||
if "item" in vpc_values:
|
|
||||||
vpc_values.pop("item")
|
|
||||||
if "connection" in vpc_values:
|
|
||||||
vpc_values.pop("connection")
|
|
||||||
return vpc_values
|
|
||||||
else:
|
else:
|
||||||
return None
|
module.exit_json(changed=True)
|
||||||
|
except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
|
||||||
|
module.fail_json_aws(e, "Failed to create the VPC")
|
||||||
|
return vpc_obj['Vpc']['VpcId']
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
argument_spec = ec2_argument_spec()
|
argument_spec = ec2_argument_spec()
|
||||||
argument_spec.update(dict(
|
argument_spec.update(dict(
|
||||||
name=dict(type='str', default=None, required=True),
|
name=dict(required=True),
|
||||||
cidr_block=dict(type='str', default=None, required=True),
|
cidr_block=dict(type='list', required=True),
|
||||||
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),
|
||||||
dhcp_opts_id=dict(type='str', default=None, required=False),
|
dhcp_opts_id=dict(),
|
||||||
tags=dict(type='dict', required=False, default=None, aliases=['resource_tags']),
|
tags=dict(type='dict', aliases=['resource_tags']),
|
||||||
state=dict(choices=['present', 'absent'], default='present'),
|
state=dict(choices=['present', 'absent'], default='present'),
|
||||||
multi_ok=dict(type='bool', default=False)
|
multi_ok=dict(type='bool', default=False),
|
||||||
|
purge_cidrs=dict(type='bool', default=False),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
module = AnsibleModule(
|
module = AnsibleAWSModule(
|
||||||
argument_spec=argument_spec,
|
argument_spec=argument_spec,
|
||||||
supports_check_mode=True
|
supports_check_mode=True
|
||||||
)
|
)
|
||||||
|
|
||||||
if not HAS_BOTO:
|
|
||||||
module.fail_json(msg='boto is required for this module')
|
|
||||||
|
|
||||||
name = module.params.get('name')
|
name = module.params.get('name')
|
||||||
cidr_block = module.params.get('cidr_block')
|
cidr_block = module.params.get('cidr_block')
|
||||||
|
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')
|
||||||
dns_hostnames = module.params.get('dns_hostnames')
|
dns_hostnames = module.params.get('dns_hostnames')
|
||||||
|
@ -250,15 +272,8 @@ def main():
|
||||||
|
|
||||||
changed = False
|
changed = False
|
||||||
|
|
||||||
region, ec2_url, aws_connect_params = get_aws_connection_info(module)
|
region, ec2_url, aws_connect_params = get_aws_connection_info(module, boto3=True)
|
||||||
|
connection = boto3_conn(module, conn_type='client', resource='ec2', region=region, **aws_connect_params)
|
||||||
if region:
|
|
||||||
try:
|
|
||||||
connection = connect_to_aws(boto.vpc, region, **aws_connect_params)
|
|
||||||
except (NoAuthHandlerFound, AnsibleAWSError) as e:
|
|
||||||
module.fail_json(msg=str(e))
|
|
||||||
else:
|
|
||||||
module.fail_json(msg="region must be specified")
|
|
||||||
|
|
||||||
if dns_hostnames and not dns_support:
|
if dns_hostnames and not dns_support:
|
||||||
module.fail_json(msg='In order to enable DNS Hostnames you must also enable DNS support')
|
module.fail_json(msg='In order to enable DNS Hostnames you must also enable DNS support')
|
||||||
|
@ -266,70 +281,84 @@ def main():
|
||||||
if state == 'present':
|
if state == 'present':
|
||||||
|
|
||||||
# Check if VPC exists
|
# Check if VPC exists
|
||||||
vpc_obj = vpc_exists(module, connection, name, cidr_block, multi)
|
vpc_id = vpc_exists(module, connection, name, cidr_block, multi)
|
||||||
|
|
||||||
if vpc_obj is None:
|
if vpc_id is None:
|
||||||
try:
|
vpc_id = create_vpc(connection, module, cidr_block[0], tenancy)
|
||||||
changed = True
|
changed = True
|
||||||
if not module.check_mode:
|
|
||||||
vpc_obj = connection.create_vpc(cidr_block, instance_tenancy=tenancy)
|
vpc_obj = get_vpc(module, connection, vpc_id)
|
||||||
else:
|
|
||||||
module.exit_json(changed=changed)
|
associated_cidrs = dict((cidr['CidrBlock'], cidr['AssociationId']) for cidr in vpc_obj.get('CidrBlockAssociationSet', [])
|
||||||
except BotoServerError as e:
|
if cidr['CidrBlockState']['State'] != 'disassociated')
|
||||||
module.fail_json(msg=e)
|
to_add = [cidr for cidr in cidr_block if cidr not in associated_cidrs]
|
||||||
|
to_remove = [associated_cidrs[cidr] for cidr in associated_cidrs if cidr not in cidr_block]
|
||||||
|
|
||||||
|
if len(cidr_block) > 1:
|
||||||
|
for cidr in to_add:
|
||||||
|
changed = True
|
||||||
|
connection.associate_vpc_cidr_block(CidrBlock=cidr, VpcId=vpc_id)
|
||||||
|
|
||||||
|
if purge_cidrs:
|
||||||
|
for association_id in to_remove:
|
||||||
|
changed = True
|
||||||
|
try:
|
||||||
|
connection.disassociate_vpc_cidr_block(AssociationId=association_id)
|
||||||
|
except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
|
||||||
|
module.fail_json_aws(e, "Unable to disassociate {0}. You must detach or delete all gateways and resources that "
|
||||||
|
"are associated with the CIDR block before you can disassociate it.".format(association_id))
|
||||||
|
|
||||||
if dhcp_id is not None:
|
if dhcp_id is not None:
|
||||||
try:
|
try:
|
||||||
if update_dhcp_opts(connection, module, vpc_obj, dhcp_id):
|
if update_dhcp_opts(connection, module, vpc_obj, dhcp_id):
|
||||||
changed = True
|
changed = True
|
||||||
except BotoServerError as e:
|
except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
|
||||||
module.fail_json(msg=e)
|
module.fail_json_aws(e, "Failed to update DHCP options")
|
||||||
|
|
||||||
if tags is not None or name is not None:
|
if tags is not None or name is not None:
|
||||||
try:
|
try:
|
||||||
if update_vpc_tags(connection, module, vpc_obj, tags, name):
|
if update_vpc_tags(connection, module, vpc_id, tags, name):
|
||||||
changed = True
|
changed = True
|
||||||
except BotoServerError as e:
|
except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
|
||||||
module.fail_json(msg=e)
|
module.fail_json_aws(e, msg="Failed to update tags")
|
||||||
|
|
||||||
# Note: Boto currently doesn't currently provide an interface to ec2-describe-vpc-attribute
|
current_dns_enabled = connection.describe_vpc_attribute(Attribute='enableDnsSupport', VpcId=vpc_id)['EnableDnsSupport']['Value']
|
||||||
# which is needed in order to detect the current status of DNS options. For now we just update
|
current_dns_hostnames = connection.describe_vpc_attribute(Attribute='enableDnsHostnames', VpcId=vpc_id)['EnableDnsHostnames']['Value']
|
||||||
# the attribute each time and is not used as a changed-factor.
|
if current_dns_enabled != dns_support:
|
||||||
try:
|
changed = True
|
||||||
if not module.check_mode:
|
if not module.check_mode:
|
||||||
connection.modify_vpc_attribute(vpc_obj.id, enable_dns_support=dns_support)
|
|
||||||
connection.modify_vpc_attribute(vpc_obj.id, enable_dns_hostnames=dns_hostnames)
|
|
||||||
except BotoServerError as e:
|
|
||||||
e_msg = boto_exception(e)
|
|
||||||
module.fail_json(msg=e_msg)
|
|
||||||
|
|
||||||
if not module.check_mode:
|
|
||||||
# get the vpc obj again in case it has changed
|
|
||||||
try:
|
try:
|
||||||
vpc_obj = connection.get_all_vpcs(vpc_obj.id)[0]
|
connection.modify_vpc_attribute(VpcId=vpc_id, EnableDnsSupport={'Value': dns_support})
|
||||||
except BotoServerError as e:
|
except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
|
||||||
e_msg = boto_exception(e)
|
module.fail_json_aws(e, "Failed to update enabled dns support attribute")
|
||||||
module.fail_json(msg=e_msg)
|
if current_dns_hostnames != dns_hostnames:
|
||||||
|
changed = True
|
||||||
|
if not module.check_mode:
|
||||||
|
try:
|
||||||
|
connection.modify_vpc_attribute(VpcId=vpc_id, EnableDnsHostnames={'Value': dns_hostnames})
|
||||||
|
except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
|
||||||
|
module.fail_json_aws(e, "Failed to update enabled dns hostnames attribute")
|
||||||
|
|
||||||
module.exit_json(changed=changed, vpc=get_vpc_values(vpc_obj))
|
final_state = camel_dict_to_snake_dict(get_vpc(module, connection, vpc_id))
|
||||||
|
final_state['id'] = final_state.pop('vpc_id')
|
||||||
|
|
||||||
|
module.exit_json(changed=changed, vpc=final_state)
|
||||||
|
|
||||||
elif state == 'absent':
|
elif state == 'absent':
|
||||||
|
|
||||||
# Check if VPC exists
|
# Check if VPC exists
|
||||||
vpc_obj = vpc_exists(module, connection, name, cidr_block, multi)
|
vpc_id = vpc_exists(module, connection, name, cidr_block, multi)
|
||||||
|
|
||||||
if vpc_obj is not None:
|
if vpc_id is not None:
|
||||||
try:
|
try:
|
||||||
if not module.check_mode:
|
if not module.check_mode:
|
||||||
connection.delete_vpc(vpc_obj.id)
|
connection.delete_vpc(VpcId=vpc_id)
|
||||||
vpc_obj = None
|
|
||||||
changed = True
|
changed = True
|
||||||
except BotoServerError as e:
|
except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
|
||||||
e_msg = boto_exception(e)
|
module.fail_json_aws(e, msg="Failed to delete VPC {0} You may want to use the ec2_vpc_subnet, ec2_vpc_igw, "
|
||||||
module.fail_json(msg="%s. You may want to use the ec2_vpc_subnet, ec2_vpc_igw, "
|
"and/or ec2_vpc_route_table modules to ensure the other components are absent.".format(vpc_id))
|
||||||
"and/or ec2_vpc_route_table modules to ensure the other components are absent." % e_msg)
|
|
||||||
|
|
||||||
module.exit_json(changed=changed, vpc=get_vpc_values(vpc_obj))
|
module.exit_json(changed=changed, vpc={})
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- 'result is failed'
|
- 'result is failed'
|
||||||
- 'result.msg.startswith("No handler was ready to authenticate")'
|
- '"Unable to locate credentials" in result.msg'
|
||||||
|
|
||||||
# ============================================================
|
# ============================================================
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue