forked from ansible-collections/amazon.aws
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
New Module: TGW VPC Attachments (ansible-collections#1004)
New modules: Transit Gateway VPC attachments SUMMARY Adds support for EC2 Transit Gateway VPC attachments Does not support accepting / rejecting attachments at this time. ISSUE TYPE New Module Pull Request COMPONENT NAME ec2_transit_gateway_vpc_attachment ec2_transit_gateway_vpc_attachment_info ADDITIONAL INFORMATION Reviewed-by: Alina Buzachis <None> This commit was initially merged in https://github.com/ansible-collections/community.aws See: ansible-collections/community.aws@9494e76
- Loading branch information
Showing
10 changed files
with
4,823 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,349 @@ | ||
#!/usr/bin/python | ||
# Copyright: Ansible Project | ||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) | ||
|
||
from __future__ import absolute_import, division, print_function | ||
__metaclass__ = type | ||
|
||
|
||
DOCUMENTATION = ''' | ||
module: ec2_transit_gateway_vpc_attachment | ||
short_description: Create and delete AWS Transit Gateway VPC attachments | ||
version_added: 4.0.0 | ||
description: | ||
- Creates, Deletes and Updates AWS Transit Gateway VPC Attachments. | ||
options: | ||
transit_gateway: | ||
description: | ||
- The ID of the Transit Gateway that the attachment belongs to. | ||
- When creating a new attachment, I(transit_gateway) must be provided. | ||
- At least one of I(name), I(transit_gateway) and I(id) must be provided. | ||
- I(transit_gateway) is an immutable setting and can not be updated on an | ||
existing attachment. | ||
type: str | ||
required: false | ||
aliases: ['transit_gateway_id'] | ||
id: | ||
description: | ||
- The ID of the Transit Gateway Attachment. | ||
- When I(id) is not set, a search using I(transit_gateway) and I(name) will be | ||
performed. If multiple results are returned, the module will fail. | ||
- At least one of I(name), I(transit_gateway) and I(id) must be provided. | ||
type: str | ||
required: false | ||
aliases: ['attachment_id'] | ||
name: | ||
description: | ||
- The C(Name) tag of the Transit Gateway attachment. | ||
- Providing both I(id) and I(name) will set the C(Name) tag on an existing | ||
attachment the matching I(id). | ||
- Setting the C(Name) tag in I(tags) will also result in the C(Name) tag being | ||
updated. | ||
- At least one of I(name), I(transit_gateway) and I(id) must be provided. | ||
type: str | ||
required: false | ||
state: | ||
description: | ||
- Create or remove the Transit Gateway attachment. | ||
type: str | ||
required: false | ||
choices: ['present', 'absent'] | ||
default: 'present' | ||
subnets: | ||
description: | ||
- The ID of the subnets in which to create the transit gateway VPC attachment. | ||
- Required when creating a new attachment. | ||
type: list | ||
elements: str | ||
required: false | ||
purge_subnets: | ||
description: | ||
- If I(purge_subnets=true), existing subnets will be removed from the | ||
attachment as necessary to match exactly what is defined by I(subnets). | ||
type: bool | ||
required: false | ||
default: true | ||
dns_support: | ||
description: | ||
- Whether DNS support is enabled. | ||
type: bool | ||
required: false | ||
ipv6_support: | ||
description: | ||
- Whether IPv6 support is enabled. | ||
type: bool | ||
required: false | ||
appliance_mode_support: | ||
description: | ||
- Whether the attachment is configured for appliance mode. | ||
- When appliance mode is enabled, Transit Gateway, using 4-tuples of an | ||
IP packet, selects a single Transit Gateway ENI in the Appliance VPC | ||
for the life of a flow to send traffic to. | ||
type: bool | ||
required: false | ||
tags: | ||
description: | ||
- A dictionary representing the tags associated with the Transit Gateway | ||
attachment. | ||
- 'For example C({"Example Tag": "some example value"})' | ||
- Unless I(purge_tags=False) all other tags will be removed from the | ||
attachment. | ||
type: dict | ||
required: false | ||
purge_tags: | ||
description: | ||
- If I(purge_tags=true), existing tags will be purged from the resource | ||
to match exactly what is defined by I(tags) parameter. | ||
type: bool | ||
required: false | ||
default: true | ||
wait: | ||
description: | ||
- Whether to wait for the Transit Gateway attachment to reach the | ||
C(Available) or C(Deleted) state before the module returns. | ||
type: bool | ||
required: false | ||
default: true | ||
wait_timeout: | ||
description: | ||
- Maximum time, in seconds, to wait for the Transit Gateway attachment | ||
to reach the expected state. | ||
- Defaults to 600 seconds. | ||
type: int | ||
required: false | ||
author: "Mark Chappell (@tremble)" | ||
extends_documentation_fragment: | ||
- amazon.aws.aws | ||
- amazon.aws.ec2 | ||
''' | ||
|
||
EXAMPLES = ''' | ||
# Create a Transit Gateway attachment | ||
- community.aws.ec2_transit_gateway_vpc_attachment: | ||
state: present | ||
transit_gateway: 'tgw-123456789abcdef01' | ||
name: AnsibleTest-1 | ||
subnets: | ||
- subnet-00000000000000000 | ||
- subnet-11111111111111111 | ||
- subnet-22222222222222222 | ||
ipv6_support: True | ||
purge_subnets: True | ||
dns_support: True | ||
appliance_mode_support: True | ||
tags: | ||
TestTag: changed data in Test Tag | ||
# Set sub options on a Transit Gateway attachment | ||
- community.aws.ec2_transit_gateway_vpc_attachment: | ||
state: present | ||
id: 'tgw-attach-0c0c5fd0b0f01d1c9' | ||
name: AnsibleTest-1 | ||
ipv6_support: True | ||
purge_subnets: False | ||
dns_support: False | ||
appliance_mode_support: True | ||
# Delete the transit gateway | ||
- community.aws.ec2_transit_gateway_vpc_attachment: | ||
state: absent | ||
id: 'tgw-attach-0c0c5fd0b0f01d1c9' | ||
''' | ||
|
||
RETURN = ''' | ||
transit_gateway_attachments: | ||
description: The attributes of the Transit Gateway attachments. | ||
type: list | ||
elements: dict | ||
returned: success | ||
contains: | ||
creation_time: | ||
description: | ||
- An ISO 8601 date time stamp of when the attachment was created. | ||
type: str | ||
returned: success | ||
example: '2022-03-10T16:40:26+00:00' | ||
options: | ||
description: | ||
- Additional VPC attachment options. | ||
type: dict | ||
returned: success | ||
contains: | ||
appliance_mode_support: | ||
description: | ||
- Indicates whether appliance mode support is enabled. | ||
type: str | ||
returned: success | ||
example: 'enable' | ||
dns_support: | ||
description: | ||
- Indicates whether DNS support is enabled. | ||
type: str | ||
returned: success | ||
example: 'disable' | ||
ipv6_support: | ||
description: | ||
- Indicates whether IPv6 support is disabled. | ||
type: str | ||
returned: success | ||
example: 'disable' | ||
state: | ||
description: | ||
- The state of the attachment. | ||
type: str | ||
returned: success | ||
example: 'deleting' | ||
subnet_ids: | ||
description: | ||
- The IDs of the subnets in use by the attachment. | ||
type: list | ||
elements: str | ||
returned: success | ||
example: ['subnet-0123456789abcdef0', 'subnet-11111111111111111'] | ||
tags: | ||
description: | ||
- A dictionary representing the resource tags. | ||
type: dict | ||
returned: success | ||
transit_gateway_attachment_id: | ||
description: | ||
- The ID of the attachment. | ||
type: str | ||
returned: success | ||
example: 'tgw-attach-0c0c5fd0b0f01d1c9' | ||
transit_gateway_id: | ||
description: | ||
- The ID of the transit gateway that the attachment is connected to. | ||
type: str | ||
returned: success | ||
example: 'tgw-0123456789abcdef0' | ||
vpc_id: | ||
description: | ||
- The ID of the VPC that the attachment is connected to. | ||
type: str | ||
returned: success | ||
example: 'vpc-0123456789abcdef0' | ||
vpc_owner_id: | ||
description: | ||
- The ID of the account that the VPC belongs to. | ||
type: str | ||
returned: success | ||
example: '012345678901' | ||
''' | ||
|
||
|
||
from ansible_collections.amazon.aws.plugins.module_utils.core import AnsibleAWSModule | ||
|
||
from ansible_collections.community.aws.plugins.module_utils.transitgateway import TransitGatewayVpcAttachmentManager | ||
|
||
|
||
def main(): | ||
|
||
argument_spec = dict( | ||
state=dict(type='str', required=False, default='present', choices=['absent', 'present']), | ||
transit_gateway=dict(type='str', required=False, aliases=['transit_gateway_id']), | ||
id=dict(type='str', required=False, aliases=['attachment_id']), | ||
name=dict(type='str', required=False), | ||
subnets=dict(type='list', elements='str', required=False), | ||
purge_subnets=dict(type='bool', required=False, default=True), | ||
tags=dict(type='dict', required=False), | ||
purge_tags=dict(type='bool', required=False, default=True), | ||
appliance_mode_support=dict(type='bool', required=False), | ||
dns_support=dict(type='bool', required=False), | ||
ipv6_support=dict(type='bool', required=False), | ||
wait=dict(type='bool', required=False, default=True), | ||
wait_timeout=dict(type='int', required=False), | ||
) | ||
|
||
one_of = [ | ||
['id', 'transit_gateway', 'name'], | ||
] | ||
|
||
module = AnsibleAWSModule( | ||
argument_spec=argument_spec, | ||
supports_check_mode=True, | ||
required_one_of=one_of, | ||
) | ||
|
||
attach_id = module.params.get('id', None) | ||
tgw = module.params.get('transit_gateway', None) | ||
name = module.params.get('name', None) | ||
tags = module.params.get('tags', None) | ||
purge_tags = module.params.get('purge_tags') | ||
state = module.params.get('state') | ||
subnets = module.params.get('subnets', None) | ||
purge_subnets = module.params.get('purge_subnets') | ||
|
||
# When not provided with an ID see if one exists. | ||
if not attach_id: | ||
search_manager = TransitGatewayVpcAttachmentManager(module=module) | ||
filters = dict() | ||
if tgw: | ||
filters['transit-gateway-id'] = tgw | ||
if name: | ||
filters['tag:Name'] = name | ||
if subnets: | ||
vpc_id = search_manager.subnets_to_vpc(subnets) | ||
filters['vpc-id'] = vpc_id | ||
|
||
# Attachments lurk in a 'deleted' state, for a while, ignore them so we | ||
# can reuse the names | ||
filters['state'] = [ | ||
'available', 'deleting', 'failed', 'failing', 'initiatingRequest', 'modifying', | ||
'pendingAcceptance', 'pending', 'rollingBack', 'rejected', 'rejecting' | ||
] | ||
attachments = search_manager.list(filters=filters) | ||
if len(attachments) > 1: | ||
module.fail_json('Multiple matching attachments found, provide an ID', attachments=attachments) | ||
# If we find a match then we'll modify it by ID, otherwise we'll be | ||
# creating a new RTB. | ||
if attachments: | ||
attach_id = attachments[0]['transit_gateway_attachment_id'] | ||
|
||
manager = TransitGatewayVpcAttachmentManager(module=module, id=attach_id) | ||
manager.set_wait(module.params.get('wait', None)) | ||
manager.set_wait_timeout(module.params.get('wait_timeout', None)) | ||
|
||
if state == 'absent': | ||
manager.delete() | ||
else: | ||
if not attach_id: | ||
if not tgw: | ||
module.fail_json('No existing attachment found. To create a new attachment' | ||
' the `transit_gateway` parameter must be provided.') | ||
if not subnets: | ||
module.fail_json('No existing attachment found. To create a new attachment' | ||
' the `subnets` parameter must be provided.') | ||
|
||
# name is just a special case of tags. | ||
if name: | ||
new_tags = dict(Name=name) | ||
if tags is None: | ||
purge_tags = False | ||
else: | ||
new_tags.update(tags) | ||
tags = new_tags | ||
|
||
manager.set_transit_gateway(tgw) | ||
manager.set_subnets(subnets, purge_subnets) | ||
manager.set_tags(tags, purge_tags) | ||
manager.set_dns_support(module.params.get('dns_support', None)) | ||
manager.set_ipv6_support(module.params.get('ipv6_support', None)) | ||
manager.set_appliance_mode_support(module.params.get('appliance_mode_support', None)) | ||
manager.flush_changes() | ||
|
||
results = dict( | ||
changed=manager.changed, | ||
attachments=[manager.updated_resource], | ||
) | ||
if manager.changed: | ||
results['diff'] = dict( | ||
before=manager.original_resource, | ||
after=manager.updated_resource, | ||
) | ||
|
||
module.exit_json(**results) | ||
|
||
|
||
if __name__ == '__main__': | ||
main() |
Oops, something went wrong.