From 85148d55e9203c7090d17e418cd97d4761a1fca5 Mon Sep 17 00:00:00 2001 From: jillr Date: Mon, 2 Mar 2020 19:25:18 +0000 Subject: [PATCH 01/34] Initial commit This commit was initially merged in https://github.com/ansible-collections/community.aws See: https://github.com/ansible-collections/community.aws/commit/eb75681585a23ea79e642b86a0f8e64e0f40a6d7 --- plugins/modules/ec2_vpc_nacl.py | 633 ++++++++++++++++++ plugins/modules/ec2_vpc_nacl_info.py | 222 ++++++ .../integration/targets/ec2_vpc_nacl/aliases | 3 + .../targets/ec2_vpc_nacl/meta/main.yml | 3 + .../ec2_vpc_nacl/tasks/ingress_and_egress.yml | 162 +++++ .../targets/ec2_vpc_nacl/tasks/ipv6.yml | 178 +++++ .../targets/ec2_vpc_nacl/tasks/main.yml | 170 +++++ .../targets/ec2_vpc_nacl/tasks/subnet_ids.yml | 174 +++++ .../ec2_vpc_nacl/tasks/subnet_names.yml | 140 ++++ .../targets/ec2_vpc_nacl/tasks/tags.yml | 117 ++++ 10 files changed, 1802 insertions(+) create mode 100644 plugins/modules/ec2_vpc_nacl.py create mode 100644 plugins/modules/ec2_vpc_nacl_info.py create mode 100644 tests/integration/targets/ec2_vpc_nacl/aliases create mode 100644 tests/integration/targets/ec2_vpc_nacl/meta/main.yml create mode 100644 tests/integration/targets/ec2_vpc_nacl/tasks/ingress_and_egress.yml create mode 100644 tests/integration/targets/ec2_vpc_nacl/tasks/ipv6.yml create mode 100644 tests/integration/targets/ec2_vpc_nacl/tasks/main.yml create mode 100644 tests/integration/targets/ec2_vpc_nacl/tasks/subnet_ids.yml create mode 100644 tests/integration/targets/ec2_vpc_nacl/tasks/subnet_names.yml create mode 100644 tests/integration/targets/ec2_vpc_nacl/tasks/tags.yml diff --git a/plugins/modules/ec2_vpc_nacl.py b/plugins/modules/ec2_vpc_nacl.py new file mode 100644 index 00000000000..f7c8be76b44 --- /dev/null +++ b/plugins/modules/ec2_vpc_nacl.py @@ -0,0 +1,633 @@ +#!/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 + + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['stableinterface'], + 'supported_by': 'community'} + + +DOCUMENTATION = ''' +module: ec2_vpc_nacl +short_description: create and delete Network ACLs. +description: + - Read the AWS documentation for Network ACLS + U(https://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_ACLs.html) +options: + name: + description: + - Tagged name identifying a network ACL. + - One and only one of the I(name) or I(nacl_id) is required. + required: false + type: str + nacl_id: + description: + - NACL id identifying a network ACL. + - One and only one of the I(name) or I(nacl_id) is required. + required: false + type: str + vpc_id: + description: + - VPC id of the requesting VPC. + - Required when state present. + required: false + type: str + subnets: + description: + - The list of subnets that should be associated with the network ACL. + - Must be specified as a list + - Each subnet can be specified as subnet ID, or its tagged name. + required: false + type: list + egress: + description: + - A list of rules for outgoing traffic. Each rule must be specified as a list. + Each rule may contain the rule number (integer 1-32766), protocol (one of ['tcp', 'udp', 'icmp', '-1', 'all']), + the rule action ('allow' or 'deny') the CIDR of the IPv4 network range to allow or deny, + the ICMP type (-1 means all types), the ICMP code (-1 means all codes), the last port in the range for + TCP or UDP protocols, and the first port in the range for TCP or UDP protocols. + See examples. + default: [] + required: false + type: list + ingress: + description: + - List of rules for incoming traffic. Each rule must be specified as a list. + Each rule may contain the rule number (integer 1-32766), protocol (one of ['tcp', 'udp', 'icmp', '-1', 'all']), + the rule action ('allow' or 'deny') the CIDR of the IPv4 network range to allow or deny, + the ICMP type (-1 means all types), the ICMP code (-1 means all codes), the last port in the range for + TCP or UDP protocols, and the first port in the range for TCP or UDP protocols. + See examples. + default: [] + required: false + type: list + tags: + description: + - Dictionary of tags to look for and apply when creating a network ACL. + required: false + type: dict + state: + description: + - Creates or modifies an existing NACL + - Deletes a NACL and reassociates subnets to the default NACL + required: false + type: str + choices: ['present', 'absent'] + default: present +author: Mike Mochan (@mmochan) +extends_documentation_fragment: +- ansible.amazon.aws +- ansible.amazon.ec2 + +requirements: [ botocore, boto3, json ] +''' + +EXAMPLES = ''' + +# Complete example to create and delete a network ACL +# that allows SSH, HTTP and ICMP in, and all traffic out. +- name: "Create and associate production DMZ network ACL with DMZ subnets" + ec2_vpc_nacl: + vpc_id: vpc-12345678 + name: prod-dmz-nacl + region: ap-southeast-2 + subnets: ['prod-dmz-1', 'prod-dmz-2'] + tags: + CostCode: CC1234 + Project: phoenix + Description: production DMZ + ingress: + # rule no, protocol, allow/deny, cidr, icmp_type, icmp_code, + # port from, port to + - [100, 'tcp', 'allow', '0.0.0.0/0', null, null, 22, 22] + - [200, 'tcp', 'allow', '0.0.0.0/0', null, null, 80, 80] + - [300, 'icmp', 'allow', '0.0.0.0/0', 0, 8] + egress: + - [100, 'all', 'allow', '0.0.0.0/0', null, null, null, null] + state: 'present' + +- name: "Remove the ingress and egress rules - defaults to deny all" + ec2_vpc_nacl: + vpc_id: vpc-12345678 + name: prod-dmz-nacl + region: ap-southeast-2 + subnets: + - prod-dmz-1 + - prod-dmz-2 + tags: + CostCode: CC1234 + Project: phoenix + Description: production DMZ + state: present + +- name: "Remove the NACL subnet associations and tags" + ec2_vpc_nacl: + vpc_id: 'vpc-12345678' + name: prod-dmz-nacl + region: ap-southeast-2 + state: present + +- name: "Delete nacl and subnet associations" + ec2_vpc_nacl: + vpc_id: vpc-12345678 + name: prod-dmz-nacl + state: absent + +- name: "Delete nacl by its id" + ec2_vpc_nacl: + nacl_id: acl-33b4ee5b + state: absent +''' +RETURN = ''' +task: + description: The result of the create, or delete action. + returned: success + type: dict +nacl_id: + description: The id of the NACL (when creating or updating an ACL) + returned: success + type: str + sample: acl-123456789abcdef01 +''' + +try: + import botocore +except ImportError: + pass # Handled by AnsibleAWSModule + +from ansible_collections.ansible.amazon.plugins.module_utils.aws.core import AnsibleAWSModule +from ansible_collections.ansible.amazon.plugins.module_utils.ec2 import AWSRetry + +# VPC-supported IANA protocol numbers +# http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml +PROTOCOL_NUMBERS = {'all': -1, 'icmp': 1, 'tcp': 6, 'udp': 17, } + + +# Utility methods +def icmp_present(entry): + if len(entry) == 6 and entry[1] == 'icmp' or entry[1] == 1: + return True + + +def load_tags(module): + tags = [] + if module.params.get('tags'): + for name, value in module.params.get('tags').items(): + tags.append({'Key': name, 'Value': str(value)}) + tags.append({'Key': "Name", 'Value': module.params.get('name')}) + else: + tags.append({'Key': "Name", 'Value': module.params.get('name')}) + return tags + + +def subnets_removed(nacl_id, subnets, client, module): + results = find_acl_by_id(nacl_id, client, module) + associations = results['NetworkAcls'][0]['Associations'] + subnet_ids = [assoc['SubnetId'] for assoc in associations] + return [subnet for subnet in subnet_ids if subnet not in subnets] + + +def subnets_added(nacl_id, subnets, client, module): + results = find_acl_by_id(nacl_id, client, module) + associations = results['NetworkAcls'][0]['Associations'] + subnet_ids = [assoc['SubnetId'] for assoc in associations] + return [subnet for subnet in subnets if subnet not in subnet_ids] + + +def subnets_changed(nacl, client, module): + changed = False + vpc_id = module.params.get('vpc_id') + nacl_id = nacl['NetworkAcls'][0]['NetworkAclId'] + subnets = subnets_to_associate(nacl, client, module) + if not subnets: + default_nacl_id = find_default_vpc_nacl(vpc_id, client, module)[0] + subnets = find_subnet_ids_by_nacl_id(nacl_id, client, module) + if subnets: + replace_network_acl_association(default_nacl_id, subnets, client, module) + changed = True + return changed + changed = False + return changed + subs_added = subnets_added(nacl_id, subnets, client, module) + if subs_added: + replace_network_acl_association(nacl_id, subs_added, client, module) + changed = True + subs_removed = subnets_removed(nacl_id, subnets, client, module) + if subs_removed: + default_nacl_id = find_default_vpc_nacl(vpc_id, client, module)[0] + replace_network_acl_association(default_nacl_id, subs_removed, client, module) + changed = True + return changed + + +def nacls_changed(nacl, client, module): + changed = False + params = dict() + params['egress'] = module.params.get('egress') + params['ingress'] = module.params.get('ingress') + + nacl_id = nacl['NetworkAcls'][0]['NetworkAclId'] + nacl = describe_network_acl(client, module) + entries = nacl['NetworkAcls'][0]['Entries'] + egress = [rule for rule in entries if rule['Egress'] is True and rule['RuleNumber'] < 32767] + ingress = [rule for rule in entries if rule['Egress'] is False and rule['RuleNumber'] < 32767] + if rules_changed(egress, params['egress'], True, nacl_id, client, module): + changed = True + if rules_changed(ingress, params['ingress'], False, nacl_id, client, module): + changed = True + return changed + + +def tags_changed(nacl_id, client, module): + changed = False + tags = dict() + if module.params.get('tags'): + tags = module.params.get('tags') + if module.params.get('name') and not tags.get('Name'): + tags['Name'] = module.params['name'] + nacl = find_acl_by_id(nacl_id, client, module) + if nacl['NetworkAcls']: + nacl_values = [t.values() for t in nacl['NetworkAcls'][0]['Tags']] + nacl_tags = [item for sublist in nacl_values for item in sublist] + tag_values = [[key, str(value)] for key, value in tags.items()] + tags = [item for sublist in tag_values for item in sublist] + if sorted(nacl_tags) == sorted(tags): + changed = False + return changed + else: + delete_tags(nacl_id, client, module) + create_tags(nacl_id, client, module) + changed = True + return changed + return changed + + +def rules_changed(aws_rules, param_rules, Egress, nacl_id, client, module): + changed = False + rules = list() + for entry in param_rules: + rules.append(process_rule_entry(entry, Egress)) + if rules == aws_rules: + return changed + else: + removed_rules = [x for x in aws_rules if x not in rules] + if removed_rules: + params = dict() + for rule in removed_rules: + params['NetworkAclId'] = nacl_id + params['RuleNumber'] = rule['RuleNumber'] + params['Egress'] = Egress + delete_network_acl_entry(params, client, module) + changed = True + added_rules = [x for x in rules if x not in aws_rules] + if added_rules: + for rule in added_rules: + rule['NetworkAclId'] = nacl_id + create_network_acl_entry(rule, client, module) + changed = True + return changed + + +def process_rule_entry(entry, Egress): + params = dict() + params['RuleNumber'] = entry[0] + params['Protocol'] = str(PROTOCOL_NUMBERS[entry[1]]) + params['RuleAction'] = entry[2] + params['Egress'] = Egress + params['CidrBlock'] = entry[3] + if icmp_present(entry): + params['IcmpTypeCode'] = {"Type": int(entry[4]), "Code": int(entry[5])} + else: + if entry[6] or entry[7]: + params['PortRange'] = {"From": entry[6], 'To': entry[7]} + return params + + +def restore_default_associations(assoc_ids, default_nacl_id, client, module): + if assoc_ids: + params = dict() + params['NetworkAclId'] = default_nacl_id[0] + for assoc_id in assoc_ids: + params['AssociationId'] = assoc_id + restore_default_acl_association(params, client, module) + return True + + +def construct_acl_entries(nacl, client, module): + for entry in module.params.get('ingress'): + params = process_rule_entry(entry, Egress=False) + params['NetworkAclId'] = nacl['NetworkAcl']['NetworkAclId'] + create_network_acl_entry(params, client, module) + for rule in module.params.get('egress'): + params = process_rule_entry(rule, Egress=True) + params['NetworkAclId'] = nacl['NetworkAcl']['NetworkAclId'] + create_network_acl_entry(params, client, module) + + +# Module invocations +def setup_network_acl(client, module): + changed = False + nacl = describe_network_acl(client, module) + if not nacl['NetworkAcls']: + nacl = create_network_acl(module.params.get('vpc_id'), client, module) + nacl_id = nacl['NetworkAcl']['NetworkAclId'] + create_tags(nacl_id, client, module) + subnets = subnets_to_associate(nacl, client, module) + replace_network_acl_association(nacl_id, subnets, client, module) + construct_acl_entries(nacl, client, module) + changed = True + return(changed, nacl['NetworkAcl']['NetworkAclId']) + else: + changed = False + nacl_id = nacl['NetworkAcls'][0]['NetworkAclId'] + changed |= subnets_changed(nacl, client, module) + changed |= nacls_changed(nacl, client, module) + changed |= tags_changed(nacl_id, client, module) + return (changed, nacl_id) + + +def remove_network_acl(client, module): + changed = False + result = dict() + nacl = describe_network_acl(client, module) + if nacl['NetworkAcls']: + nacl_id = nacl['NetworkAcls'][0]['NetworkAclId'] + vpc_id = nacl['NetworkAcls'][0]['VpcId'] + associations = nacl['NetworkAcls'][0]['Associations'] + assoc_ids = [a['NetworkAclAssociationId'] for a in associations] + default_nacl_id = find_default_vpc_nacl(vpc_id, client, module) + if not default_nacl_id: + result = {vpc_id: "Default NACL ID not found - Check the VPC ID"} + return changed, result + if restore_default_associations(assoc_ids, default_nacl_id, client, module): + delete_network_acl(nacl_id, client, module) + changed = True + result[nacl_id] = "Successfully deleted" + return changed, result + if not assoc_ids: + delete_network_acl(nacl_id, client, module) + changed = True + result[nacl_id] = "Successfully deleted" + return changed, result + return changed, result + + +# Boto3 client methods +@AWSRetry.jittered_backoff() +def _create_network_acl(client, *args, **kwargs): + return client.create_network_acl(*args, **kwargs) + + +def create_network_acl(vpc_id, client, module): + try: + if module.check_mode: + nacl = dict(NetworkAcl=dict(NetworkAclId="nacl-00000000")) + else: + nacl = _create_network_acl(client, VpcId=vpc_id) + except botocore.exceptions.ClientError as e: + module.fail_json_aws(e) + return nacl + + +@AWSRetry.jittered_backoff(catch_extra_error_codes=['InvalidNetworkAclID.NotFound']) +def _create_network_acl_entry(client, *args, **kwargs): + return client.create_network_acl_entry(*args, **kwargs) + + +def create_network_acl_entry(params, client, module): + try: + if not module.check_mode: + _create_network_acl_entry(client, **params) + except botocore.exceptions.ClientError as e: + module.fail_json_aws(e) + + +@AWSRetry.jittered_backoff(catch_extra_error_codes=['InvalidNetworkAclID.NotFound']) +def _create_tags(client, *args, **kwargs): + return client.create_tags(*args, **kwargs) + + +def create_tags(nacl_id, client, module): + try: + delete_tags(nacl_id, client, module) + if not module.check_mode: + _create_tags(client, Resources=[nacl_id], Tags=load_tags(module)) + except botocore.exceptions.ClientError as e: + module.fail_json_aws(e) + + +@AWSRetry.jittered_backoff() +def _delete_network_acl(client, *args, **kwargs): + return client.delete_network_acl(*args, **kwargs) + + +def delete_network_acl(nacl_id, client, module): + try: + if not module.check_mode: + _delete_network_acl(client, NetworkAclId=nacl_id) + except botocore.exceptions.ClientError as e: + module.fail_json_aws(e) + + +@AWSRetry.jittered_backoff(catch_extra_error_codes=['InvalidNetworkAclID.NotFound']) +def _delete_network_acl_entry(client, *args, **kwargs): + return client.delete_network_acl_entry(*args, **kwargs) + + +def delete_network_acl_entry(params, client, module): + try: + if not module.check_mode: + _delete_network_acl_entry(client, **params) + except botocore.exceptions.ClientError as e: + module.fail_json_aws(e) + + +@AWSRetry.jittered_backoff(catch_extra_error_codes=['InvalidNetworkAclID.NotFound']) +def _delete_tags(client, *args, **kwargs): + return client.delete_tags(*args, **kwargs) + + +def delete_tags(nacl_id, client, module): + try: + if not module.check_mode: + _delete_tags(client, Resources=[nacl_id]) + except botocore.exceptions.ClientError as e: + module.fail_json_aws(e) + + +@AWSRetry.jittered_backoff() +def _describe_network_acls(client, **kwargs): + return client.describe_network_acls(**kwargs) + + +@AWSRetry.jittered_backoff(catch_extra_error_codes=['InvalidNetworkAclID.NotFound']) +def _describe_network_acls_retry_missing(client, **kwargs): + return client.describe_network_acls(**kwargs) + + +def describe_acl_associations(subnets, client, module): + if not subnets: + return [] + try: + results = _describe_network_acls_retry_missing(client, Filters=[ + {'Name': 'association.subnet-id', 'Values': subnets} + ]) + except botocore.exceptions.ClientError as e: + module.fail_json_aws(e) + associations = results['NetworkAcls'][0]['Associations'] + return [a['NetworkAclAssociationId'] for a in associations if a['SubnetId'] in subnets] + + +def describe_network_acl(client, module): + try: + if module.params.get('nacl_id'): + nacl = _describe_network_acls(client, Filters=[ + {'Name': 'network-acl-id', 'Values': [module.params.get('nacl_id')]} + ]) + else: + nacl = _describe_network_acls(client, Filters=[ + {'Name': 'tag:Name', 'Values': [module.params.get('name')]} + ]) + except botocore.exceptions.ClientError as e: + module.fail_json_aws(e) + return nacl + + +def find_acl_by_id(nacl_id, client, module): + try: + return _describe_network_acls_retry_missing(client, NetworkAclIds=[nacl_id]) + except botocore.exceptions.ClientError as e: + module.fail_json_aws(e) + + +def find_default_vpc_nacl(vpc_id, client, module): + try: + response = _describe_network_acls_retry_missing(client, Filters=[ + {'Name': 'vpc-id', 'Values': [vpc_id]}]) + except botocore.exceptions.ClientError as e: + module.fail_json_aws(e) + nacls = response['NetworkAcls'] + return [n['NetworkAclId'] for n in nacls if n['IsDefault'] is True] + + +def find_subnet_ids_by_nacl_id(nacl_id, client, module): + try: + results = _describe_network_acls_retry_missing(client, Filters=[ + {'Name': 'association.network-acl-id', 'Values': [nacl_id]} + ]) + except botocore.exceptions.ClientError as e: + module.fail_json_aws(e) + if results['NetworkAcls']: + associations = results['NetworkAcls'][0]['Associations'] + return [s['SubnetId'] for s in associations if s['SubnetId']] + else: + return [] + + +@AWSRetry.jittered_backoff(catch_extra_error_codes=['InvalidNetworkAclID.NotFound']) +def _replace_network_acl_association(client, *args, **kwargs): + return client.replace_network_acl_association(*args, **kwargs) + + +def replace_network_acl_association(nacl_id, subnets, client, module): + params = dict() + params['NetworkAclId'] = nacl_id + for association in describe_acl_associations(subnets, client, module): + params['AssociationId'] = association + try: + if not module.check_mode: + _replace_network_acl_association(client, **params) + except botocore.exceptions.ClientError as e: + module.fail_json_aws(e) + + +@AWSRetry.jittered_backoff(catch_extra_error_codes=['InvalidNetworkAclID.NotFound']) +def _replace_network_acl_entry(client, *args, **kwargs): + return client.replace_network_acl_entry(*args, **kwargs) + + +def replace_network_acl_entry(entries, Egress, nacl_id, client, module): + for entry in entries: + params = entry + params['NetworkAclId'] = nacl_id + try: + if not module.check_mode: + _replace_network_acl_entry(client, **params) + except botocore.exceptions.ClientError as e: + module.fail_json_aws(e) + + +@AWSRetry.jittered_backoff(catch_extra_error_codes=['InvalidNetworkAclID.NotFound']) +def _replace_network_acl_association(client, *args, **kwargs): + return client.replace_network_acl_association(*args, **kwargs) + + +def restore_default_acl_association(params, client, module): + try: + if not module.check_mode: + _replace_network_acl_association(client, **params) + except botocore.exceptions.ClientError as e: + module.fail_json_aws(e) + + +@AWSRetry.jittered_backoff() +def _describe_subnets(client, *args, **kwargs): + return client.describe_subnets(*args, **kwargs) + + +def subnets_to_associate(nacl, client, module): + params = list(module.params.get('subnets')) + if not params: + return [] + all_found = [] + if any(x.startswith("subnet-") for x in params): + try: + subnets = _describe_subnets(client, Filters=[ + {'Name': 'subnet-id', 'Values': params}]) + all_found.extend(subnets.get('Subnets', [])) + except botocore.exceptions.ClientError as e: + module.fail_json_aws(e) + if len(params) != len(all_found): + try: + subnets = _describe_subnets(client, Filters=[ + {'Name': 'tag:Name', 'Values': params}]) + all_found.extend(subnets.get('Subnets', [])) + except botocore.exceptions.ClientError as e: + module.fail_json_aws(e) + return list(set(s['SubnetId'] for s in all_found if s.get('SubnetId'))) + + +def main(): + argument_spec = dict( + vpc_id=dict(), + name=dict(), + nacl_id=dict(), + subnets=dict(required=False, type='list', default=list()), + tags=dict(required=False, type='dict'), + ingress=dict(required=False, type='list', default=list()), + egress=dict(required=False, type='list', default=list()), + state=dict(default='present', choices=['present', 'absent']), + ) + module = AnsibleAWSModule(argument_spec=argument_spec, + supports_check_mode=True, + required_one_of=[['name', 'nacl_id']], + required_if=[['state', 'present', ['vpc_id']]]) + + state = module.params.get('state').lower() + + client = module.client('ec2') + + invocations = { + "present": setup_network_acl, + "absent": remove_network_acl + } + (changed, results) = invocations[state](client, module) + module.exit_json(changed=changed, nacl_id=results) + + +if __name__ == '__main__': + main() diff --git a/plugins/modules/ec2_vpc_nacl_info.py b/plugins/modules/ec2_vpc_nacl_info.py new file mode 100644 index 00000000000..9db13f104d2 --- /dev/null +++ b/plugins/modules/ec2_vpc_nacl_info.py @@ -0,0 +1,222 @@ +#!/usr/bin/python +# 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 + + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['stableinterface'], + 'supported_by': 'community'} + + +DOCUMENTATION = ''' +--- +module: ec2_vpc_nacl_info +short_description: Gather information about Network ACLs in an AWS VPC +description: + - Gather information about Network ACLs in an AWS VPC + - This module was called C(ec2_vpc_nacl_facts) before Ansible 2.9. The usage did not change. +author: "Brad Davidson (@brandond)" +requirements: [ boto3 ] +options: + nacl_ids: + description: + - A list of Network ACL IDs to retrieve information about. + required: false + default: [] + aliases: [nacl_id] + type: list + filters: + description: + - A dict of filters to apply. Each dict item consists of a filter key and a filter value. See + U(https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeNetworkAcls.html) for possible filters. Filter + names and values are case sensitive. + required: false + default: {} + type: dict +notes: + - By default, the module will return all Network ACLs. + +extends_documentation_fragment: +- ansible.amazon.aws +- ansible.amazon.ec2 + +''' + +EXAMPLES = ''' +# Note: These examples do not set authentication details, see the AWS Guide for details. + +# Gather information about all Network ACLs: +- name: Get All NACLs + register: all_nacls + ec2_vpc_nacl_info: + region: us-west-2 + +# Retrieve default Network ACLs: +- name: Get Default NACLs + register: default_nacls + ec2_vpc_nacl_info: + region: us-west-2 + filters: + 'default': 'true' +''' + +RETURN = ''' +nacls: + description: Returns an array of complex objects as described below. + returned: success + type: complex + contains: + nacl_id: + description: The ID of the Network Access Control List. + returned: always + type: str + vpc_id: + description: The ID of the VPC that the NACL is attached to. + returned: always + type: str + is_default: + description: True if the NACL is the default for its VPC. + returned: always + type: bool + tags: + description: A dict of tags associated with the NACL. + returned: always + type: dict + subnets: + description: A list of subnet IDs that are associated with the NACL. + returned: always + type: list + elements: str + ingress: + description: + - A list of NACL ingress rules with the following format. + - "C([rule no, protocol, allow/deny, v4 or v6 cidr, icmp_type, icmp_code, port from, port to])" + returned: always + type: list + elements: list + sample: [[100, 'tcp', 'allow', '0.0.0.0/0', null, null, 22, 22]] + egress: + description: + - A list of NACL egress rules with the following format. + - "C([rule no, protocol, allow/deny, v4 or v6 cidr, icmp_type, icmp_code, port from, port to])" + returned: always + type: list + elements: list + sample: [[100, 'all', 'allow', '0.0.0.0/0', null, null, null, null]] +''' + +try: + from botocore.exceptions import ClientError, BotoCoreError +except ImportError: + pass # caught by AnsibleAWSModule + +from ansible_collections.ansible.amazon.plugins.module_utils.aws.core import AnsibleAWSModule +from ansible.module_utils._text import to_native +from ansible_collections.ansible.amazon.plugins.module_utils.ec2 import (AWSRetry, ansible_dict_to_boto3_filter_list, + camel_dict_to_snake_dict, boto3_tag_list_to_ansible_dict) + + +# VPC-supported IANA protocol numbers +# http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml +PROTOCOL_NAMES = {'-1': 'all', '1': 'icmp', '6': 'tcp', '17': 'udp'} + + +def list_ec2_vpc_nacls(connection, module): + + nacl_ids = module.params.get("nacl_ids") + filters = ansible_dict_to_boto3_filter_list(module.params.get("filters")) + + if nacl_ids is None: + nacl_ids = [] + + try: + nacls = connection.describe_network_acls(aws_retry=True, NetworkAclIds=nacl_ids, Filters=filters) + except ClientError as e: + if e.response['Error']['Code'] == 'InvalidNetworkAclID.NotFound': + module.fail_json(msg='Unable to describe ACL. NetworkAcl does not exist') + module.fail_json_aws(e, msg="Unable to describe network ACLs {0}".format(nacl_ids)) + except BotoCoreError as e: + module.fail_json_aws(e, msg="Unable to describe network ACLs {0}".format(nacl_ids)) + + # Turn the boto3 result in to ansible_friendly_snaked_names + snaked_nacls = [] + for nacl in nacls['NetworkAcls']: + snaked_nacls.append(camel_dict_to_snake_dict(nacl)) + + # Turn the boto3 result in to ansible friendly tag dictionary + for nacl in snaked_nacls: + if 'tags' in nacl: + nacl['tags'] = boto3_tag_list_to_ansible_dict(nacl['tags'], 'key', 'value') + if 'entries' in nacl: + nacl['egress'] = [nacl_entry_to_list(entry) for entry in nacl['entries'] + if entry['rule_number'] < 32767 and entry['egress']] + nacl['ingress'] = [nacl_entry_to_list(entry) for entry in nacl['entries'] + if entry['rule_number'] < 32767 and not entry['egress']] + del nacl['entries'] + if 'associations' in nacl: + nacl['subnets'] = [a['subnet_id'] for a in nacl['associations']] + del nacl['associations'] + if 'network_acl_id' in nacl: + nacl['nacl_id'] = nacl['network_acl_id'] + del nacl['network_acl_id'] + + module.exit_json(nacls=snaked_nacls) + + +def nacl_entry_to_list(entry): + + # entry list format + # [ rule_num, protocol name or number, allow or deny, ipv4/6 cidr, icmp type, icmp code, port from, port to] + elist = [] + + elist.append(entry['rule_number']) + + if entry.get('protocol') in PROTOCOL_NAMES: + elist.append(PROTOCOL_NAMES[entry['protocol']]) + else: + elist.append(entry.get('protocol')) + + elist.append(entry['rule_action']) + + if entry.get('cidr_block'): + elist.append(entry['cidr_block']) + elif entry.get('ipv6_cidr_block'): + elist.append(entry['ipv6_cidr_block']) + else: + elist.append(None) + + elist = elist + [None, None, None, None] + + if entry['protocol'] in ('1', '58'): + elist[4] = entry.get('icmp_type_code', {}).get('type') + elist[5] = entry.get('icmp_type_code', {}).get('code') + + if entry['protocol'] not in ('1', '6', '17', '58'): + elist[6] = 0 + elist[7] = 65535 + elif 'port_range' in entry: + elist[6] = entry['port_range']['from'] + elist[7] = entry['port_range']['to'] + + return elist + + +def main(): + + argument_spec = dict( + nacl_ids=dict(default=[], type='list', aliases=['nacl_id']), + filters=dict(default={}, type='dict')) + + module = AnsibleAWSModule(argument_spec=argument_spec, supports_check_mode=True) + if module._name == 'ec2_vpc_nacl_facts': + module.deprecate("The 'ec2_vpc_nacl_facts' module has been renamed to 'ec2_vpc_nacl_info'", version='2.13') + + connection = module.client('ec2', retry_decorator=AWSRetry.jittered_backoff()) + + list_ec2_vpc_nacls(connection, module) + + +if __name__ == '__main__': + main() diff --git a/tests/integration/targets/ec2_vpc_nacl/aliases b/tests/integration/targets/ec2_vpc_nacl/aliases new file mode 100644 index 00000000000..074f2ab60c1 --- /dev/null +++ b/tests/integration/targets/ec2_vpc_nacl/aliases @@ -0,0 +1,3 @@ +ec2_vpc_nacl_info +cloud/aws +shippable/aws/group2 diff --git a/tests/integration/targets/ec2_vpc_nacl/meta/main.yml b/tests/integration/targets/ec2_vpc_nacl/meta/main.yml new file mode 100644 index 00000000000..1f64f1169a9 --- /dev/null +++ b/tests/integration/targets/ec2_vpc_nacl/meta/main.yml @@ -0,0 +1,3 @@ +dependencies: + - prepare_tests + - setup_ec2 diff --git a/tests/integration/targets/ec2_vpc_nacl/tasks/ingress_and_egress.yml b/tests/integration/targets/ec2_vpc_nacl/tasks/ingress_and_egress.yml new file mode 100644 index 00000000000..4eb60791290 --- /dev/null +++ b/tests/integration/targets/ec2_vpc_nacl/tasks/ingress_and_egress.yml @@ -0,0 +1,162 @@ +# ============================================================ + +- name: create ingress and egress rules using subnet IDs + ec2_vpc_nacl: + vpc_id: "{{ vpc_id }}" + name: "{{ resource_prefix }}-acl" + subnets: "{{ subnet_ids }}" + tags: + Created_by: "Ansible test {{ resource_prefix }}" + ingress: + - [100, 'tcp', 'allow', '0.0.0.0/0', null, null, 22, 22] + - [200, 'tcp', 'allow', '0.0.0.0/0', null, null, 80, 80] + - [300, 'icmp', 'allow', '0.0.0.0/0', 0, 8] + egress: + - [100, 'all', 'allow', '0.0.0.0/0', null, null, null, null] + state: 'present' + register: nacl + +- name: assert the network acl was created + assert: + that: + - nacl.changed + - nacl.nacl_id.startswith('acl-') + +- name: get network ACL facts + ec2_vpc_nacl_info: + nacl_ids: + - "{{ nacl.nacl_id }}" + register: nacl_facts + +- name: assert the nacl has the correct attributes + assert: + that: + - nacl_facts.nacls | length == 1 + - nacl_facts.nacls[0].ingress | length == 3 + - nacl_facts.nacls[0].egress | length == 1 + +# ============================================================ + +- name: remove an ingress rule + ec2_vpc_nacl: + vpc_id: "{{ vpc_id }}" + name: "{{ resource_prefix }}-acl" + subnets: "{{ subnet_ids }}" + tags: + Created_by: "Ansible test {{ resource_prefix }}" + ingress: + - [100, 'tcp', 'allow', '0.0.0.0/0', null, null, 22, 22] + - [200, 'tcp', 'allow', '0.0.0.0/0', null, null, 80, 80] + egress: + - [100, 'all', 'allow', '0.0.0.0/0', null, null, null, null] + state: 'present' + register: nacl + +- name: assert the network acl changed + assert: + that: + - nacl.changed + - nacl.nacl_id.startswith('acl-') + +- name: get network ACL facts + ec2_vpc_nacl_info: + nacl_ids: + - "{{ nacl.nacl_id }}" + register: nacl_facts + +- name: assert the nacl has the correct attributes + assert: + that: + - nacl_facts.nacls | length == 1 + - nacl_facts.nacls[0].ingress | length == 2 + - nacl_facts.nacls[0].egress | length == 1 + +# ============================================================ + +- name: remove the egress rule + ec2_vpc_nacl: + vpc_id: "{{ vpc_id }}" + name: "{{ resource_prefix }}-acl" + subnets: "{{ subnet_ids }}" + tags: + Created_by: "Ansible test {{ resource_prefix }}" + ingress: + - [100, 'tcp', 'allow', '0.0.0.0/0', null, null, 22, 22] + - [200, 'tcp', 'allow', '0.0.0.0/0', null, null, 80, 80] + egress: [] + state: 'present' + register: nacl + +- name: assert the network acl changed + assert: + that: + - nacl.changed + - nacl.nacl_id.startswith('acl-') + +- name: get network ACL facts + ec2_vpc_nacl_info: + nacl_ids: + - "{{ nacl.nacl_id }}" + register: nacl_facts + +- name: assert the nacl has the correct attributes + assert: + that: + - nacl_facts.nacls | length == 1 + - nacl_facts.nacls[0].ingress | length == 2 + - nacl_facts.nacls[0].egress | length == 0 + +# ============================================================ + +- name: add egress rules + ec2_vpc_nacl: + vpc_id: "{{ vpc_id }}" + name: "{{ resource_prefix }}-acl" + subnets: "{{ subnet_ids }}" + tags: + Created_by: "Ansible test {{ resource_prefix }}" + ingress: + - [100, 'tcp', 'allow', '0.0.0.0/0', null, null, 22, 22] + - [200, 'tcp', 'allow', '0.0.0.0/0', null, null, 80, 80] + egress: + - [100, 'tcp', 'allow', '10.0.0.0/24', null, null, 22, 22] + - [200, 'udp', 'allow', '10.0.0.0/24', null, null, 22, 22] + state: 'present' + register: nacl + +- name: assert the network acl changed + assert: + that: + - nacl.changed + - nacl.nacl_id.startswith('acl-') + +- name: get network ACL facts + ec2_vpc_nacl_info: + nacl_ids: + - "{{ nacl.nacl_id }}" + register: nacl_facts + +- name: assert the nacl has the correct attributes + assert: + that: + - nacl_facts.nacls | length == 1 + - nacl_facts.nacls[0].ingress | length == 2 + - nacl_facts.nacls[0].egress | length == 2 + +# ============================================================ + +- name: remove the network ACL + ec2_vpc_nacl: + vpc_id: "{{ vpc_id }}" + name: "{{ resource_prefix }}-acl" + state: absent + register: nacl + until: nacl is success + ignore_errors: yes + retries: 5 + delay: 5 + +- name: assert nacl was removed + assert: + that: + - nacl.changed diff --git a/tests/integration/targets/ec2_vpc_nacl/tasks/ipv6.yml b/tests/integration/targets/ec2_vpc_nacl/tasks/ipv6.yml new file mode 100644 index 00000000000..16b3a5aaaff --- /dev/null +++ b/tests/integration/targets/ec2_vpc_nacl/tasks/ipv6.yml @@ -0,0 +1,178 @@ +- block: + - name: create a VPC + ec2_vpc_net: + cidr_block: 10.230.231.0/24 + name: "{{ resource_prefix }}-ipv6" + state: present + ipv6_cidr: yes + register: vpc_result + + - set_fact: + vpc_ipv6_cidr: "{{ vpc_result.vpc.ipv6_cidr_block_association_set[0].ipv6_cidr_block }}" + + # ============================================================ + - name: create subnet with IPv6 (expected changed=true) + ec2_vpc_subnet: + cidr: 10.230.231.0/26 + vpc_id: "{{ vpc_result.vpc.id }}" + ipv6_cidr: "{{ vpc_ipv6_cidr | regex_replace('::/56', '::/64') }}" + state: present + tags: + Name: "{{ resource_prefix }}-ipv6-subnet-1" + register: vpc_subnet_ipv6 + + - name: assert creation with IPv6 happened (expected changed=true) + assert: + that: + - "vpc_subnet_ipv6.subnet.ipv6_cidr_block == '{{ vpc_ipv6_cidr | regex_replace('::/56', '::/64') }}'" + + # ============================================================ + + - name: create ingress and egress rules using subnet names + ec2_vpc_nacl: + vpc_id: "{{ vpc_result.vpc.id }}" + name: "{{ resource_prefix }}-acl" + subnets: + - "{{ resource_prefix }}-ipv6-subnet-1" + tags: + Created_by: "Ansible test {{ resource_prefix }}" + ingress: + - [100, 'tcp', 'allow', '0.0.0.0/0', null, null, 22, 22] + - [200, 'tcp', 'allow', '0.0.0.0/0', null, null, 80, 80] + - [300, 'icmp', 'allow', '0.0.0.0/0', 0, 8] + egress: + - [100, 'all', 'allow', '0.0.0.0/0', null, null, null, null] + state: 'present' + register: nacl + - assert: + that: + - nacl.nacl_id + + - set_fact: + nacl_id: "{{ nacl.nacl_id }}" + + - name: add ipv6 entries + ec2_vpc_nacl: + vpc_id: "{{ vpc_result.vpc.id }}" + name: "{{ resource_prefix }}-acl" + subnets: + - "{{ resource_prefix }}-ipv6-subnet-1" + tags: + Created_by: "Ansible test {{ resource_prefix }}" + ingress: + - [100, 'tcp', 'allow', '0.0.0.0/0', null, null, 22, 22] + - [200, 'tcp', 'allow', '0.0.0.0/0', null, null, 80, 80] + - [205, 'ipv6-tcp', 'allow', '::/0', null, null, 80, 80] + - [300, 'icmp', 'allow', '0.0.0.0/0', 0, 8] + - [305, 'ipv6-icmp', 'allow', '::/0', 0, 8] + egress: + - [100, 'all', 'allow', '0.0.0.0/0', null, null, null, null] + - [105, 'all', 'allow', '::/0', null, null, null, null] + state: 'present' + register: nacl + # FIXME: Currently IPv6 rules are not supported - uncomment assertion when + # fixed (and add some nacl_info tests) + ignore_errors: yes + - name: get network ACL facts (test that it works with ipv6 entries) + ec2_vpc_nacl_info: + nacl_ids: + - "{{ nacl_id }}" + register: nacl_facts + + + #- assert: + # that: + # - nacl.changed + # - nacl.nacl_id == nacl_id + + - name: purge ingress entries + ec2_vpc_nacl: + vpc_id: "{{ vpc_result.vpc.id }}" + name: "{{ resource_prefix }}-acl" + subnets: + - "{{ resource_prefix }}-ipv6-subnet-1" + tags: + Created_by: "Ansible test {{ resource_prefix }}" + ingress: [] + egress: + - [100, 'all', 'allow', '0.0.0.0/0', null, null, null, null] + - [105, 'all', 'allow', '::/0', null, null, null, null] + state: 'present' + register: nacl + # FIXME: Currently IPv6 rules are not supported - uncomment assertion when + # fixed (and add some nacl_info tests) + ignore_errors: yes + + #- assert: + # that: + # - nacl.changed + # - nacl.nacl_id == nacl_id + + - name: purge egress entries + ec2_vpc_nacl: + vpc_id: "{{ vpc_result.vpc.id }}" + name: "{{ resource_prefix }}-acl" + subnets: + - "{{ resource_prefix }}-ipv6-subnet-1" + tags: + Created_by: "Ansible test {{ resource_prefix }}" + ingress: [] + egress: [] + state: 'present' + register: nacl + + - assert: + that: + - nacl.changed + + # ============================================================ + - name: remove subnet ipv6 cidr (expected changed=true) + ec2_vpc_subnet: + cidr: 10.230.231.0/26 + vpc_id: "{{ vpc_result.vpc.id }}" + state: absent + register: vpc_remove_ipv6_cidr + + - name: assert subnet ipv6 cidr removed (expected changed=true) + assert: + that: + - 'vpc_remove_ipv6_cidr.changed' + + always: + + ################################################ + # TEARDOWN STARTS HERE + ################################################ + + - name: remove network ACL + ec2_vpc_nacl: + vpc_id: "{{ vpc_result.vpc.id }}" + name: "{{ resource_prefix }}-acl" + state: absent + register: removed_acl + until: removed_acl is success + retries: 5 + delay: 5 + ignore_errors: yes + + - name: tidy up subnet + ec2_vpc_subnet: + cidr: 10.230.231.0/26 + vpc_id: "{{ vpc_result.vpc.id }}" + state: absent + register: removed_subnet + until: removed_subnet is success + retries: 5 + delay: 5 + ignore_errors: yes + + - name: tidy up VPC + ec2_vpc_net: + name: "{{ resource_prefix }}-ipv6" + state: absent + cidr_block: 10.230.231.0/24 + register: removed_vpc + until: removed_vpc is success + retries: 5 + delay: 5 + ignore_errors: yes diff --git a/tests/integration/targets/ec2_vpc_nacl/tasks/main.yml b/tests/integration/targets/ec2_vpc_nacl/tasks/main.yml new file mode 100644 index 00000000000..ad72530e290 --- /dev/null +++ b/tests/integration/targets/ec2_vpc_nacl/tasks/main.yml @@ -0,0 +1,170 @@ +--- +- module_defaults: + group/aws: + aws_access_key: "{{ aws_access_key }}" + aws_secret_key: "{{ aws_secret_key }}" + security_token: "{{ security_token | default(omit) }}" + region: "{{ aws_region }}" + block: + + # ============================================================ + + - name: test without any parameters + ec2_vpc_nacl: + register: result + ignore_errors: yes + + - name: assert required parameters + assert: + that: + - result.failed + - "result.msg == 'one of the following is required: name, nacl_id'" + + - name: get network ACL info without any parameters + ec2_vpc_nacl_info: + register: nacl_facts + + - name: assert we don't error + assert: + that: + - nacl_facts is succeeded + + - name: get network ACL info with invalid ID + ec2_vpc_nacl_info: + nacl_ids: + - 'acl-000000000000' + register: nacl_facts + ignore_errors: yes + + - name: assert message mentions missing ACLs + assert: + that: + - nacl_facts is failed + - '"does not exist" in nacl_facts.msg' + + # ============================================================ + + - name: fetch AZ availability + aws_az_info: + register: az_info + + - name: Assert that we have multiple AZs available to us + assert: + that: az_info.availability_zones | length >= 2 + + - name: pick AZs + set_fact: + az_one: '{{ az_info.availability_zones[0].zone_name }}' + az_two: '{{ az_info.availability_zones[1].zone_name }}' + + # ============================================================ + + - name: create a VPC + ec2_vpc_net: + cidr_block: 10.230.230.0/24 + name: "{{ resource_prefix }}" + state: present + register: vpc + + - name: create subnets + ec2_vpc_subnet: + cidr: "{{ item.cidr }}" + az: "{{ item.az }}" + vpc_id: "{{ vpc.vpc.id }}" + state: present + tags: + Name: "{{ item.name }}" + with_items: + - cidr: 10.230.230.0/26 + az: "{{ az_one }}" + name: "{{ resource_prefix }}-subnet-1" + - cidr: 10.230.230.64/26 + az: "{{ az_two }}" + name: "{{ resource_prefix }}-subnet-2" + - cidr: 10.230.230.128/26 + az: "{{ az_one }}" + name: "{{ resource_prefix }}-subnet-3" + - cidr: 10.230.230.192/26 + az: "{{ az_two }}" + name: "{{ resource_prefix }}-subnet-4" + register: subnets + + # ============================================================ + + - include_tasks: tasks/subnet_ids.yml + vars: + vpc_id: "{{ vpc.vpc.id }}" + subnet_ids: "{{ subnets | json_query('results[*].subnet.id') }}" + + - include_tasks: tasks/subnet_names.yml + vars: + vpc_id: "{{ vpc.vpc.id }}" + subnet_names: "{{ subnets | json_query('results[*].subnet.tags.Name') }}" + + - include_tasks: tasks/tags.yml + vars: + vpc_id: "{{ vpc.vpc.id }}" + subnet_ids: "{{ subnets | json_query('results[*].subnet.id') }}" + + - include_tasks: tasks/ingress_and_egress.yml + vars: + vpc_id: "{{ vpc.vpc.id }}" + subnet_ids: "{{ subnets | json_query('results[*].subnet.id') }}" + + - include_tasks: tasks/ipv6.yml + + # ============================================================ + + always: + + - name: remove network ACL + ec2_vpc_nacl: + vpc_id: "{{ vpc.vpc.id }}" + name: "{{ resource_prefix }}-acl" + state: absent + register: removed_acl + until: removed_acl is success + retries: 5 + delay: 5 + ignore_errors: yes + + - name: remove subnets + ec2_vpc_subnet: + cidr: "{{ item.cidr }}" + az: "{{ aws_region}}{{ item.az }}" + vpc_id: "{{ vpc.vpc.id }}" + state: absent + tags: + Public: "{{ item.public | string }}" + Name: "{{ item.public | ternary('public', 'private') }}-{{ item.az }}" + with_items: + - cidr: 10.230.230.0/26 + az: "a" + public: "True" + - cidr: 10.230.230.64/26 + az: "b" + public: "True" + - cidr: 10.230.230.128/26 + az: "a" + public: "False" + - cidr: 10.230.230.192/26 + az: "b" + public: "False" + ignore_errors: yes + register: removed_subnets + until: removed_subnets is success + retries: 5 + delay: 5 + + - name: remove the VPC + ec2_vpc_net: + cidr_block: 10.230.230.0/24 + name: "{{ resource_prefix }}" + state: absent + ignore_errors: yes + register: removed_vpc + until: removed_vpc is success + retries: 5 + delay: 5 + + # ============================================================ diff --git a/tests/integration/targets/ec2_vpc_nacl/tasks/subnet_ids.yml b/tests/integration/targets/ec2_vpc_nacl/tasks/subnet_ids.yml new file mode 100644 index 00000000000..de371d629ae --- /dev/null +++ b/tests/integration/targets/ec2_vpc_nacl/tasks/subnet_ids.yml @@ -0,0 +1,174 @@ +# ============================================================ + +- name: create ingress and egress rules using subnet IDs + ec2_vpc_nacl: + vpc_id: "{{ vpc_id }}" + name: "{{ resource_prefix }}-acl" + subnets: "{{ subnet_ids }}" + tags: + Created_by: "Ansible test {{ resource_prefix }}" + ingress: + - [100, 'tcp', 'allow', '0.0.0.0/0', null, null, 22, 22] + - [200, 'tcp', 'allow', '0.0.0.0/0', null, null, 80, 80] + - [300, 'icmp', 'allow', '0.0.0.0/0', 0, 8] + egress: + - [100, 'all', 'allow', '0.0.0.0/0', null, null, null, null] + state: 'present' + register: nacl + +- set_fact: + nacl_id: "{{ nacl.nacl_id }}" + +- name: assert the network acl was created + assert: + that: + - nacl.changed + - nacl.nacl_id.startswith('acl-') + +- name: get network ACL facts + ec2_vpc_nacl_info: + nacl_ids: + - "{{ nacl_id }}" + register: nacl_facts + +- name: assert the nacl has the correct attributes + assert: + that: + - nacl_facts.nacls | length == 1 + - nacl_facts.nacls[0].nacl_id == nacl_id + - nacl_facts.nacls[0].subnets | length == 4 + - nacl_facts.nacls[0].subnets | sort == subnet_ids | sort + - nacl_facts.nacls[0].ingress | length == 3 + - nacl_facts.nacls[0].egress | length == 1 + - "'{{ nacl_facts.nacls[0].tags.Name }}' == '{{ resource_prefix }}-acl'" + +# ============================================================ + +- name: test idempotence + ec2_vpc_nacl: + vpc_id: "{{ vpc_id }}" + name: "{{ resource_prefix }}-acl" + subnets: "{{ subnet_ids }}" + tags: + Created_by: "Ansible test {{ resource_prefix }}" + ingress: + - [100, 'tcp', 'allow', '0.0.0.0/0', null, null, 22, 22] + - [200, 'tcp', 'allow', '0.0.0.0/0', null, null, 80, 80] + - [300, 'icmp', 'allow', '0.0.0.0/0', 0, 8] + egress: + - [100, 'all', 'allow', '0.0.0.0/0', null, null, null, null] + state: 'present' + register: nacl + +- name: assert the network acl already existed + assert: + that: + - not nacl.changed + - nacl.nacl_id == nacl_id + - nacl.nacl_id.startswith('acl-') + +- name: get network ACL facts + ec2_vpc_nacl_info: + nacl_ids: + - "{{ nacl.nacl_id }}" + register: nacl_facts_idem + +- name: assert the facts are the same as before + assert: + that: + - nacl_facts_idem == nacl_facts + +# ============================================================ + +- name: remove a subnet from the network ACL + ec2_vpc_nacl: + vpc_id: "{{ vpc_id }}" + name: "{{ resource_prefix }}-acl" + subnets: + - "{{ subnet_ids[0] }}" + - "{{ subnet_ids[1] }}" + - "{{ subnet_ids[2] }}" + tags: + Created_by: "Ansible test {{ resource_prefix }}" + ingress: + - [100, 'tcp', 'allow', '0.0.0.0/0', null, null, 22, 22] + - [200, 'tcp', 'allow', '0.0.0.0/0', null, null, 80, 80] + - [300, 'icmp', 'allow', '0.0.0.0/0', 0, 8] + egress: + - [100, 'all', 'allow', '0.0.0.0/0', null, null, null, null] + state: 'present' + register: nacl + +- name: assert the network ACL changed + assert: + that: + - nacl.changed + - nacl.nacl_id.startswith('acl-') + - nacl.nacl_id == nacl_id + +- name: get network ACL facts + ec2_vpc_nacl_info: + nacl_id: + - "{{ nacl.nacl_id }}" + register: nacl_facts + +- name: assert the nacl has the correct attributes + assert: + that: + - nacl_facts.nacls | length == 1 + - nacl_facts.nacls[0].nacl_id == nacl_id + - nacl_facts.nacls[0].subnets | length == 3 + - subnet_ids[3] not in nacl_facts.nacls[0].subnets + - nacl_facts.nacls[0].ingress | length == 3 + - nacl_facts.nacls[0].egress | length == 1 + - "'{{ nacl_facts.nacls[0].tags.Name }}' == '{{ resource_prefix }}-acl'" + +# ============================================================ + +- name: remove the network ACL + ec2_vpc_nacl: + vpc_id: "{{ vpc_id }}" + name: "{{ resource_prefix }}-acl" + state: absent + register: nacl + until: nacl is success + ignore_errors: yes + retries: 5 + delay: 5 + +- name: assert nacl was removed + assert: + that: + - nacl.changed + +- name: re-remove the network ACL by name (test idempotency) + ec2_vpc_nacl: + vpc_id: "{{ vpc_id }}" + name: "{{ resource_prefix }}-acl" + state: absent + register: nacl + until: nacl is success + ignore_errors: yes + retries: 5 + delay: 5 + +- name: assert nacl was removed + assert: + that: + - nacl is not changed + +- name: re-remove the network ACL by id (test idempotency) + ec2_vpc_nacl: + vpc_id: "{{ vpc_id }}" + nacl_id: "{{ nacl_id }}" + state: absent + register: nacl + until: nacl is success + ignore_errors: yes + retries: 5 + delay: 5 + +- name: assert nacl was removed + assert: + that: + - nacl is not changed diff --git a/tests/integration/targets/ec2_vpc_nacl/tasks/subnet_names.yml b/tests/integration/targets/ec2_vpc_nacl/tasks/subnet_names.yml new file mode 100644 index 00000000000..5a4db04df92 --- /dev/null +++ b/tests/integration/targets/ec2_vpc_nacl/tasks/subnet_names.yml @@ -0,0 +1,140 @@ +# ============================================================ + +- name: create ingress and egress rules using subnet names + ec2_vpc_nacl: + vpc_id: "{{ vpc_id }}" + name: "{{ resource_prefix }}-acl" + subnets: "{{ subnet_names }}" + tags: + Created_by: "Ansible test {{ resource_prefix }}" + ingress: + - [100, 'tcp', 'allow', '0.0.0.0/0', null, null, 22, 22] + - [200, 'tcp', 'allow', '0.0.0.0/0', null, null, 80, 80] + - [300, 'icmp', 'allow', '0.0.0.0/0', 0, 8] + egress: + - [100, 'all', 'allow', '0.0.0.0/0', null, null, null, null] + state: 'present' + register: nacl + +- set_fact: + nacl_id: "{{ nacl.nacl_id }}" + +- name: assert the network acl was created + assert: + that: + - nacl.changed + - nacl.nacl_id.startswith('acl-') + +- name: get network ACL facts + ec2_vpc_nacl_info: + nacl_ids: + - "{{ nacl_id }}" + register: nacl_facts + +- name: assert the nacl has the correct attributes + assert: + that: + - nacl_facts.nacls | length == 1 + - nacl_facts.nacls[0].nacl_id == nacl_id + - nacl_facts.nacls[0].subnets | length == 4 + - nacl_facts.nacls[0].ingress | length == 3 + - nacl_facts.nacls[0].egress | length == 1 + - "'{{ nacl_facts.nacls[0].tags.Name }}' == '{{ resource_prefix }}-acl'" + +# ============================================================ + +- name: test idempotence + ec2_vpc_nacl: + vpc_id: "{{ vpc_id }}" + name: "{{ resource_prefix }}-acl" + subnets: "{{ subnet_names }}" + tags: + Created_by: "Ansible test {{ resource_prefix }}" + ingress: + - [100, 'tcp', 'allow', '0.0.0.0/0', null, null, 22, 22] + - [200, 'tcp', 'allow', '0.0.0.0/0', null, null, 80, 80] + - [300, 'icmp', 'allow', '0.0.0.0/0', 0, 8] + egress: + - [100, 'all', 'allow', '0.0.0.0/0', null, null, null, null] + state: 'present' + register: nacl + +- name: assert the network acl already existed + assert: + that: + - not nacl.changed + - nacl.nacl_id == nacl_id + - nacl.nacl_id.startswith('acl-') + +- name: get network ACL facts + ec2_vpc_nacl_info: + nacl_ids: + - "{{ nacl.nacl_id }}" + register: nacl_facts_idem + +- name: assert the facts are the same as before + assert: + that: + - nacl_facts_idem == nacl_facts + +# ============================================================ + +- name: remove a subnet from the network ACL + ec2_vpc_nacl: + vpc_id: "{{ vpc_id }}" + name: "{{ resource_prefix }}-acl" + subnets: + - "{{ subnet_names[0] }}" + - "{{ subnet_names[1] }}" + - "{{ subnet_names[2] }}" + tags: + Created_by: "Ansible test {{ resource_prefix }}" + ingress: + - [100, 'tcp', 'allow', '0.0.0.0/0', null, null, 22, 22] + - [200, 'tcp', 'allow', '0.0.0.0/0', null, null, 80, 80] + - [300, 'icmp', 'allow', '0.0.0.0/0', 0, 8] + egress: + - [100, 'all', 'allow', '0.0.0.0/0', null, null, null, null] + state: 'present' + register: nacl + +- name: assert the network ACL changed + assert: + that: + - nacl.changed + - nacl.nacl_id == nacl_id + - nacl.nacl_id.startswith('acl-') + +- name: get network ACL facts + ec2_vpc_nacl_info: + nacl_ids: + - "{{ nacl.nacl_id }}" + register: nacl_facts + +- name: assert the nacl has the correct attributes + assert: + that: + - nacl_facts.nacls | length == 1 + - nacl_facts.nacls[0].nacl_id == nacl_id + - nacl_facts.nacls[0].subnets | length == 3 + - nacl_facts.nacls[0].ingress | length == 3 + - nacl_facts.nacls[0].egress | length == 1 + - "'{{ nacl_facts.nacls[0].tags.Name }}' == '{{ resource_prefix }}-acl'" + +# ============================================================ + +- name: remove the network ACL + ec2_vpc_nacl: + vpc_id: "{{ vpc_id }}" + name: "{{ resource_prefix }}-acl" + state: absent + register: nacl + until: nacl is success + ignore_errors: yes + retries: 5 + delay: 5 + +- name: assert nacl was removed + assert: + that: + - nacl.changed diff --git a/tests/integration/targets/ec2_vpc_nacl/tasks/tags.yml b/tests/integration/targets/ec2_vpc_nacl/tasks/tags.yml new file mode 100644 index 00000000000..f7847850a58 --- /dev/null +++ b/tests/integration/targets/ec2_vpc_nacl/tasks/tags.yml @@ -0,0 +1,117 @@ +# ============================================================ + +- name: create a network ACL using subnet IDs + ec2_vpc_nacl: + vpc_id: "{{ vpc_id }}" + name: "{{ resource_prefix }}-acl" + subnets: "{{ subnet_ids }}" + state: 'present' + register: nacl + +- name: assert the network acl was created + assert: + that: + - nacl.changed + - nacl.nacl_id.startswith('acl-') + +- name: get network ACL facts + ec2_vpc_nacl_info: + nacl_ids: + - "{{ nacl.nacl_id }}" + register: nacl_facts + +- name: assert the nacl has the correct attributes + assert: + that: + - nacl_facts.nacls[0].tags | length == 1 + - "'{{ nacl_facts.nacls[0].tags.Name }}' == '{{ resource_prefix }}-acl'" + +# ============================================================ + +- name: add a tag + ec2_vpc_nacl: + vpc_id: "{{ vpc_id }}" + name: "{{ resource_prefix }}-acl" + subnets: "{{ subnet_ids }}" + tags: + Created_by: "Ansible test {{ resource_prefix }}" + state: 'present' + register: nacl + +- name: assert the network acl changed + assert: + that: + - nacl.changed + +- name: get network ACL facts + ec2_vpc_nacl_info: + nacl_ids: + - "{{ nacl.nacl_id }}" + register: nacl_facts + +- name: assert the facts are the same as before + assert: + that: + - nacl_facts.nacls[0].tags | length == 2 + - "'{{ nacl_facts.nacls[0].tags.Name }}' == '{{ resource_prefix }}-acl'" + - "'{{ nacl_facts.nacls[0].tags.Created_by }}' == 'Ansible test {{ resource_prefix }}'" + +- name: get network ACL facts by filter + ec2_vpc_nacl_info: + filters: + "tag:Created_by": "Ansible test {{ resource_prefix }}" + register: nacl_facts + +- name: assert the facts are the same as before + assert: + that: + - nacl_facts.nacls | length == 1 + - nacl_facts.nacls[0].tags | length == 2 + - "'{{ nacl_facts.nacls[0].tags.Name }}' == '{{ resource_prefix }}-acl'" + - "'{{ nacl_facts.nacls[0].tags.Created_by }}' == 'Ansible test {{ resource_prefix }}'" + +# ============================================================ + +- name: remove a tag + ec2_vpc_nacl: + vpc_id: "{{ vpc_id }}" + name: "{{ resource_prefix }}-acl" + subnets: "{{ subnet_ids }}" + state: 'present' + register: nacl + +- name: assert the network acl was created + assert: + that: + - nacl.changed + - nacl.nacl_id.startswith('acl-') + +- name: get network ACL facts + ec2_vpc_nacl_info: + nacl_ids: + - "{{ nacl.nacl_id }}" + register: nacl_facts + +- name: assert the nacl has the correct attributes + assert: + that: + - nacl_facts.nacls[0].tags | length == 1 + - "'{{ nacl_facts.nacls[0].tags.Name }}' == '{{ resource_prefix }}-acl'" + +# ============================================================ + +- name: remove the network ACL + ec2_vpc_nacl: + vpc_id: "{{ vpc_id }}" + name: "{{ resource_prefix }}-acl" + state: absent + register: nacl + until: nacl is success + ignore_errors: yes + retries: 5 + delay: 5 + +- name: assert nacl was removed + assert: + that: + - nacl.changed From 723cd965117c291f5ecec14e3462c7c433d8143a Mon Sep 17 00:00:00 2001 From: jillr Date: Tue, 3 Mar 2020 19:43:21 +0000 Subject: [PATCH 02/34] migration test cleanup This commit was initially merged in https://github.com/ansible-collections/community.aws See: https://github.com/ansible-collections/community.aws/commit/13b104b912784bb31a0bff23eed4c27b0f5e0283 --- plugins/modules/ec2_vpc_nacl_info.py | 7 +++++-- tests/integration/targets/ec2_vpc_nacl/tasks/main.yml | 10 ++++++---- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/plugins/modules/ec2_vpc_nacl_info.py b/plugins/modules/ec2_vpc_nacl_info.py index 9db13f104d2..068b62845ff 100644 --- a/plugins/modules/ec2_vpc_nacl_info.py +++ b/plugins/modules/ec2_vpc_nacl_info.py @@ -114,8 +114,11 @@ from ansible_collections.ansible.amazon.plugins.module_utils.aws.core import AnsibleAWSModule from ansible.module_utils._text import to_native -from ansible_collections.ansible.amazon.plugins.module_utils.ec2 import (AWSRetry, ansible_dict_to_boto3_filter_list, - camel_dict_to_snake_dict, boto3_tag_list_to_ansible_dict) +from ansible_collections.ansible.amazon.plugins.module_utils.ec2 import (AWSRetry, + ansible_dict_to_boto3_filter_list, + camel_dict_to_snake_dict, + boto3_tag_list_to_ansible_dict, + ) # VPC-supported IANA protocol numbers diff --git a/tests/integration/targets/ec2_vpc_nacl/tasks/main.yml b/tests/integration/targets/ec2_vpc_nacl/tasks/main.yml index ad72530e290..5d350f9744d 100644 --- a/tests/integration/targets/ec2_vpc_nacl/tasks/main.yml +++ b/tests/integration/targets/ec2_vpc_nacl/tasks/main.yml @@ -5,6 +5,8 @@ aws_secret_key: "{{ aws_secret_key }}" security_token: "{{ security_token | default(omit) }}" region: "{{ aws_region }}" + collections: + - ansible.amazon block: # ============================================================ @@ -94,22 +96,22 @@ - include_tasks: tasks/subnet_ids.yml vars: vpc_id: "{{ vpc.vpc.id }}" - subnet_ids: "{{ subnets | json_query('results[*].subnet.id') }}" + subnet_ids: "{{ subnets | community.general.json_query('results[*].subnet.id') }}" - include_tasks: tasks/subnet_names.yml vars: vpc_id: "{{ vpc.vpc.id }}" - subnet_names: "{{ subnets | json_query('results[*].subnet.tags.Name') }}" + subnet_names: "{{ subnets | community.general.json_query('results[*].subnet.tags.Name') }}" - include_tasks: tasks/tags.yml vars: vpc_id: "{{ vpc.vpc.id }}" - subnet_ids: "{{ subnets | json_query('results[*].subnet.id') }}" + subnet_ids: "{{ subnets | community.general.json_query('results[*].subnet.id') }}" - include_tasks: tasks/ingress_and_egress.yml vars: vpc_id: "{{ vpc.vpc.id }}" - subnet_ids: "{{ subnets | json_query('results[*].subnet.id') }}" + subnet_ids: "{{ subnets | community.general.json_query('results[*].subnet.id') }}" - include_tasks: tasks/ipv6.yml From 9a2a23cfbdd51104fa25d2dac42c76de02a32732 Mon Sep 17 00:00:00 2001 From: Jill R <4121322+jillr@users.noreply.github.com> Date: Wed, 25 Mar 2020 15:39:40 -0700 Subject: [PATCH 03/34] Rename collection (#12) * Rename core collection Rename references to ansible.amazon to amazon.aws. * Rename community.amazon to community.aws Fix pep8 line lengths for rewritten amazon.aws imports * Missed a path in shippable.sh * Dependency repos moved This commit was initially merged in https://github.com/ansible-collections/community.aws See: https://github.com/ansible-collections/community.aws/commit/235c5db571cc45db5839476c94356c9b91e1f228 --- plugins/modules/ec2_vpc_nacl.py | 8 ++++---- plugins/modules/ec2_vpc_nacl_info.py | 16 ++++++++-------- .../targets/ec2_vpc_nacl/tasks/main.yml | 2 +- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/plugins/modules/ec2_vpc_nacl.py b/plugins/modules/ec2_vpc_nacl.py index f7c8be76b44..213cf167cd4 100644 --- a/plugins/modules/ec2_vpc_nacl.py +++ b/plugins/modules/ec2_vpc_nacl.py @@ -80,8 +80,8 @@ default: present author: Mike Mochan (@mmochan) extends_documentation_fragment: -- ansible.amazon.aws -- ansible.amazon.ec2 +- amazon.aws.aws +- amazon.aws.ec2 requirements: [ botocore, boto3, json ] ''' @@ -159,8 +159,8 @@ except ImportError: pass # Handled by AnsibleAWSModule -from ansible_collections.ansible.amazon.plugins.module_utils.aws.core import AnsibleAWSModule -from ansible_collections.ansible.amazon.plugins.module_utils.ec2 import AWSRetry +from ansible_collections.amazon.aws.plugins.module_utils.aws.core import AnsibleAWSModule +from ansible_collections.amazon.aws.plugins.module_utils.ec2 import AWSRetry # VPC-supported IANA protocol numbers # http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml diff --git a/plugins/modules/ec2_vpc_nacl_info.py b/plugins/modules/ec2_vpc_nacl_info.py index 068b62845ff..b5a8d3bc251 100644 --- a/plugins/modules/ec2_vpc_nacl_info.py +++ b/plugins/modules/ec2_vpc_nacl_info.py @@ -39,8 +39,8 @@ - By default, the module will return all Network ACLs. extends_documentation_fragment: -- ansible.amazon.aws -- ansible.amazon.ec2 +- amazon.aws.aws +- amazon.aws.ec2 ''' @@ -112,13 +112,13 @@ except ImportError: pass # caught by AnsibleAWSModule -from ansible_collections.ansible.amazon.plugins.module_utils.aws.core import AnsibleAWSModule +from ansible_collections.amazon.aws.plugins.module_utils.aws.core import AnsibleAWSModule from ansible.module_utils._text import to_native -from ansible_collections.ansible.amazon.plugins.module_utils.ec2 import (AWSRetry, - ansible_dict_to_boto3_filter_list, - camel_dict_to_snake_dict, - boto3_tag_list_to_ansible_dict, - ) +from ansible_collections.amazon.aws.plugins.module_utils.ec2 import (AWSRetry, + ansible_dict_to_boto3_filter_list, + camel_dict_to_snake_dict, + boto3_tag_list_to_ansible_dict, + ) # VPC-supported IANA protocol numbers diff --git a/tests/integration/targets/ec2_vpc_nacl/tasks/main.yml b/tests/integration/targets/ec2_vpc_nacl/tasks/main.yml index 5d350f9744d..7be79895473 100644 --- a/tests/integration/targets/ec2_vpc_nacl/tasks/main.yml +++ b/tests/integration/targets/ec2_vpc_nacl/tasks/main.yml @@ -6,7 +6,7 @@ security_token: "{{ security_token | default(omit) }}" region: "{{ aws_region }}" collections: - - ansible.amazon + - amazon.aws block: # ============================================================ From 92264df1c179add15f6f3390e68110e1efbb6188 Mon Sep 17 00:00:00 2001 From: Jill R <4121322+jillr@users.noreply.github.com> Date: Tue, 19 May 2020 16:06:12 -0700 Subject: [PATCH 04/34] Remove METADATA and cleanup galaxy.yml (#70) * Remove ANSIBLE_METADATA entirely, see ansible/ansible/pull/69454. Remove `license` field from galaxy.yml, in favor of `license_file`. This commit was initially merged in https://github.com/ansible-collections/community.aws See: https://github.com/ansible-collections/community.aws/commit/05672a64e2362cc2d865b5af6a57da6bc3cd08e3 --- plugins/modules/ec2_vpc_nacl.py | 5 ----- plugins/modules/ec2_vpc_nacl_info.py | 5 ----- 2 files changed, 10 deletions(-) diff --git a/plugins/modules/ec2_vpc_nacl.py b/plugins/modules/ec2_vpc_nacl.py index 213cf167cd4..23130310720 100644 --- a/plugins/modules/ec2_vpc_nacl.py +++ b/plugins/modules/ec2_vpc_nacl.py @@ -6,11 +6,6 @@ __metaclass__ = type -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['stableinterface'], - 'supported_by': 'community'} - - DOCUMENTATION = ''' module: ec2_vpc_nacl short_description: create and delete Network ACLs. diff --git a/plugins/modules/ec2_vpc_nacl_info.py b/plugins/modules/ec2_vpc_nacl_info.py index b5a8d3bc251..658816545b4 100644 --- a/plugins/modules/ec2_vpc_nacl_info.py +++ b/plugins/modules/ec2_vpc_nacl_info.py @@ -5,11 +5,6 @@ __metaclass__ = type -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['stableinterface'], - 'supported_by': 'community'} - - DOCUMENTATION = ''' --- module: ec2_vpc_nacl_info From df777deaafd2e4048833d2962a6252881912b8b1 Mon Sep 17 00:00:00 2001 From: Jill R <4121322+jillr@users.noreply.github.com> Date: Tue, 16 Jun 2020 11:23:52 -0700 Subject: [PATCH 05/34] Collections related fixes for CI (#96) * Update module deprecations Switch version to `removed_at_date` * Don't install amazon.aws from galaxy We've been using galaxy to install amazon.aws in shippable, but that doesn't really work if we aren't publising faster. Get that collection from git so it is most up to date. * We need to declare python test deps now * missed a python dep This commit was initially merged in https://github.com/ansible-collections/community.aws See: https://github.com/ansible-collections/community.aws/commit/7cd211e9383db26bc2aa4cc06e657cf60ed0acc0 --- plugins/modules/ec2_vpc_nacl_info.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/modules/ec2_vpc_nacl_info.py b/plugins/modules/ec2_vpc_nacl_info.py index 658816545b4..d4c0c431465 100644 --- a/plugins/modules/ec2_vpc_nacl_info.py +++ b/plugins/modules/ec2_vpc_nacl_info.py @@ -209,7 +209,7 @@ def main(): module = AnsibleAWSModule(argument_spec=argument_spec, supports_check_mode=True) if module._name == 'ec2_vpc_nacl_facts': - module.deprecate("The 'ec2_vpc_nacl_facts' module has been renamed to 'ec2_vpc_nacl_info'", version='2.13') + module.deprecate("The 'ec2_vpc_nacl_facts' module has been renamed to 'ec2_vpc_nacl_info'", date='2021-12-01', collection_name='community.aws') connection = module.client('ec2', retry_decorator=AWSRetry.jittered_backoff()) From 9f729dda8d7ece397a7fc82905d07e6f8623eac2 Mon Sep 17 00:00:00 2001 From: Abhijeet Kasurde Date: Wed, 17 Jun 2020 01:24:54 +0530 Subject: [PATCH 06/34] Update Examples with FQCN (#67) Updated module examples with FQCN Signed-off-by: Abhijeet Kasurde This commit was initially merged in https://github.com/ansible-collections/community.aws See: https://github.com/ansible-collections/community.aws/commit/98173aefbbceed7fc0d9db62687b73f96a55a999 --- plugins/modules/ec2_vpc_nacl.py | 10 +++++----- plugins/modules/ec2_vpc_nacl_info.py | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/plugins/modules/ec2_vpc_nacl.py b/plugins/modules/ec2_vpc_nacl.py index 23130310720..5c14fec8040 100644 --- a/plugins/modules/ec2_vpc_nacl.py +++ b/plugins/modules/ec2_vpc_nacl.py @@ -86,7 +86,7 @@ # Complete example to create and delete a network ACL # that allows SSH, HTTP and ICMP in, and all traffic out. - name: "Create and associate production DMZ network ACL with DMZ subnets" - ec2_vpc_nacl: + community.aws.ec2_vpc_nacl: vpc_id: vpc-12345678 name: prod-dmz-nacl region: ap-southeast-2 @@ -106,7 +106,7 @@ state: 'present' - name: "Remove the ingress and egress rules - defaults to deny all" - ec2_vpc_nacl: + community.aws.ec2_vpc_nacl: vpc_id: vpc-12345678 name: prod-dmz-nacl region: ap-southeast-2 @@ -120,20 +120,20 @@ state: present - name: "Remove the NACL subnet associations and tags" - ec2_vpc_nacl: + community.aws.ec2_vpc_nacl: vpc_id: 'vpc-12345678' name: prod-dmz-nacl region: ap-southeast-2 state: present - name: "Delete nacl and subnet associations" - ec2_vpc_nacl: + community.aws.ec2_vpc_nacl: vpc_id: vpc-12345678 name: prod-dmz-nacl state: absent - name: "Delete nacl by its id" - ec2_vpc_nacl: + community.aws.ec2_vpc_nacl: nacl_id: acl-33b4ee5b state: absent ''' diff --git a/plugins/modules/ec2_vpc_nacl_info.py b/plugins/modules/ec2_vpc_nacl_info.py index d4c0c431465..31b1099b04c 100644 --- a/plugins/modules/ec2_vpc_nacl_info.py +++ b/plugins/modules/ec2_vpc_nacl_info.py @@ -44,17 +44,17 @@ # Gather information about all Network ACLs: - name: Get All NACLs - register: all_nacls - ec2_vpc_nacl_info: + community.aws.ec2_vpc_nacl_info: region: us-west-2 + register: all_nacls # Retrieve default Network ACLs: - name: Get Default NACLs - register: default_nacls - ec2_vpc_nacl_info: + community.aws.ec2_vpc_nacl_info: region: us-west-2 filters: 'default': 'true' + register: default_nacls ''' RETURN = ''' From cac0d7665b7ce4e720997385cc4158df1913f824 Mon Sep 17 00:00:00 2001 From: flowerysong Date: Tue, 16 Jun 2020 19:30:00 -0400 Subject: [PATCH 07/34] Update module_utils paths to remove aws subdir (#23) Co-authored-by: Ezekiel Hendrickson This commit was initially merged in https://github.com/ansible-collections/community.aws See: https://github.com/ansible-collections/community.aws/commit/10853d9441a586ba177006dd889325cfb24a3dd6 --- plugins/modules/ec2_vpc_nacl.py | 2 +- plugins/modules/ec2_vpc_nacl_info.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/modules/ec2_vpc_nacl.py b/plugins/modules/ec2_vpc_nacl.py index 5c14fec8040..14853edf767 100644 --- a/plugins/modules/ec2_vpc_nacl.py +++ b/plugins/modules/ec2_vpc_nacl.py @@ -154,7 +154,7 @@ except ImportError: pass # Handled by AnsibleAWSModule -from ansible_collections.amazon.aws.plugins.module_utils.aws.core import AnsibleAWSModule +from ansible_collections.amazon.aws.plugins.module_utils.core import AnsibleAWSModule from ansible_collections.amazon.aws.plugins.module_utils.ec2 import AWSRetry # VPC-supported IANA protocol numbers diff --git a/plugins/modules/ec2_vpc_nacl_info.py b/plugins/modules/ec2_vpc_nacl_info.py index 31b1099b04c..2cc4f012d58 100644 --- a/plugins/modules/ec2_vpc_nacl_info.py +++ b/plugins/modules/ec2_vpc_nacl_info.py @@ -107,7 +107,7 @@ except ImportError: pass # caught by AnsibleAWSModule -from ansible_collections.amazon.aws.plugins.module_utils.aws.core import AnsibleAWSModule +from ansible_collections.amazon.aws.plugins.module_utils.core import AnsibleAWSModule from ansible.module_utils._text import to_native from ansible_collections.amazon.aws.plugins.module_utils.ec2 import (AWSRetry, ansible_dict_to_boto3_filter_list, From a3e7a16839adf9c7f15404cf4875e2cecebde37c Mon Sep 17 00:00:00 2001 From: Jill R <4121322+jillr@users.noreply.github.com> Date: Wed, 17 Jun 2020 09:31:32 -0700 Subject: [PATCH 08/34] Update docs (#99) * Update docs Remove .git from repo url so links in readme will generate correctly Add required ansible version Run latest version of add_docs.py Add version_added string to modules * galaxy.yml was missing authors This commit was initially merged in https://github.com/ansible-collections/community.aws See: https://github.com/ansible-collections/community.aws/commit/96ee268e5267f5b12c3d59892bc1279f75aa3135 --- plugins/modules/ec2_vpc_nacl.py | 1 + plugins/modules/ec2_vpc_nacl_info.py | 1 + 2 files changed, 2 insertions(+) diff --git a/plugins/modules/ec2_vpc_nacl.py b/plugins/modules/ec2_vpc_nacl.py index 14853edf767..f2ca5cda6f6 100644 --- a/plugins/modules/ec2_vpc_nacl.py +++ b/plugins/modules/ec2_vpc_nacl.py @@ -9,6 +9,7 @@ DOCUMENTATION = ''' module: ec2_vpc_nacl short_description: create and delete Network ACLs. +version_added: 1.0.0 description: - Read the AWS documentation for Network ACLS U(https://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_ACLs.html) diff --git a/plugins/modules/ec2_vpc_nacl_info.py b/plugins/modules/ec2_vpc_nacl_info.py index 2cc4f012d58..337a91d1c93 100644 --- a/plugins/modules/ec2_vpc_nacl_info.py +++ b/plugins/modules/ec2_vpc_nacl_info.py @@ -8,6 +8,7 @@ DOCUMENTATION = ''' --- module: ec2_vpc_nacl_info +version_added: 1.0.0 short_description: Gather information about Network ACLs in an AWS VPC description: - Gather information about Network ACLs in an AWS VPC From 62ac7a3bd4a0beb09f0ec61bdb95faf7fb19bd21 Mon Sep 17 00:00:00 2001 From: Abhijeet Kasurde Date: Thu, 16 Jul 2020 01:31:41 +0530 Subject: [PATCH 09/34] Docs: sanity fixes (#133) Signed-off-by: Abhijeet Kasurde This commit was initially merged in https://github.com/ansible-collections/community.aws See: https://github.com/ansible-collections/community.aws/commit/059cf9efc95bb976de21ab4f8e4d9ddd001983fc --- plugins/modules/ec2_vpc_nacl.py | 15 +++++++++------ plugins/modules/ec2_vpc_nacl_info.py | 9 +++++---- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/plugins/modules/ec2_vpc_nacl.py b/plugins/modules/ec2_vpc_nacl.py index f2ca5cda6f6..387ceb48f26 100644 --- a/plugins/modules/ec2_vpc_nacl.py +++ b/plugins/modules/ec2_vpc_nacl.py @@ -6,7 +6,7 @@ __metaclass__ = type -DOCUMENTATION = ''' +DOCUMENTATION = r''' module: ec2_vpc_nacl short_description: create and delete Network ACLs. version_added: 1.0.0 @@ -39,6 +39,7 @@ - Each subnet can be specified as subnet ID, or its tagged name. required: false type: list + elements: str egress: description: - A list of rules for outgoing traffic. Each rule must be specified as a list. @@ -50,6 +51,7 @@ default: [] required: false type: list + elements: list ingress: description: - List of rules for incoming traffic. Each rule must be specified as a list. @@ -61,6 +63,7 @@ default: [] required: false type: list + elements: list tags: description: - Dictionary of tags to look for and apply when creating a network ACL. @@ -82,7 +85,7 @@ requirements: [ botocore, boto3, json ] ''' -EXAMPLES = ''' +EXAMPLES = r''' # Complete example to create and delete a network ACL # that allows SSH, HTTP and ICMP in, and all traffic out. @@ -138,7 +141,7 @@ nacl_id: acl-33b4ee5b state: absent ''' -RETURN = ''' +RETURN = r''' task: description: The result of the create, or delete action. returned: success @@ -602,10 +605,10 @@ def main(): vpc_id=dict(), name=dict(), nacl_id=dict(), - subnets=dict(required=False, type='list', default=list()), + subnets=dict(required=False, type='list', default=list(), elements='str'), tags=dict(required=False, type='dict'), - ingress=dict(required=False, type='list', default=list()), - egress=dict(required=False, type='list', default=list()), + ingress=dict(required=False, type='list', default=list(), elements='list'), + egress=dict(required=False, type='list', default=list(), elements='list'), state=dict(default='present', choices=['present', 'absent']), ) module = AnsibleAWSModule(argument_spec=argument_spec, diff --git a/plugins/modules/ec2_vpc_nacl_info.py b/plugins/modules/ec2_vpc_nacl_info.py index 337a91d1c93..aabe489c112 100644 --- a/plugins/modules/ec2_vpc_nacl_info.py +++ b/plugins/modules/ec2_vpc_nacl_info.py @@ -5,7 +5,7 @@ __metaclass__ = type -DOCUMENTATION = ''' +DOCUMENTATION = r''' --- module: ec2_vpc_nacl_info version_added: 1.0.0 @@ -23,6 +23,7 @@ default: [] aliases: [nacl_id] type: list + elements: str filters: description: - A dict of filters to apply. Each dict item consists of a filter key and a filter value. See @@ -40,7 +41,7 @@ ''' -EXAMPLES = ''' +EXAMPLES = r''' # Note: These examples do not set authentication details, see the AWS Guide for details. # Gather information about all Network ACLs: @@ -58,7 +59,7 @@ register: default_nacls ''' -RETURN = ''' +RETURN = r''' nacls: description: Returns an array of complex objects as described below. returned: success @@ -205,7 +206,7 @@ def nacl_entry_to_list(entry): def main(): argument_spec = dict( - nacl_ids=dict(default=[], type='list', aliases=['nacl_id']), + nacl_ids=dict(default=[], type='list', aliases=['nacl_id'], elements='str'), filters=dict(default={}, type='dict')) module = AnsibleAWSModule(argument_spec=argument_spec, supports_check_mode=True) From 69ae7f24a0afa71ee61b0a940375e5e16069b6e6 Mon Sep 17 00:00:00 2001 From: Mark Chappell Date: Mon, 27 Jul 2020 18:43:01 +0200 Subject: [PATCH 10/34] Mark a number of integration tests as unstable based on high failure rates over the last week (#160) https://github.com/ansible-collections/community.aws/issues/158 https://github.com/ansible-collections/community.aws/issues/157 https://github.com/ansible-collections/community.aws/issues/159 https://github.com/ansible-collections/community.aws/issues/153 https://github.com/ansible-collections/community.aws/issues/154 https://github.com/ansible-collections/community.aws/issues/155 https://github.com/ansible-collections/community.aws/issues/156 This commit was initially merged in https://github.com/ansible-collections/community.aws See: https://github.com/ansible-collections/community.aws/commit/61783c7995aa177f34ceb0295ff62db251b102df --- tests/integration/targets/ec2_vpc_nacl/aliases | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/integration/targets/ec2_vpc_nacl/aliases b/tests/integration/targets/ec2_vpc_nacl/aliases index 074f2ab60c1..d82d1f9e4cd 100644 --- a/tests/integration/targets/ec2_vpc_nacl/aliases +++ b/tests/integration/targets/ec2_vpc_nacl/aliases @@ -1,3 +1,5 @@ ec2_vpc_nacl_info cloud/aws shippable/aws/group2 +# https://github.com/ansible-collections/community.aws/issues/153 +unstable From 7d3e487bf012f8948bcb023a401e54b75b63dc9c Mon Sep 17 00:00:00 2001 From: Mark Chappell Date: Wed, 27 Jan 2021 09:17:44 +0100 Subject: [PATCH 11/34] Bulk migration to fail_json_aws (#361) * Split imports and sort * Move camel_dict_to_snake_dict imports to ansible.module_utils.common.dict_transformations * Cleanup unused imports * Bulk migration to fail_json_aws * Changelog This commit was initially merged in https://github.com/ansible-collections/community.aws See: https://github.com/ansible-collections/community.aws/commit/6c883156d250d3ed926a21dbd619b2b138246c5d --- plugins/modules/ec2_vpc_nacl_info.py | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/modules/ec2_vpc_nacl_info.py b/plugins/modules/ec2_vpc_nacl_info.py index aabe489c112..1e42e486cea 100644 --- a/plugins/modules/ec2_vpc_nacl_info.py +++ b/plugins/modules/ec2_vpc_nacl_info.py @@ -110,7 +110,6 @@ pass # caught by AnsibleAWSModule from ansible_collections.amazon.aws.plugins.module_utils.core import AnsibleAWSModule -from ansible.module_utils._text import to_native from ansible_collections.amazon.aws.plugins.module_utils.ec2 import (AWSRetry, ansible_dict_to_boto3_filter_list, camel_dict_to_snake_dict, From 7fc898305edac7dcbb9fb9921b0b4e631b62eb24 Mon Sep 17 00:00:00 2001 From: Mark Chappell Date: Fri, 5 Feb 2021 09:43:09 +0100 Subject: [PATCH 12/34] Cleanup - use is_boto3_error_(message|code) (#268) * Reorder imports * Make use of is_boto3_error_message * Mass-migration over to is_boto3_error_code * Remove unused imports * unused vars in exception * Improve consistency around catching BotoCoreError and ClientError * Remove unused imports * Remove unused 'PolicyError' from iam_policy_info * Avoid catching botocore.exceptions.ClientError when we only want some error codes * Import camel_dict_to_snake_dict/snake_dict_to_camel_dict from ansible.module_utils.common.dict_transformations This commit was initially merged in https://github.com/ansible-collections/community.aws See: https://github.com/ansible-collections/community.aws/commit/4cf52ef67682fd4f9ed2a707adfbafffe7b88f15 --- plugins/modules/ec2_vpc_nacl_info.py | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/plugins/modules/ec2_vpc_nacl_info.py b/plugins/modules/ec2_vpc_nacl_info.py index 1e42e486cea..8c905f67e58 100644 --- a/plugins/modules/ec2_vpc_nacl_info.py +++ b/plugins/modules/ec2_vpc_nacl_info.py @@ -105,16 +105,17 @@ ''' try: - from botocore.exceptions import ClientError, BotoCoreError + import botocore except ImportError: pass # caught by AnsibleAWSModule +from ansible.module_utils.common.dict_transformations import camel_dict_to_snake_dict + from ansible_collections.amazon.aws.plugins.module_utils.core import AnsibleAWSModule -from ansible_collections.amazon.aws.plugins.module_utils.ec2 import (AWSRetry, - ansible_dict_to_boto3_filter_list, - camel_dict_to_snake_dict, - boto3_tag_list_to_ansible_dict, - ) +from ansible_collections.amazon.aws.plugins.module_utils.core import is_boto3_error_code +from ansible_collections.amazon.aws.plugins.module_utils.ec2 import AWSRetry +from ansible_collections.amazon.aws.plugins.module_utils.ec2 import ansible_dict_to_boto3_filter_list +from ansible_collections.amazon.aws.plugins.module_utils.ec2 import boto3_tag_list_to_ansible_dict # VPC-supported IANA protocol numbers @@ -132,11 +133,9 @@ def list_ec2_vpc_nacls(connection, module): try: nacls = connection.describe_network_acls(aws_retry=True, NetworkAclIds=nacl_ids, Filters=filters) - except ClientError as e: - if e.response['Error']['Code'] == 'InvalidNetworkAclID.NotFound': - module.fail_json(msg='Unable to describe ACL. NetworkAcl does not exist') - module.fail_json_aws(e, msg="Unable to describe network ACLs {0}".format(nacl_ids)) - except BotoCoreError as e: + except is_boto3_error_code('InvalidNetworkAclID.NotFound'): + module.fail_json(msg='Unable to describe ACL. NetworkAcl does not exist') + except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: # pylint: disable=duplicate-except module.fail_json_aws(e, msg="Unable to describe network ACLs {0}".format(nacl_ids)) # Turn the boto3 result in to ansible_friendly_snaked_names From 921c6e3138f009bc8885932d597b97ca597fef83 Mon Sep 17 00:00:00 2001 From: Mark Chappell Date: Sun, 21 Feb 2021 15:40:04 +0100 Subject: [PATCH 13/34] Yet more integration test aliases file cleanup (#431) * More aliases cleanup * Mark ec2_classic_lb tests unstable * Add more comments about why tests aren't enabled This commit was initially merged in https://github.com/ansible-collections/community.aws See: https://github.com/ansible-collections/community.aws/commit/cb55efa7a4fda574b637f3b18c072cd2436e2a21 --- tests/integration/targets/ec2_vpc_nacl/aliases | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/integration/targets/ec2_vpc_nacl/aliases b/tests/integration/targets/ec2_vpc_nacl/aliases index d82d1f9e4cd..a0b5045ec87 100644 --- a/tests/integration/targets/ec2_vpc_nacl/aliases +++ b/tests/integration/targets/ec2_vpc_nacl/aliases @@ -1,5 +1,7 @@ -ec2_vpc_nacl_info -cloud/aws -shippable/aws/group2 # https://github.com/ansible-collections/community.aws/issues/153 unstable + +cloud/aws +shippable/aws/group2 + +ec2_vpc_nacl_info From a4fbafe62c180b1d3eec81e6a5864ed5d7b3da57 Mon Sep 17 00:00:00 2001 From: Nicolas Boutet Date: Mon, 8 Mar 2021 13:47:03 +0100 Subject: [PATCH 14/34] ec2_vpc_nacl: add IPv6 support (#398) This commit was initially merged in https://github.com/ansible-collections/community.aws See: https://github.com/ansible-collections/community.aws/commit/7bddc31e406e198d7de6734f942b53447c61c8a4 --- plugins/modules/ec2_vpc_nacl.py | 24 +++++++--- .../targets/ec2_vpc_nacl/tasks/ipv6.yml | 46 ++++++++++++------- 2 files changed, 47 insertions(+), 23 deletions(-) diff --git a/plugins/modules/ec2_vpc_nacl.py b/plugins/modules/ec2_vpc_nacl.py index 387ceb48f26..da053f55a46 100644 --- a/plugins/modules/ec2_vpc_nacl.py +++ b/plugins/modules/ec2_vpc_nacl.py @@ -43,8 +43,8 @@ egress: description: - A list of rules for outgoing traffic. Each rule must be specified as a list. - Each rule may contain the rule number (integer 1-32766), protocol (one of ['tcp', 'udp', 'icmp', '-1', 'all']), - the rule action ('allow' or 'deny') the CIDR of the IPv4 network range to allow or deny, + Each rule may contain the rule number (integer 1-32766), protocol (one of ['tcp', 'udp', 'icmp', 'ipv6-icmp', '-1', 'all']), + the rule action ('allow' or 'deny') the CIDR of the IPv4 or IPv6 network range to allow or deny, the ICMP type (-1 means all types), the ICMP code (-1 means all codes), the last port in the range for TCP or UDP protocols, and the first port in the range for TCP or UDP protocols. See examples. @@ -55,8 +55,8 @@ ingress: description: - List of rules for incoming traffic. Each rule must be specified as a list. - Each rule may contain the rule number (integer 1-32766), protocol (one of ['tcp', 'udp', 'icmp', '-1', 'all']), - the rule action ('allow' or 'deny') the CIDR of the IPv4 network range to allow or deny, + Each rule may contain the rule number (integer 1-32766), protocol (one of ['tcp', 'udp', 'icmp', 'ipv6-icmp', '-1', 'all']), + the rule action ('allow' or 'deny') the CIDR of the IPv4 or IPv6 network range to allow or deny, the ICMP type (-1 means all types), the ICMP code (-1 means all codes), the last port in the range for TCP or UDP protocols, and the first port in the range for TCP or UDP protocols. See examples. @@ -104,9 +104,12 @@ # port from, port to - [100, 'tcp', 'allow', '0.0.0.0/0', null, null, 22, 22] - [200, 'tcp', 'allow', '0.0.0.0/0', null, null, 80, 80] + - [205, 'tcp', 'allow', '::/0', null, null, 80, 80] - [300, 'icmp', 'allow', '0.0.0.0/0', 0, 8] + - [305, 'ipv6-icmp', 'allow', '::/0', 0, 8] egress: - [100, 'all', 'allow', '0.0.0.0/0', null, null, null, null] + - [105, 'all', 'allow', '::/0', null, null, null, null] state: 'present' - name: "Remove the ingress and egress rules - defaults to deny all" @@ -163,12 +166,12 @@ # VPC-supported IANA protocol numbers # http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml -PROTOCOL_NUMBERS = {'all': -1, 'icmp': 1, 'tcp': 6, 'udp': 17, } +PROTOCOL_NUMBERS = {'all': -1, 'icmp': 1, 'tcp': 6, 'udp': 17, 'ipv6-icmp': 58} # Utility methods def icmp_present(entry): - if len(entry) == 6 and entry[1] == 'icmp' or entry[1] == 1: + if len(entry) == 6 and entry[1] in ['icmp', 'ipv6-icmp'] or entry[1] in [1, 58]: return True @@ -291,13 +294,20 @@ def rules_changed(aws_rules, param_rules, Egress, nacl_id, client, module): return changed +def is_ipv6(cidr): + return ':' in cidr + + def process_rule_entry(entry, Egress): params = dict() params['RuleNumber'] = entry[0] params['Protocol'] = str(PROTOCOL_NUMBERS[entry[1]]) params['RuleAction'] = entry[2] params['Egress'] = Egress - params['CidrBlock'] = entry[3] + if is_ipv6(entry[3]): + params['Ipv6CidrBlock'] = entry[3] + else: + params['CidrBlock'] = entry[3] if icmp_present(entry): params['IcmpTypeCode'] = {"Type": int(entry[4]), "Code": int(entry[5])} else: diff --git a/tests/integration/targets/ec2_vpc_nacl/tasks/ipv6.yml b/tests/integration/targets/ec2_vpc_nacl/tasks/ipv6.yml index 16b3a5aaaff..59634c0d429 100644 --- a/tests/integration/targets/ec2_vpc_nacl/tasks/ipv6.yml +++ b/tests/integration/targets/ec2_vpc_nacl/tasks/ipv6.yml @@ -62,7 +62,7 @@ ingress: - [100, 'tcp', 'allow', '0.0.0.0/0', null, null, 22, 22] - [200, 'tcp', 'allow', '0.0.0.0/0', null, null, 80, 80] - - [205, 'ipv6-tcp', 'allow', '::/0', null, null, 80, 80] + - [205, 'tcp', 'allow', '::/0', null, null, 80, 80] - [300, 'icmp', 'allow', '0.0.0.0/0', 0, 8] - [305, 'ipv6-icmp', 'allow', '::/0', 0, 8] egress: @@ -70,20 +70,24 @@ - [105, 'all', 'allow', '::/0', null, null, null, null] state: 'present' register: nacl - # FIXME: Currently IPv6 rules are not supported - uncomment assertion when - # fixed (and add some nacl_info tests) - ignore_errors: yes + + - assert: + that: + - nacl.changed + - nacl.nacl_id == nacl_id + - name: get network ACL facts (test that it works with ipv6 entries) ec2_vpc_nacl_info: nacl_ids: - "{{ nacl_id }}" register: nacl_facts - - #- assert: - # that: - # - nacl.changed - # - nacl.nacl_id == nacl_id + - name: assert the nacl has the correct attributes + assert: + that: + - nacl_facts.nacls | length == 1 + - nacl_facts.nacls[0].ingress | length == 5 + - nacl_facts.nacls[0].egress | length == 2 - name: purge ingress entries ec2_vpc_nacl: @@ -99,14 +103,11 @@ - [105, 'all', 'allow', '::/0', null, null, null, null] state: 'present' register: nacl - # FIXME: Currently IPv6 rules are not supported - uncomment assertion when - # fixed (and add some nacl_info tests) - ignore_errors: yes - #- assert: - # that: - # - nacl.changed - # - nacl.nacl_id == nacl_id + - assert: + that: + - nacl.changed + - nacl.nacl_id == nacl_id - name: purge egress entries ec2_vpc_nacl: @@ -125,6 +126,19 @@ that: - nacl.changed + - name: get network ACL facts (test that removed entries are gone) + ec2_vpc_nacl_info: + nacl_ids: + - "{{ nacl_id }}" + register: nacl_facts + + - name: assert the nacl has the correct attributes + assert: + that: + - nacl_facts.nacls | length == 1 + - nacl_facts.nacls[0].ingress | length == 0 + - nacl_facts.nacls[0].egress | length == 0 + # ============================================================ - name: remove subnet ipv6 cidr (expected changed=true) ec2_vpc_subnet: From 0d0122b36b1db908075f81e9c3cf89f3ed26e5ac Mon Sep 17 00:00:00 2001 From: Mark Chappell Date: Thu, 6 May 2021 21:01:46 +0200 Subject: [PATCH 15/34] Update the default module requirements from python 2.6/boto to python 3.6/boto3 This commit was initially merged in https://github.com/ansible-collections/community.aws See: https://github.com/ansible-collections/community.aws/commit/c097c55293be0834a2b9d394733ec28965d142d7 --- plugins/modules/ec2_vpc_nacl.py | 2 -- plugins/modules/ec2_vpc_nacl_info.py | 1 - 2 files changed, 3 deletions(-) diff --git a/plugins/modules/ec2_vpc_nacl.py b/plugins/modules/ec2_vpc_nacl.py index da053f55a46..04da531a2f8 100644 --- a/plugins/modules/ec2_vpc_nacl.py +++ b/plugins/modules/ec2_vpc_nacl.py @@ -81,8 +81,6 @@ extends_documentation_fragment: - amazon.aws.aws - amazon.aws.ec2 - -requirements: [ botocore, boto3, json ] ''' EXAMPLES = r''' diff --git a/plugins/modules/ec2_vpc_nacl_info.py b/plugins/modules/ec2_vpc_nacl_info.py index 8c905f67e58..88786bf76ca 100644 --- a/plugins/modules/ec2_vpc_nacl_info.py +++ b/plugins/modules/ec2_vpc_nacl_info.py @@ -14,7 +14,6 @@ - Gather information about Network ACLs in an AWS VPC - This module was called C(ec2_vpc_nacl_facts) before Ansible 2.9. The usage did not change. author: "Brad Davidson (@brandond)" -requirements: [ boto3 ] options: nacl_ids: description: From 4bfd7d5345b94626051ac82a9a2fc6cb00a21011 Mon Sep 17 00:00:00 2001 From: jillr Date: Thu, 29 Apr 2021 21:58:50 +0000 Subject: [PATCH 16/34] Remove shippable references from repo This collection has been operating on Zuul CI for some weeks now This commit was initially merged in https://github.com/ansible-collections/community.aws See: https://github.com/ansible-collections/community.aws/commit/4e0d83c65568a99a24307e37a14e6e0b173c948b --- tests/integration/targets/ec2_vpc_nacl/aliases | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/integration/targets/ec2_vpc_nacl/aliases b/tests/integration/targets/ec2_vpc_nacl/aliases index a0b5045ec87..4c474104da5 100644 --- a/tests/integration/targets/ec2_vpc_nacl/aliases +++ b/tests/integration/targets/ec2_vpc_nacl/aliases @@ -2,6 +2,5 @@ unstable cloud/aws -shippable/aws/group2 ec2_vpc_nacl_info From fa610432150c498b54f4aa7e870f7fb3dc437442 Mon Sep 17 00:00:00 2001 From: Jill R <4121322+jillr@users.noreply.github.com> Date: Thu, 2 Dec 2021 02:58:06 -0700 Subject: [PATCH 17/34] Remove deprecated "facts" aliases (#814) Remove deprecated "facts" aliases SUMMARY Modules named "facts.py" that do not return ansible_facts were renamed to "info.py" in 2.9. Remove these aliases now that the deprecation period is over. This PR should be included in 3.0.0 of the collection. ISSUE TYPE Bugfix Pull Request COMPONENT NAME *_facts.py Reviewed-by: Mark Chappell Reviewed-by: Jill R Reviewed-by: None This commit was initially merged in https://github.com/ansible-collections/community.aws See: https://github.com/ansible-collections/community.aws/commit/68aaa7057be46a3ab36f572fd0013d64653af909 --- plugins/modules/ec2_vpc_nacl_info.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/plugins/modules/ec2_vpc_nacl_info.py b/plugins/modules/ec2_vpc_nacl_info.py index 88786bf76ca..b8d256470ee 100644 --- a/plugins/modules/ec2_vpc_nacl_info.py +++ b/plugins/modules/ec2_vpc_nacl_info.py @@ -12,7 +12,6 @@ short_description: Gather information about Network ACLs in an AWS VPC description: - Gather information about Network ACLs in an AWS VPC - - This module was called C(ec2_vpc_nacl_facts) before Ansible 2.9. The usage did not change. author: "Brad Davidson (@brandond)" options: nacl_ids: @@ -207,8 +206,6 @@ def main(): filters=dict(default={}, type='dict')) module = AnsibleAWSModule(argument_spec=argument_spec, supports_check_mode=True) - if module._name == 'ec2_vpc_nacl_facts': - module.deprecate("The 'ec2_vpc_nacl_facts' module has been renamed to 'ec2_vpc_nacl_info'", date='2021-12-01', collection_name='community.aws') connection = module.client('ec2', retry_decorator=AWSRetry.jittered_backoff()) From 385a228b1bf854cef19b8a2c145935ec44bcd6a3 Mon Sep 17 00:00:00 2001 From: Mark Chappell Date: Fri, 22 Apr 2022 11:44:07 +0200 Subject: [PATCH 18/34] Integration test dependency cleanup (#1086) Integration test dependency cleanup SUMMARY remove dependencies on setup_remote_tmp_dir where it's not used (often just copy & paste from another test) remove setup_ec2 (no main.yml means it's not doing anything) remove prepare_tests (empty main.yml means it's not doing anything) ISSUE TYPE Feature Pull Request COMPONENT NAME tests/integration/targets ADDITIONAL INFORMATION By cleaning up what we have we reduce the chance of people copying things about "because that's what test XYZ did". Reviewed-by: Alina Buzachis Reviewed-by: Mark Woolley This commit was initially merged in https://github.com/ansible-collections/community.aws See: https://github.com/ansible-collections/community.aws/commit/dd12046a1e2d5f39692b1890ff07e06c56b3bf0e --- tests/integration/targets/ec2_vpc_nacl/meta/main.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/integration/targets/ec2_vpc_nacl/meta/main.yml b/tests/integration/targets/ec2_vpc_nacl/meta/main.yml index 1f64f1169a9..32cf5dda7ed 100644 --- a/tests/integration/targets/ec2_vpc_nacl/meta/main.yml +++ b/tests/integration/targets/ec2_vpc_nacl/meta/main.yml @@ -1,3 +1 @@ -dependencies: - - prepare_tests - - setup_ec2 +dependencies: [] From 9beb607584eb0dbad8728952d83a618841c5bad4 Mon Sep 17 00:00:00 2001 From: Mark Chappell Date: Thu, 2 Jun 2022 09:58:31 +0200 Subject: [PATCH 19/34] ec2_vpc_nacl - Add support for purge_tags (#1189) ec2_vpc_nacl - Add support for purge_tags SUMMARY Add support to ec2_vpc_nacl for purge_tags Use ec2 helper for tagging Use TaggingSpecifications on creation ISSUE TYPE Feature Pull Request COMPONENT NAME ec2_vpc_nacl ADDITIONAL INFORMATION Changelog Integration tests Reviewed-by: Joseph Torcasso This commit was initially merged in https://github.com/ansible-collections/community.aws See: https://github.com/ansible-collections/community.aws/commit/edc393e87cc8d8ba66769bec6134ea7728720482 --- plugins/modules/ec2_vpc_nacl.py | 109 ++-- .../integration/targets/ec2_vpc_nacl/aliases | 3 - .../targets/ec2_vpc_nacl/defaults/main.yml | 12 + .../ec2_vpc_nacl/tasks/ingress_and_egress.yml | 318 +++++----- .../targets/ec2_vpc_nacl/tasks/ipv6.yml | 96 +-- .../targets/ec2_vpc_nacl/tasks/main.yml | 111 ++-- .../targets/ec2_vpc_nacl/tasks/subnet_ids.yml | 27 +- .../ec2_vpc_nacl/tasks/subnet_names.yml | 16 +- .../targets/ec2_vpc_nacl/tasks/tags.yml | 562 ++++++++++++++---- 9 files changed, 736 insertions(+), 518 deletions(-) create mode 100644 tests/integration/targets/ec2_vpc_nacl/defaults/main.yml diff --git a/plugins/modules/ec2_vpc_nacl.py b/plugins/modules/ec2_vpc_nacl.py index 04da531a2f8..9968e2929ff 100644 --- a/plugins/modules/ec2_vpc_nacl.py +++ b/plugins/modules/ec2_vpc_nacl.py @@ -8,7 +8,7 @@ DOCUMENTATION = r''' module: ec2_vpc_nacl -short_description: create and delete Network ACLs. +short_description: create and delete Network ACLs version_added: 1.0.0 description: - Read the AWS documentation for Network ACLS @@ -64,11 +64,6 @@ required: false type: list elements: list - tags: - description: - - Dictionary of tags to look for and apply when creating a network ACL. - required: false - type: dict state: description: - Creates or modifies an existing NACL @@ -79,8 +74,11 @@ default: present author: Mike Mochan (@mmochan) extends_documentation_fragment: -- amazon.aws.aws -- amazon.aws.ec2 + - amazon.aws.aws + - amazon.aws.ec2 + - amazon.aws.tags +notes: + - Support for I(purge_tags) was added in release 4.0.0. ''' EXAMPLES = r''' @@ -161,6 +159,8 @@ from ansible_collections.amazon.aws.plugins.module_utils.core import AnsibleAWSModule from ansible_collections.amazon.aws.plugins.module_utils.ec2 import AWSRetry +from ansible_collections.amazon.aws.plugins.module_utils.ec2 import ensure_ec2_tags +from ansible_collections.amazon.aws.plugins.module_utils.tagging import boto3_tag_specifications # VPC-supported IANA protocol numbers # http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml @@ -173,17 +173,6 @@ def icmp_present(entry): return True -def load_tags(module): - tags = [] - if module.params.get('tags'): - for name, value in module.params.get('tags').items(): - tags.append({'Key': name, 'Value': str(value)}) - tags.append({'Key': "Name", 'Value': module.params.get('name')}) - else: - tags.append({'Key': "Name", 'Value': module.params.get('name')}) - return tags - - def subnets_removed(nacl_id, subnets, client, module): results = find_acl_by_id(nacl_id, client, module) associations = results['NetworkAcls'][0]['Associations'] @@ -243,27 +232,25 @@ def nacls_changed(nacl, client, module): def tags_changed(nacl_id, client, module): + tags = module.params.get('tags') + name = module.params.get('name') + purge_tags = module.params.get('purge_tags') changed = False - tags = dict() - if module.params.get('tags'): - tags = module.params.get('tags') - if module.params.get('name') and not tags.get('Name'): - tags['Name'] = module.params['name'] - nacl = find_acl_by_id(nacl_id, client, module) - if nacl['NetworkAcls']: - nacl_values = [t.values() for t in nacl['NetworkAcls'][0]['Tags']] - nacl_tags = [item for sublist in nacl_values for item in sublist] - tag_values = [[key, str(value)] for key, value in tags.items()] - tags = [item for sublist in tag_values for item in sublist] - if sorted(nacl_tags) == sorted(tags): - changed = False - return changed - else: - delete_tags(nacl_id, client, module) - create_tags(nacl_id, client, module) - changed = True - return changed - return changed + + if name is None and tags is None: + return False + + if module.params.get('tags') is None: + # Only purge tags if tags is explicitly set to {} and purge_tags is True + purge_tags = False + + new_tags = dict() + if module.params.get('name') is not None: + new_tags['Name'] = module.params.get('name') + new_tags.update(module.params.get('tags') or {}) + + return ensure_ec2_tags(client, module, nacl_id, tags=new_tags, + purge_tags=purge_tags, retry_codes=['InvalidNetworkAclID.NotFound']) def rules_changed(aws_rules, param_rules, Egress, nacl_id, client, module): @@ -340,9 +327,12 @@ def setup_network_acl(client, module): changed = False nacl = describe_network_acl(client, module) if not nacl['NetworkAcls']: - nacl = create_network_acl(module.params.get('vpc_id'), client, module) + tags = {} + if module.params.get('name'): + tags['Name'] = module.params.get('name') + tags.update(module.params.get('tags') or {}) + nacl = create_network_acl(module.params.get('vpc_id'), client, module, tags) nacl_id = nacl['NetworkAcl']['NetworkAclId'] - create_tags(nacl_id, client, module) subnets = subnets_to_associate(nacl, client, module) replace_network_acl_association(nacl_id, subnets, client, module) construct_acl_entries(nacl, client, module) @@ -389,12 +379,15 @@ def _create_network_acl(client, *args, **kwargs): return client.create_network_acl(*args, **kwargs) -def create_network_acl(vpc_id, client, module): +def create_network_acl(vpc_id, client, module, tags): + params = dict(VpcId=vpc_id) + if tags: + params['TagSpecifications'] = boto3_tag_specifications(tags, ['network-acl']) try: if module.check_mode: nacl = dict(NetworkAcl=dict(NetworkAclId="nacl-00000000")) else: - nacl = _create_network_acl(client, VpcId=vpc_id) + nacl = _create_network_acl(client, **params) except botocore.exceptions.ClientError as e: module.fail_json_aws(e) return nacl @@ -413,20 +406,6 @@ def create_network_acl_entry(params, client, module): module.fail_json_aws(e) -@AWSRetry.jittered_backoff(catch_extra_error_codes=['InvalidNetworkAclID.NotFound']) -def _create_tags(client, *args, **kwargs): - return client.create_tags(*args, **kwargs) - - -def create_tags(nacl_id, client, module): - try: - delete_tags(nacl_id, client, module) - if not module.check_mode: - _create_tags(client, Resources=[nacl_id], Tags=load_tags(module)) - except botocore.exceptions.ClientError as e: - module.fail_json_aws(e) - - @AWSRetry.jittered_backoff() def _delete_network_acl(client, *args, **kwargs): return client.delete_network_acl(*args, **kwargs) @@ -453,19 +432,6 @@ def delete_network_acl_entry(params, client, module): module.fail_json_aws(e) -@AWSRetry.jittered_backoff(catch_extra_error_codes=['InvalidNetworkAclID.NotFound']) -def _delete_tags(client, *args, **kwargs): - return client.delete_tags(*args, **kwargs) - - -def delete_tags(nacl_id, client, module): - try: - if not module.check_mode: - _delete_tags(client, Resources=[nacl_id]) - except botocore.exceptions.ClientError as e: - module.fail_json_aws(e) - - @AWSRetry.jittered_backoff() def _describe_network_acls(client, **kwargs): return client.describe_network_acls(**kwargs) @@ -614,7 +580,8 @@ def main(): name=dict(), nacl_id=dict(), subnets=dict(required=False, type='list', default=list(), elements='str'), - tags=dict(required=False, type='dict'), + tags=dict(required=False, type='dict', aliases=['resource_tags']), + purge_tags=dict(required=False, type='bool', default=True), ingress=dict(required=False, type='list', default=list(), elements='list'), egress=dict(required=False, type='list', default=list(), elements='list'), state=dict(default='present', choices=['present', 'absent']), diff --git a/tests/integration/targets/ec2_vpc_nacl/aliases b/tests/integration/targets/ec2_vpc_nacl/aliases index 4c474104da5..04109c2687b 100644 --- a/tests/integration/targets/ec2_vpc_nacl/aliases +++ b/tests/integration/targets/ec2_vpc_nacl/aliases @@ -1,6 +1,3 @@ -# https://github.com/ansible-collections/community.aws/issues/153 -unstable - cloud/aws ec2_vpc_nacl_info diff --git a/tests/integration/targets/ec2_vpc_nacl/defaults/main.yml b/tests/integration/targets/ec2_vpc_nacl/defaults/main.yml new file mode 100644 index 00000000000..5ac931209fb --- /dev/null +++ b/tests/integration/targets/ec2_vpc_nacl/defaults/main.yml @@ -0,0 +1,12 @@ +--- +vpc_name: '{{ resource_prefix }}-ec2-vpc-nacl' +nacl_name: '{{ resource_prefix }}-ec2-vpc-nacl' +subnet_name: '{{ resource_prefix }}-ec2-vpc-nacl' +vpc_cidr: '10.{{ 256 | random(seed=resource_prefix) }}.0.0/16' +subnet_1: '10.{{ 256 | random(seed=resource_prefix) }}.1.0/24' +subnet_2: '10.{{ 256 | random(seed=resource_prefix) }}.2.0/24' +subnet_3: '10.{{ 256 | random(seed=resource_prefix) }}.3.0/24' +subnet_4: '10.{{ 256 | random(seed=resource_prefix) }}.4.0/24' + +vpc_ipv6_cidr: '10.{{ 256 | random(seed=resource_prefix) }}.5.0/25' +vpc_ipv6_name: '{{ vpc_name }}-ipv6' diff --git a/tests/integration/targets/ec2_vpc_nacl/tasks/ingress_and_egress.yml b/tests/integration/targets/ec2_vpc_nacl/tasks/ingress_and_egress.yml index 4eb60791290..875e7f0b2d7 100644 --- a/tests/integration/targets/ec2_vpc_nacl/tasks/ingress_and_egress.yml +++ b/tests/integration/targets/ec2_vpc_nacl/tasks/ingress_and_egress.yml @@ -1,162 +1,158 @@ # ============================================================ - -- name: create ingress and egress rules using subnet IDs - ec2_vpc_nacl: - vpc_id: "{{ vpc_id }}" - name: "{{ resource_prefix }}-acl" - subnets: "{{ subnet_ids }}" - tags: - Created_by: "Ansible test {{ resource_prefix }}" - ingress: - - [100, 'tcp', 'allow', '0.0.0.0/0', null, null, 22, 22] - - [200, 'tcp', 'allow', '0.0.0.0/0', null, null, 80, 80] - - [300, 'icmp', 'allow', '0.0.0.0/0', 0, 8] - egress: - - [100, 'all', 'allow', '0.0.0.0/0', null, null, null, null] - state: 'present' - register: nacl - -- name: assert the network acl was created - assert: - that: - - nacl.changed - - nacl.nacl_id.startswith('acl-') - -- name: get network ACL facts - ec2_vpc_nacl_info: - nacl_ids: - - "{{ nacl.nacl_id }}" - register: nacl_facts - -- name: assert the nacl has the correct attributes - assert: - that: - - nacl_facts.nacls | length == 1 - - nacl_facts.nacls[0].ingress | length == 3 - - nacl_facts.nacls[0].egress | length == 1 - -# ============================================================ - -- name: remove an ingress rule - ec2_vpc_nacl: - vpc_id: "{{ vpc_id }}" - name: "{{ resource_prefix }}-acl" - subnets: "{{ subnet_ids }}" - tags: - Created_by: "Ansible test {{ resource_prefix }}" - ingress: - - [100, 'tcp', 'allow', '0.0.0.0/0', null, null, 22, 22] - - [200, 'tcp', 'allow', '0.0.0.0/0', null, null, 80, 80] - egress: - - [100, 'all', 'allow', '0.0.0.0/0', null, null, null, null] - state: 'present' - register: nacl - -- name: assert the network acl changed - assert: - that: - - nacl.changed - - nacl.nacl_id.startswith('acl-') - -- name: get network ACL facts - ec2_vpc_nacl_info: - nacl_ids: - - "{{ nacl.nacl_id }}" - register: nacl_facts - -- name: assert the nacl has the correct attributes - assert: - that: - - nacl_facts.nacls | length == 1 - - nacl_facts.nacls[0].ingress | length == 2 - - nacl_facts.nacls[0].egress | length == 1 - -# ============================================================ - -- name: remove the egress rule - ec2_vpc_nacl: - vpc_id: "{{ vpc_id }}" - name: "{{ resource_prefix }}-acl" - subnets: "{{ subnet_ids }}" - tags: - Created_by: "Ansible test {{ resource_prefix }}" - ingress: - - [100, 'tcp', 'allow', '0.0.0.0/0', null, null, 22, 22] - - [200, 'tcp', 'allow', '0.0.0.0/0', null, null, 80, 80] - egress: [] - state: 'present' - register: nacl - -- name: assert the network acl changed - assert: - that: - - nacl.changed - - nacl.nacl_id.startswith('acl-') - -- name: get network ACL facts - ec2_vpc_nacl_info: - nacl_ids: - - "{{ nacl.nacl_id }}" - register: nacl_facts - -- name: assert the nacl has the correct attributes - assert: - that: - - nacl_facts.nacls | length == 1 - - nacl_facts.nacls[0].ingress | length == 2 - - nacl_facts.nacls[0].egress | length == 0 - -# ============================================================ - -- name: add egress rules - ec2_vpc_nacl: - vpc_id: "{{ vpc_id }}" - name: "{{ resource_prefix }}-acl" - subnets: "{{ subnet_ids }}" - tags: - Created_by: "Ansible test {{ resource_prefix }}" - ingress: - - [100, 'tcp', 'allow', '0.0.0.0/0', null, null, 22, 22] - - [200, 'tcp', 'allow', '0.0.0.0/0', null, null, 80, 80] - egress: - - [100, 'tcp', 'allow', '10.0.0.0/24', null, null, 22, 22] - - [200, 'udp', 'allow', '10.0.0.0/24', null, null, 22, 22] - state: 'present' - register: nacl - -- name: assert the network acl changed - assert: - that: - - nacl.changed - - nacl.nacl_id.startswith('acl-') - -- name: get network ACL facts - ec2_vpc_nacl_info: - nacl_ids: - - "{{ nacl.nacl_id }}" - register: nacl_facts - -- name: assert the nacl has the correct attributes - assert: - that: - - nacl_facts.nacls | length == 1 - - nacl_facts.nacls[0].ingress | length == 2 - - nacl_facts.nacls[0].egress | length == 2 - -# ============================================================ - -- name: remove the network ACL - ec2_vpc_nacl: - vpc_id: "{{ vpc_id }}" - name: "{{ resource_prefix }}-acl" - state: absent - register: nacl - until: nacl is success - ignore_errors: yes - retries: 5 - delay: 5 - -- name: assert nacl was removed - assert: - that: - - nacl.changed +- block: + - name: create ingress and egress rules using subnet IDs + ec2_vpc_nacl: + vpc_id: "{{ vpc_id }}" + name: "{{ nacl_name }}" + subnets: "{{ subnet_ids }}" + tags: + Created_by: "Ansible test {{ resource_prefix }}" + ingress: + - [100, 'tcp', 'allow', '0.0.0.0/0', null, null, 22, 22] + - [200, 'tcp', 'allow', '0.0.0.0/0', null, null, 80, 80] + - [300, 'icmp', 'allow', '0.0.0.0/0', 0, 8] + egress: + - [100, 'all', 'allow', '0.0.0.0/0', null, null, null, null] + state: 'present' + register: nacl + + - name: assert the network acl was created + assert: + that: + - nacl.changed + - nacl.nacl_id.startswith('acl-') + + - name: get network ACL facts + ec2_vpc_nacl_info: + nacl_ids: + - "{{ nacl.nacl_id }}" + register: nacl_facts + + - name: assert the nacl has the correct attributes + assert: + that: + - nacl_facts.nacls | length == 1 + - nacl_facts.nacls[0].ingress | length == 3 + - nacl_facts.nacls[0].egress | length == 1 + + # ============================================================ + + - name: remove an ingress rule + ec2_vpc_nacl: + vpc_id: "{{ vpc_id }}" + name: "{{ nacl_name }}" + subnets: "{{ subnet_ids }}" + tags: + Created_by: "Ansible test {{ resource_prefix }}" + ingress: + - [100, 'tcp', 'allow', '0.0.0.0/0', null, null, 22, 22] + - [200, 'tcp', 'allow', '0.0.0.0/0', null, null, 80, 80] + egress: + - [100, 'all', 'allow', '0.0.0.0/0', null, null, null, null] + state: 'present' + register: nacl + + - name: assert the network acl changed + assert: + that: + - nacl.changed + - nacl.nacl_id.startswith('acl-') + + - name: get network ACL facts + ec2_vpc_nacl_info: + nacl_ids: + - "{{ nacl.nacl_id }}" + register: nacl_facts + + - name: assert the nacl has the correct attributes + assert: + that: + - nacl_facts.nacls | length == 1 + - nacl_facts.nacls[0].ingress | length == 2 + - nacl_facts.nacls[0].egress | length == 1 + + # ============================================================ + + - name: remove the egress rule + ec2_vpc_nacl: + vpc_id: "{{ vpc_id }}" + name: "{{ nacl_name }}" + subnets: "{{ subnet_ids }}" + tags: + Created_by: "Ansible test {{ resource_prefix }}" + ingress: + - [100, 'tcp', 'allow', '0.0.0.0/0', null, null, 22, 22] + - [200, 'tcp', 'allow', '0.0.0.0/0', null, null, 80, 80] + egress: [] + state: 'present' + register: nacl + + - name: assert the network acl changed + assert: + that: + - nacl.changed + - nacl.nacl_id.startswith('acl-') + + - name: get network ACL facts + ec2_vpc_nacl_info: + nacl_ids: + - "{{ nacl.nacl_id }}" + register: nacl_facts + + - name: assert the nacl has the correct attributes + assert: + that: + - nacl_facts.nacls | length == 1 + - nacl_facts.nacls[0].ingress | length == 2 + - nacl_facts.nacls[0].egress | length == 0 + + # ============================================================ + + - name: add egress rules + ec2_vpc_nacl: + vpc_id: "{{ vpc_id }}" + name: "{{ nacl_name }}" + subnets: "{{ subnet_ids }}" + tags: + Created_by: "Ansible test {{ resource_prefix }}" + ingress: + - [100, 'tcp', 'allow', '0.0.0.0/0', null, null, 22, 22] + - [200, 'tcp', 'allow', '0.0.0.0/0', null, null, 80, 80] + egress: + - [100, 'tcp', 'allow', '10.0.0.0/24', null, null, 22, 22] + - [200, 'udp', 'allow', '10.0.0.0/24', null, null, 22, 22] + state: 'present' + register: nacl + + - name: assert the network acl changed + assert: + that: + - nacl.changed + - nacl.nacl_id.startswith('acl-') + + - name: get network ACL facts + ec2_vpc_nacl_info: + nacl_ids: + - "{{ nacl.nacl_id }}" + register: nacl_facts + + - name: assert the nacl has the correct attributes + assert: + that: + - nacl_facts.nacls | length == 1 + - nacl_facts.nacls[0].ingress | length == 2 + - nacl_facts.nacls[0].egress | length == 2 + + # ============================================================ + + - name: remove the network ACL + ec2_vpc_nacl: + vpc_id: "{{ vpc_id }}" + name: "{{ nacl_name }}" + state: absent + register: nacl + + - name: assert nacl was removed + assert: + that: + - nacl.changed diff --git a/tests/integration/targets/ec2_vpc_nacl/tasks/ipv6.yml b/tests/integration/targets/ec2_vpc_nacl/tasks/ipv6.yml index 59634c0d429..1366971613a 100644 --- a/tests/integration/targets/ec2_vpc_nacl/tasks/ipv6.yml +++ b/tests/integration/targets/ec2_vpc_nacl/tasks/ipv6.yml @@ -1,39 +1,13 @@ - block: - - name: create a VPC - ec2_vpc_net: - cidr_block: 10.230.231.0/24 - name: "{{ resource_prefix }}-ipv6" - state: present - ipv6_cidr: yes - register: vpc_result - - - set_fact: - vpc_ipv6_cidr: "{{ vpc_result.vpc.ipv6_cidr_block_association_set[0].ipv6_cidr_block }}" - - # ============================================================ - - name: create subnet with IPv6 (expected changed=true) - ec2_vpc_subnet: - cidr: 10.230.231.0/26 - vpc_id: "{{ vpc_result.vpc.id }}" - ipv6_cidr: "{{ vpc_ipv6_cidr | regex_replace('::/56', '::/64') }}" - state: present - tags: - Name: "{{ resource_prefix }}-ipv6-subnet-1" - register: vpc_subnet_ipv6 - - - name: assert creation with IPv6 happened (expected changed=true) - assert: - that: - - "vpc_subnet_ipv6.subnet.ipv6_cidr_block == '{{ vpc_ipv6_cidr | regex_replace('::/56', '::/64') }}'" # ============================================================ - name: create ingress and egress rules using subnet names ec2_vpc_nacl: - vpc_id: "{{ vpc_result.vpc.id }}" - name: "{{ resource_prefix }}-acl" + vpc_id: "{{ vpc_ipv6_id }}" + name: "{{ nacl_name }}" subnets: - - "{{ resource_prefix }}-ipv6-subnet-1" + - "{{ subnet_name }}-ipv6" tags: Created_by: "Ansible test {{ resource_prefix }}" ingress: @@ -53,10 +27,10 @@ - name: add ipv6 entries ec2_vpc_nacl: - vpc_id: "{{ vpc_result.vpc.id }}" - name: "{{ resource_prefix }}-acl" + vpc_id: "{{ vpc_ipv6_id }}" + name: "{{ nacl_name }}" subnets: - - "{{ resource_prefix }}-ipv6-subnet-1" + - "{{ subnet_name }}-ipv6" tags: Created_by: "Ansible test {{ resource_prefix }}" ingress: @@ -91,10 +65,10 @@ - name: purge ingress entries ec2_vpc_nacl: - vpc_id: "{{ vpc_result.vpc.id }}" - name: "{{ resource_prefix }}-acl" + vpc_id: "{{ vpc_ipv6_id }}" + name: "{{ nacl_name }}" subnets: - - "{{ resource_prefix }}-ipv6-subnet-1" + - "{{ subnet_name }}-ipv6" tags: Created_by: "Ansible test {{ resource_prefix }}" ingress: [] @@ -111,10 +85,10 @@ - name: purge egress entries ec2_vpc_nacl: - vpc_id: "{{ vpc_result.vpc.id }}" - name: "{{ resource_prefix }}-acl" + vpc_id: "{{ vpc_ipv6_id }}" + name: "{{ nacl_name }}" subnets: - - "{{ resource_prefix }}-ipv6-subnet-1" + - "{{ subnet_name }}-ipv6" tags: Created_by: "Ansible test {{ resource_prefix }}" ingress: [] @@ -139,54 +113,12 @@ - nacl_facts.nacls[0].ingress | length == 0 - nacl_facts.nacls[0].egress | length == 0 - # ============================================================ - - name: remove subnet ipv6 cidr (expected changed=true) - ec2_vpc_subnet: - cidr: 10.230.231.0/26 - vpc_id: "{{ vpc_result.vpc.id }}" - state: absent - register: vpc_remove_ipv6_cidr - - - name: assert subnet ipv6 cidr removed (expected changed=true) - assert: - that: - - 'vpc_remove_ipv6_cidr.changed' - always: - ################################################ - # TEARDOWN STARTS HERE - ################################################ - - name: remove network ACL ec2_vpc_nacl: - vpc_id: "{{ vpc_result.vpc.id }}" - name: "{{ resource_prefix }}-acl" + vpc_id: "{{ vpc_ipv6_id }}" + name: "{{ nacl_name }}" state: absent register: removed_acl - until: removed_acl is success - retries: 5 - delay: 5 - ignore_errors: yes - - - name: tidy up subnet - ec2_vpc_subnet: - cidr: 10.230.231.0/26 - vpc_id: "{{ vpc_result.vpc.id }}" - state: absent - register: removed_subnet - until: removed_subnet is success - retries: 5 - delay: 5 - ignore_errors: yes - - - name: tidy up VPC - ec2_vpc_net: - name: "{{ resource_prefix }}-ipv6" - state: absent - cidr_block: 10.230.231.0/24 - register: removed_vpc - until: removed_vpc is success - retries: 5 - delay: 5 ignore_errors: yes diff --git a/tests/integration/targets/ec2_vpc_nacl/tasks/main.yml b/tests/integration/targets/ec2_vpc_nacl/tasks/main.yml index 7be79895473..e1538049aba 100644 --- a/tests/integration/targets/ec2_vpc_nacl/tasks/main.yml +++ b/tests/integration/targets/ec2_vpc_nacl/tasks/main.yml @@ -63,55 +63,75 @@ - name: create a VPC ec2_vpc_net: - cidr_block: 10.230.230.0/24 - name: "{{ resource_prefix }}" + cidr_block: "{{ vpc_cidr }}" + name: "{{ vpc_name }}" state: present register: vpc + - name: Save VPC ID for later + set_fact: + vpc_id: "{{ vpc.vpc.id }}" + - name: create subnets ec2_vpc_subnet: cidr: "{{ item.cidr }}" az: "{{ item.az }}" - vpc_id: "{{ vpc.vpc.id }}" + vpc_id: "{{ vpc_id }}" state: present tags: Name: "{{ item.name }}" with_items: - - cidr: 10.230.230.0/26 + - cidr: "{{ subnet_1 }}" az: "{{ az_one }}" - name: "{{ resource_prefix }}-subnet-1" - - cidr: 10.230.230.64/26 + name: "{{ subnet_name }}-1" + - cidr: "{{ subnet_2 }}" az: "{{ az_two }}" - name: "{{ resource_prefix }}-subnet-2" - - cidr: 10.230.230.128/26 + name: "{{ subnet_name }}-2" + - cidr: "{{ subnet_3 }}" az: "{{ az_one }}" - name: "{{ resource_prefix }}-subnet-3" - - cidr: 10.230.230.192/26 + name: "{{ subnet_name }}-3" + - cidr: "{{ subnet_4 }}" az: "{{ az_two }}" - name: "{{ resource_prefix }}-subnet-4" + name: "{{ subnet_name }}-4" register: subnets + - name: set helpful facts about subnets + set_fact: + subnet_ids: "{{ subnets | community.general.json_query('results[*].subnet.id') }}" + subnet_names: "{{ subnets | community.general.json_query('results[*].subnet.tags.Name') }}" + + - name: create VPC for IPv6 tests + ec2_vpc_net: + cidr_block: "{{ vpc_ipv6_cidr }}" + name: "{{ vpc_ipv6_name }}" + state: present + ipv6_cidr: yes + register: vpc_result + - set_fact: + vpc_ipv6_id: "{{ vpc_result.vpc.id }}" + vpc_ipv6_cidr_v6: "{{ _ipv6_cidr }}" + subnet_ipv6: "{{ _ipv6_cidr | regex_replace('::/56', '::/64') }}" + vars: + _ipv6_cidr: "{{ vpc_result.vpc.ipv6_cidr_block_association_set[0].ipv6_cidr_block }}" + + - name: create subnet with IPv6 + ec2_vpc_subnet: + cidr: "{{ vpc_ipv6_cidr }}" + vpc_id: "{{ vpc_ipv6_id }}" + ipv6_cidr: "{{ subnet_ipv6 }}" + state: present + tags: + Name: "{{ subnet_name }}-ipv6" + # ============================================================ - include_tasks: tasks/subnet_ids.yml - vars: - vpc_id: "{{ vpc.vpc.id }}" - subnet_ids: "{{ subnets | community.general.json_query('results[*].subnet.id') }}" - include_tasks: tasks/subnet_names.yml - vars: - vpc_id: "{{ vpc.vpc.id }}" - subnet_names: "{{ subnets | community.general.json_query('results[*].subnet.tags.Name') }}" - include_tasks: tasks/tags.yml - vars: - vpc_id: "{{ vpc.vpc.id }}" - subnet_ids: "{{ subnets | community.general.json_query('results[*].subnet.id') }}" - include_tasks: tasks/ingress_and_egress.yml - vars: - vpc_id: "{{ vpc.vpc.id }}" - subnet_ids: "{{ subnets | community.general.json_query('results[*].subnet.id') }}" - include_tasks: tasks/ipv6.yml @@ -121,52 +141,35 @@ - name: remove network ACL ec2_vpc_nacl: - vpc_id: "{{ vpc.vpc.id }}" - name: "{{ resource_prefix }}-acl" + vpc_id: "{{ vpc_id }}" + name: "{{ nacl_name }}" state: absent register: removed_acl - until: removed_acl is success - retries: 5 - delay: 5 ignore_errors: yes - name: remove subnets ec2_vpc_subnet: cidr: "{{ item.cidr }}" - az: "{{ aws_region}}{{ item.az }}" - vpc_id: "{{ vpc.vpc.id }}" + vpc_id: "{{ item.vpc_id | default(vpc_id) }}" state: absent - tags: - Public: "{{ item.public | string }}" - Name: "{{ item.public | ternary('public', 'private') }}-{{ item.az }}" with_items: - - cidr: 10.230.230.0/26 - az: "a" - public: "True" - - cidr: 10.230.230.64/26 - az: "b" - public: "True" - - cidr: 10.230.230.128/26 - az: "a" - public: "False" - - cidr: 10.230.230.192/26 - az: "b" - public: "False" + - cidr: "{{ subnet_1 }}" + - cidr: "{{ subnet_2 }}" + - cidr: "{{ subnet_3 }}" + - cidr: "{{ subnet_4 }}" + - cidr: "{{ vpc_ipv6_cidr }}" + vpc_id: "{{ vpc_ipv6_id }}" ignore_errors: yes register: removed_subnets - until: removed_subnets is success - retries: 5 - delay: 5 - - name: remove the VPC + - name: remove the VPCs ec2_vpc_net: - cidr_block: 10.230.230.0/24 - name: "{{ resource_prefix }}" + vpc_id: "{{ item }}" state: absent ignore_errors: yes register: removed_vpc - until: removed_vpc is success - retries: 5 - delay: 5 + with_items: + - '{{ vpc_id }}' + - '{{ vpc_ipv6_id }}' # ============================================================ diff --git a/tests/integration/targets/ec2_vpc_nacl/tasks/subnet_ids.yml b/tests/integration/targets/ec2_vpc_nacl/tasks/subnet_ids.yml index de371d629ae..4e1affa1f34 100644 --- a/tests/integration/targets/ec2_vpc_nacl/tasks/subnet_ids.yml +++ b/tests/integration/targets/ec2_vpc_nacl/tasks/subnet_ids.yml @@ -3,7 +3,7 @@ - name: create ingress and egress rules using subnet IDs ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" - name: "{{ resource_prefix }}-acl" + name: "{{ nacl_name }}" subnets: "{{ subnet_ids }}" tags: Created_by: "Ansible test {{ resource_prefix }}" @@ -40,14 +40,14 @@ - nacl_facts.nacls[0].subnets | sort == subnet_ids | sort - nacl_facts.nacls[0].ingress | length == 3 - nacl_facts.nacls[0].egress | length == 1 - - "'{{ nacl_facts.nacls[0].tags.Name }}' == '{{ resource_prefix }}-acl'" + - nacl_facts.nacls[0].tags.Name == nacl_name # ============================================================ - name: test idempotence ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" - name: "{{ resource_prefix }}-acl" + name: "{{ nacl_name }}" subnets: "{{ subnet_ids }}" tags: Created_by: "Ansible test {{ resource_prefix }}" @@ -83,7 +83,7 @@ - name: remove a subnet from the network ACL ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" - name: "{{ resource_prefix }}-acl" + name: "{{ nacl_name }}" subnets: - "{{ subnet_ids[0] }}" - "{{ subnet_ids[1] }}" @@ -121,20 +121,16 @@ - subnet_ids[3] not in nacl_facts.nacls[0].subnets - nacl_facts.nacls[0].ingress | length == 3 - nacl_facts.nacls[0].egress | length == 1 - - "'{{ nacl_facts.nacls[0].tags.Name }}' == '{{ resource_prefix }}-acl'" + - nacl_facts.nacls[0].tags.Name == nacl_name # ============================================================ - name: remove the network ACL ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" - name: "{{ resource_prefix }}-acl" + name: "{{ nacl_name }}" state: absent register: nacl - until: nacl is success - ignore_errors: yes - retries: 5 - delay: 5 - name: assert nacl was removed assert: @@ -144,14 +140,9 @@ - name: re-remove the network ACL by name (test idempotency) ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" - name: "{{ resource_prefix }}-acl" + name: "{{ nacl_name }}" state: absent register: nacl - until: nacl is success - ignore_errors: yes - retries: 5 - delay: 5 - - name: assert nacl was removed assert: that: @@ -163,10 +154,6 @@ nacl_id: "{{ nacl_id }}" state: absent register: nacl - until: nacl is success - ignore_errors: yes - retries: 5 - delay: 5 - name: assert nacl was removed assert: diff --git a/tests/integration/targets/ec2_vpc_nacl/tasks/subnet_names.yml b/tests/integration/targets/ec2_vpc_nacl/tasks/subnet_names.yml index 5a4db04df92..4db7e1b2068 100644 --- a/tests/integration/targets/ec2_vpc_nacl/tasks/subnet_names.yml +++ b/tests/integration/targets/ec2_vpc_nacl/tasks/subnet_names.yml @@ -3,7 +3,7 @@ - name: create ingress and egress rules using subnet names ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" - name: "{{ resource_prefix }}-acl" + name: "{{ nacl_name }}" subnets: "{{ subnet_names }}" tags: Created_by: "Ansible test {{ resource_prefix }}" @@ -39,14 +39,14 @@ - nacl_facts.nacls[0].subnets | length == 4 - nacl_facts.nacls[0].ingress | length == 3 - nacl_facts.nacls[0].egress | length == 1 - - "'{{ nacl_facts.nacls[0].tags.Name }}' == '{{ resource_prefix }}-acl'" + - nacl_facts.nacls[0].tags.Name == nacl_name # ============================================================ - name: test idempotence ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" - name: "{{ resource_prefix }}-acl" + name: "{{ nacl_name }}" subnets: "{{ subnet_names }}" tags: Created_by: "Ansible test {{ resource_prefix }}" @@ -82,7 +82,7 @@ - name: remove a subnet from the network ACL ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" - name: "{{ resource_prefix }}-acl" + name: "{{ nacl_name }}" subnets: - "{{ subnet_names[0] }}" - "{{ subnet_names[1] }}" @@ -119,20 +119,16 @@ - nacl_facts.nacls[0].subnets | length == 3 - nacl_facts.nacls[0].ingress | length == 3 - nacl_facts.nacls[0].egress | length == 1 - - "'{{ nacl_facts.nacls[0].tags.Name }}' == '{{ resource_prefix }}-acl'" + - nacl_facts.nacls[0].tags.Name == nacl_name # ============================================================ - name: remove the network ACL ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" - name: "{{ resource_prefix }}-acl" + name: "{{ nacl_name }}" state: absent register: nacl - until: nacl is success - ignore_errors: yes - retries: 5 - delay: 5 - name: assert nacl was removed assert: diff --git a/tests/integration/targets/ec2_vpc_nacl/tasks/tags.yml b/tests/integration/targets/ec2_vpc_nacl/tasks/tags.yml index f7847850a58..da3ad71dda3 100644 --- a/tests/integration/targets/ec2_vpc_nacl/tasks/tags.yml +++ b/tests/integration/targets/ec2_vpc_nacl/tasks/tags.yml @@ -1,117 +1,445 @@ -# ============================================================ - -- name: create a network ACL using subnet IDs - ec2_vpc_nacl: - vpc_id: "{{ vpc_id }}" - name: "{{ resource_prefix }}-acl" - subnets: "{{ subnet_ids }}" - state: 'present' - register: nacl - -- name: assert the network acl was created - assert: - that: - - nacl.changed - - nacl.nacl_id.startswith('acl-') - -- name: get network ACL facts - ec2_vpc_nacl_info: - nacl_ids: - - "{{ nacl.nacl_id }}" - register: nacl_facts - -- name: assert the nacl has the correct attributes - assert: - that: - - nacl_facts.nacls[0].tags | length == 1 - - "'{{ nacl_facts.nacls[0].tags.Name }}' == '{{ resource_prefix }}-acl'" - -# ============================================================ - -- name: add a tag - ec2_vpc_nacl: - vpc_id: "{{ vpc_id }}" - name: "{{ resource_prefix }}-acl" - subnets: "{{ subnet_ids }}" - tags: - Created_by: "Ansible test {{ resource_prefix }}" - state: 'present' - register: nacl - -- name: assert the network acl changed - assert: - that: - - nacl.changed - -- name: get network ACL facts - ec2_vpc_nacl_info: - nacl_ids: - - "{{ nacl.nacl_id }}" - register: nacl_facts - -- name: assert the facts are the same as before - assert: - that: - - nacl_facts.nacls[0].tags | length == 2 - - "'{{ nacl_facts.nacls[0].tags.Name }}' == '{{ resource_prefix }}-acl'" - - "'{{ nacl_facts.nacls[0].tags.Created_by }}' == 'Ansible test {{ resource_prefix }}'" - -- name: get network ACL facts by filter - ec2_vpc_nacl_info: - filters: - "tag:Created_by": "Ansible test {{ resource_prefix }}" - register: nacl_facts - -- name: assert the facts are the same as before - assert: - that: - - nacl_facts.nacls | length == 1 - - nacl_facts.nacls[0].tags | length == 2 - - "'{{ nacl_facts.nacls[0].tags.Name }}' == '{{ resource_prefix }}-acl'" - - "'{{ nacl_facts.nacls[0].tags.Created_by }}' == 'Ansible test {{ resource_prefix }}'" - -# ============================================================ - -- name: remove a tag - ec2_vpc_nacl: - vpc_id: "{{ vpc_id }}" - name: "{{ resource_prefix }}-acl" - subnets: "{{ subnet_ids }}" - state: 'present' - register: nacl - -- name: assert the network acl was created - assert: - that: - - nacl.changed - - nacl.nacl_id.startswith('acl-') - -- name: get network ACL facts - ec2_vpc_nacl_info: - nacl_ids: - - "{{ nacl.nacl_id }}" - register: nacl_facts - -- name: assert the nacl has the correct attributes - assert: - that: - - nacl_facts.nacls[0].tags | length == 1 - - "'{{ nacl_facts.nacls[0].tags.Name }}' == '{{ resource_prefix }}-acl'" - -# ============================================================ - -- name: remove the network ACL - ec2_vpc_nacl: - vpc_id: "{{ vpc_id }}" - name: "{{ resource_prefix }}-acl" - state: absent - register: nacl - until: nacl is success - ignore_errors: yes - retries: 5 - delay: 5 - -- name: assert nacl was removed - assert: - that: - - nacl.changed +- vars: + first_tags: + 'Key with Spaces': Value with spaces + CamelCaseKey: CamelCaseValue + pascalCaseKey: pascalCaseValue + snake_case_key: snake_case_value + second_tags: + 'New Key with Spaces': Value with spaces + NewCamelCaseKey: CamelCaseValue + newPascalCaseKey: pascalCaseValue + new_snake_case_key: snake_case_value + third_tags: + 'Key with Spaces': Value with spaces + CamelCaseKey: CamelCaseValue + pascalCaseKey: pascalCaseValue + snake_case_key: snake_case_value + 'New Key with Spaces': Updated Value with spaces + final_tags: + 'Key with Spaces': Value with spaces + CamelCaseKey: CamelCaseValue + pascalCaseKey: pascalCaseValue + snake_case_key: snake_case_value + 'New Key with Spaces': Updated Value with spaces + NewCamelCaseKey: CamelCaseValue + newPascalCaseKey: pascalCaseValue + new_snake_case_key: snake_case_value + name_tags: + Name: '{{ nacl_name }}' + block: + + # ============================================================ + + - name: create a network ACL using subnet IDs + ec2_vpc_nacl: + vpc_id: "{{ vpc_id }}" + name: "{{ nacl_name }}" + subnets: "{{ subnet_ids }}" + state: 'present' + register: nacl + + - name: assert the network acl was created + assert: + that: + - nacl.changed + - nacl.nacl_id.startswith('acl-') + + - name: Store NACL ID + set_fact: + nacl_id: '{{ nacl.nacl_id }}' + + - name: get network ACL facts + ec2_vpc_nacl_info: + nacl_ids: + - "{{ nacl_id }}" + register: nacl_info + + - name: assert the nacl has the correct attributes + assert: + that: + - nacl_info.nacls[0].nacl_id == nacl_id + - nacl_info.nacls[0].tags == name_tags + + # ============================================================ + + - name: (check) add tags + ec2_vpc_nacl: + vpc_id: "{{ vpc_id }}" + name: "{{ nacl_name }}" + subnets: "{{ subnet_ids }}" + tags: "{{ first_tags }}" + state: 'present' + register: nacl + check_mode: True + + - name: assert would change + assert: + that: + - nacl is changed + - nacl.nacl_id == nacl_id + + - name: add tags + ec2_vpc_nacl: + vpc_id: "{{ vpc_id }}" + name: "{{ nacl_name }}" + subnets: "{{ subnet_ids }}" + tags: "{{ first_tags }}" + state: 'present' + register: nacl + - name: get network ACL facts + ec2_vpc_nacl_info: + nacl_ids: + - "{{ nacl.nacl_id }}" + register: nacl_info + + - name: verify the tags were added + assert: + that: + - nacl is changed + - nacl.nacl_id == nacl_id + - nacl_info.nacls[0].nacl_id == nacl_id + - nacl_info.nacls[0].tags == ( first_tags | combine(name_tags) ) + + - name: (check) add tags - IDEMPOTENCY + ec2_vpc_nacl: + vpc_id: "{{ vpc_id }}" + name: "{{ nacl_name }}" + subnets: "{{ subnet_ids }}" + tags: "{{ first_tags }}" + state: 'present' + register: nacl + check_mode: True + + - name: assert would not change + assert: + that: + - nacl is not changed + - nacl.nacl_id == nacl_id + + - name: add tags - IDEMPOTENCY + ec2_vpc_nacl: + vpc_id: "{{ vpc_id }}" + name: "{{ nacl_name }}" + subnets: "{{ subnet_ids }}" + tags: "{{ first_tags }}" + state: 'present' + register: nacl + - name: get network ACL facts + ec2_vpc_nacl_info: + nacl_ids: + - "{{ nacl.nacl_id }}" + register: nacl_info + + - name: verify no change + assert: + that: + - nacl is not changed + - nacl.nacl_id == nacl_id + - nacl_info.nacls[0].nacl_id == nacl_id + - nacl_info.nacls[0].tags == ( first_tags | combine(name_tags) ) + + # ============================================================ + + - name: get network ACL facts by filter + ec2_vpc_nacl_info: + filters: + "tag:Name": "{{ nacl_name }}" + register: nacl_info + + - name: assert the facts are the same as before + assert: + that: + - nacl_info.nacls | length == 1 + - nacl.nacl_id == nacl_id + - nacl_info.nacls[0].nacl_id == nacl_id + + # ============================================================ + + - name: (check) modify tags with purge + ec2_vpc_nacl: + vpc_id: "{{ vpc_id }}" + name: "{{ nacl_name }}" + subnets: "{{ subnet_ids }}" + tags: "{{ second_tags }}" + state: 'present' + register: nacl + check_mode: True + + - name: assert would change + assert: + that: + - nacl is changed + - nacl.nacl_id == nacl_id + + - name: modify tags with purge + ec2_vpc_nacl: + vpc_id: "{{ vpc_id }}" + name: "{{ nacl_name }}" + subnets: "{{ subnet_ids }}" + tags: "{{ second_tags }}" + state: 'present' + register: nacl + - name: get network ACL facts + ec2_vpc_nacl_info: + nacl_ids: + - "{{ nacl.nacl_id }}" + register: nacl_info + + - name: verify the tags were added + assert: + that: + - nacl is changed + - nacl.nacl_id == nacl_id + - nacl_info.nacls[0].nacl_id == nacl_id + - nacl_info.nacls[0].tags == ( second_tags | combine(name_tags) ) + + - name: (check) modify tags with purge - IDEMPOTENCY + ec2_vpc_nacl: + vpc_id: "{{ vpc_id }}" + name: "{{ nacl_name }}" + subnets: "{{ subnet_ids }}" + tags: "{{ second_tags }}" + state: 'present' + register: nacl + check_mode: True + + - name: assert would not change + assert: + that: + - nacl is not changed + - nacl.nacl_id == nacl_id + + - name: modify tags with purge - IDEMPOTENCY + ec2_vpc_nacl: + vpc_id: "{{ vpc_id }}" + name: "{{ nacl_name }}" + subnets: "{{ subnet_ids }}" + tags: "{{ second_tags }}" + state: 'present' + register: nacl + - name: get network ACL facts + ec2_vpc_nacl_info: + nacl_ids: + - "{{ nacl.nacl_id }}" + register: nacl_info + + - name: verify no change + assert: + that: + - nacl is not changed + - nacl.nacl_id == nacl_id + - nacl_info.nacls[0].nacl_id == nacl_id + - nacl_info.nacls[0].tags == ( second_tags | combine(name_tags) ) + + # ============================================================ + + - name: (check) modify tags without purge + ec2_vpc_nacl: + vpc_id: "{{ vpc_id }}" + name: "{{ nacl_name }}" + subnets: "{{ subnet_ids }}" + tags: "{{ third_tags }}" + state: 'present' + purge_tags: False + register: nacl + check_mode: True + + - name: assert would change + assert: + that: + - nacl is changed + - nacl.nacl_id == nacl_id + + - name: modify tags without purge + ec2_vpc_nacl: + vpc_id: "{{ vpc_id }}" + name: "{{ nacl_name }}" + subnets: "{{ subnet_ids }}" + tags: "{{ third_tags }}" + state: 'present' + purge_tags: False + register: nacl + - name: get network ACL facts + ec2_vpc_nacl_info: + nacl_ids: + - "{{ nacl.nacl_id }}" + register: nacl_info + + - name: verify the tags were added + assert: + that: + - nacl is changed + - nacl.nacl_id == nacl_id + - nacl_info.nacls[0].nacl_id == nacl_id + - nacl_info.nacls[0].tags == ( final_tags | combine(name_tags) ) + + - name: (check) modify tags without purge - IDEMPOTENCY + ec2_vpc_nacl: + vpc_id: "{{ vpc_id }}" + name: "{{ nacl_name }}" + subnets: "{{ subnet_ids }}" + tags: "{{ third_tags }}" + state: 'present' + purge_tags: False + register: nacl + check_mode: True + + - name: assert would not change + assert: + that: + - nacl is not changed + - nacl.nacl_id == nacl_id + + - name: modify tags without purge - IDEMPOTENCY + ec2_vpc_nacl: + vpc_id: "{{ vpc_id }}" + name: "{{ nacl_name }}" + subnets: "{{ subnet_ids }}" + tags: "{{ third_tags }}" + state: 'present' + purge_tags: False + register: nacl + - name: get network ACL facts + ec2_vpc_nacl_info: + nacl_ids: + - "{{ nacl.nacl_id }}" + register: nacl_info + + - name: verify no change + assert: + that: + - nacl is not changed + - nacl.nacl_id == nacl_id + - nacl_info.nacls[0].nacl_id == nacl_id + - nacl_info.nacls[0].tags == ( final_tags | combine(name_tags) ) + + # ============================================================ + + - name: (check) No change to tags without setting tags + ec2_vpc_nacl: + vpc_id: "{{ vpc_id }}" + name: "{{ nacl_name }}" + subnets: "{{ subnet_ids }}" + state: 'present' + register: nacl + check_mode: True + + - name: assert would change + assert: + that: + - nacl is not changed + - nacl.nacl_id == nacl_id + + - name: No change to tags without setting tags + ec2_vpc_nacl: + vpc_id: "{{ vpc_id }}" + name: "{{ nacl_name }}" + subnets: "{{ subnet_ids }}" + state: 'present' + register: nacl + - name: get network ACL facts + ec2_vpc_nacl_info: + nacl_ids: + - "{{ nacl.nacl_id }}" + register: nacl_info + + - name: verify the tags were added + assert: + that: + - nacl is not changed + - nacl.nacl_id == nacl_id + - nacl_info.nacls[0].nacl_id == nacl_id + - nacl_info.nacls[0].tags == ( final_tags | combine(name_tags) ) + + # ============================================================ + + - name: (check) remove non name tags + ec2_vpc_nacl: + vpc_id: "{{ vpc_id }}" + name: "{{ nacl_name }}" + subnets: "{{ subnet_ids }}" + tags: {} + state: 'present' + register: nacl + check_mode: True + + - name: assert would change + assert: + that: + - nacl is changed + - nacl.nacl_id == nacl_id + + - name: remove non name tags + ec2_vpc_nacl: + vpc_id: "{{ vpc_id }}" + name: "{{ nacl_name }}" + subnets: "{{ subnet_ids }}" + tags: {} + state: 'present' + register: nacl + - name: get network ACL facts + ec2_vpc_nacl_info: + nacl_ids: + - "{{ nacl.nacl_id }}" + register: nacl_info + + - name: verify the tags were added + assert: + that: + - nacl is changed + - nacl.nacl_id == nacl_id + - nacl_info.nacls[0].nacl_id == nacl_id + - nacl_info.nacls[0].tags == name_tags + + - name: (check) remove non name tags - IDEMPOTENCY + ec2_vpc_nacl: + vpc_id: "{{ vpc_id }}" + name: "{{ nacl_name }}" + subnets: "{{ subnet_ids }}" + tags: {} + state: 'present' + register: nacl + check_mode: True + + - name: assert would not change + assert: + that: + - nacl is not changed + - nacl.nacl_id == nacl_id + + - name: remove non name tags - IDEMPOTENCY + ec2_vpc_nacl: + vpc_id: "{{ vpc_id }}" + name: "{{ nacl_name }}" + subnets: "{{ subnet_ids }}" + tags: {} + state: 'present' + register: nacl + - name: get network ACL facts + ec2_vpc_nacl_info: + nacl_ids: + - "{{ nacl.nacl_id }}" + register: nacl_info + + - name: verify no change + assert: + that: + - nacl is not changed + - nacl.nacl_id == nacl_id + - nacl_info.nacls[0].nacl_id == nacl_id + - nacl_info.nacls[0].tags == name_tags + + # ============================================================ + + always: + - name: remove the network ACL + ec2_vpc_nacl: + vpc_id: "{{ vpc_id }}" + name: "{{ nacl_name }}" + state: absent + register: nacl + + - name: assert nacl was removed + assert: + that: + - nacl.changed From 0a40d320c25ec9f43527ee2eec3029e9183e4b41 Mon Sep 17 00:00:00 2001 From: Mark Chappell Date: Mon, 15 Aug 2022 20:39:10 +0200 Subject: [PATCH 20/34] Minor sanity test fixes. (#1410) Minor sanity test fixes (new devel) SUMMARY ansible-devel has added a new PEP test (missing whitespace after keyword), this adds the fixes before the devel sanity tests are 'voting'. Additionally fixes: unused variables broad catching of Exception ISSUE TYPE Bugfix Pull Request COMPONENT NAME plugins/modules/autoscaling_group_info.py plugins/modules/cloudfront_distribution.py plugins/modules/cloudfront_origin_access_identity.py plugins/modules/cloudtrail.py plugins/modules/ec2_vpc_nacl.py plugins/modules/eks_fargate_profile.py plugins/modules/redshift.py plugins/modules/s3_bucket_info.py ADDITIONAL INFORMATION cloudfront_distribution still has a lot of catch Exception but it's part of parameter validation which should be overhauled separately, unfortunately the tests are rather b0rked. Reviewed-by: Alina Buzachis This commit was initially merged in https://github.com/ansible-collections/community.aws See: https://github.com/ansible-collections/community.aws/commit/3d4736bb8c0fa47159a961fdc0d13ed2184b4823 --- plugins/modules/ec2_vpc_nacl.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/plugins/modules/ec2_vpc_nacl.py b/plugins/modules/ec2_vpc_nacl.py index 9968e2929ff..03cdef89c39 100644 --- a/plugins/modules/ec2_vpc_nacl.py +++ b/plugins/modules/ec2_vpc_nacl.py @@ -235,7 +235,6 @@ def tags_changed(nacl_id, client, module): tags = module.params.get('tags') name = module.params.get('name') purge_tags = module.params.get('purge_tags') - changed = False if name is None and tags is None: return False @@ -337,14 +336,14 @@ def setup_network_acl(client, module): replace_network_acl_association(nacl_id, subnets, client, module) construct_acl_entries(nacl, client, module) changed = True - return(changed, nacl['NetworkAcl']['NetworkAclId']) + return changed, nacl['NetworkAcl']['NetworkAclId'] else: changed = False nacl_id = nacl['NetworkAcls'][0]['NetworkAclId'] changed |= subnets_changed(nacl, client, module) changed |= nacls_changed(nacl, client, module) changed |= tags_changed(nacl_id, client, module) - return (changed, nacl_id) + return changed, nacl_id def remove_network_acl(client, module): From 68dae23d151757beef4195c558f498b7bfdffeee Mon Sep 17 00:00:00 2001 From: Alina Buzachis Date: Wed, 5 Oct 2022 17:04:40 +0200 Subject: [PATCH 21/34] Update extends_documentation_fragment with amazon.aws.boto3 (#1459) Update extends_documentation_fragment with amazon.aws.boto3 Depends-On: ansible/ansible-zuul-jobs#1654 SUMMARY As per ansible-collections/amazon.aws#985 add amazon.aws.boto3. ISSUE TYPE Docs Pull Request COMPONENT NAME several Reviewed-by: Jill R Reviewed-by: Mark Chappell Reviewed-by: Markus Bergholz This commit was initially merged in https://github.com/ansible-collections/community.aws See: https://github.com/ansible-collections/community.aws/commit/bd3c03fcba0848f593b86309740fa73e986a9646 --- plugins/modules/ec2_vpc_nacl.py | 1 + plugins/modules/ec2_vpc_nacl_info.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/modules/ec2_vpc_nacl.py b/plugins/modules/ec2_vpc_nacl.py index 03cdef89c39..85f8d8baa92 100644 --- a/plugins/modules/ec2_vpc_nacl.py +++ b/plugins/modules/ec2_vpc_nacl.py @@ -76,6 +76,7 @@ extends_documentation_fragment: - amazon.aws.aws - amazon.aws.ec2 + - amazon.aws.boto3 - amazon.aws.tags notes: - Support for I(purge_tags) was added in release 4.0.0. diff --git a/plugins/modules/ec2_vpc_nacl_info.py b/plugins/modules/ec2_vpc_nacl_info.py index b8d256470ee..b85c9423663 100644 --- a/plugins/modules/ec2_vpc_nacl_info.py +++ b/plugins/modules/ec2_vpc_nacl_info.py @@ -36,7 +36,7 @@ extends_documentation_fragment: - amazon.aws.aws - amazon.aws.ec2 - +- amazon.aws.boto3 ''' EXAMPLES = r''' From d027327af379f7df0a1eeac047b8160eacd87497 Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Wed, 2 Nov 2022 11:49:57 +0100 Subject: [PATCH 22/34] Fix non-matching defaults in docs (#1576) Fix non-matching defaults in docs Depends-On: #1579 SUMMARY Fix various non-matching default values exposed by ansible/ansible#79267. ISSUE TYPE Docs Pull Request COMPONENT NAME various Reviewed-by: Markus Bergholz This commit was initially merged in https://github.com/ansible-collections/community.aws See: https://github.com/ansible-collections/community.aws/commit/15568f01dc839983dc5c79b78f26b53a93fa72ee --- plugins/modules/ec2_vpc_nacl.py | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/modules/ec2_vpc_nacl.py b/plugins/modules/ec2_vpc_nacl.py index 85f8d8baa92..e11df3de532 100644 --- a/plugins/modules/ec2_vpc_nacl.py +++ b/plugins/modules/ec2_vpc_nacl.py @@ -40,6 +40,7 @@ required: false type: list elements: str + default: [] egress: description: - A list of rules for outgoing traffic. Each rule must be specified as a list. From df403243078e0cc34ca48d86696e9b8864a4a44e Mon Sep 17 00:00:00 2001 From: Bikouo Aubin <79859644+abikouo@users.noreply.github.com> Date: Tue, 10 Jan 2023 19:22:13 +0100 Subject: [PATCH 23/34] Ansible User-Agent identification for community.aws (#1632) Ansible User-Agent identification for community.aws SUMMARY The value will be similar to this APN/1.0 Ansible/2.14.1 community.aws/6.0.0-dev0 ISSUE TYPE Feature Pull Request Reviewed-by: Mark Chappell Reviewed-by: Bikouo Aubin Reviewed-by: Alina Buzachis This commit was initially merged in https://github.com/ansible-collections/community.aws See: https://github.com/ansible-collections/community.aws/commit/a8cbce24071bcc62fe4594c38aff1baf18bd2862 --- plugins/modules/ec2_vpc_nacl.py | 2 +- plugins/modules/ec2_vpc_nacl_info.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/modules/ec2_vpc_nacl.py b/plugins/modules/ec2_vpc_nacl.py index e11df3de532..3b10a0a66f9 100644 --- a/plugins/modules/ec2_vpc_nacl.py +++ b/plugins/modules/ec2_vpc_nacl.py @@ -159,7 +159,7 @@ except ImportError: pass # Handled by AnsibleAWSModule -from ansible_collections.amazon.aws.plugins.module_utils.core import AnsibleAWSModule +from ansible_collections.community.aws.plugins.module_utils.modules import AnsibleCommunityAWSModule as AnsibleAWSModule from ansible_collections.amazon.aws.plugins.module_utils.ec2 import AWSRetry from ansible_collections.amazon.aws.plugins.module_utils.ec2 import ensure_ec2_tags from ansible_collections.amazon.aws.plugins.module_utils.tagging import boto3_tag_specifications diff --git a/plugins/modules/ec2_vpc_nacl_info.py b/plugins/modules/ec2_vpc_nacl_info.py index b85c9423663..3684d0d397b 100644 --- a/plugins/modules/ec2_vpc_nacl_info.py +++ b/plugins/modules/ec2_vpc_nacl_info.py @@ -109,7 +109,7 @@ from ansible.module_utils.common.dict_transformations import camel_dict_to_snake_dict -from ansible_collections.amazon.aws.plugins.module_utils.core import AnsibleAWSModule +from ansible_collections.community.aws.plugins.module_utils.modules import AnsibleCommunityAWSModule as AnsibleAWSModule from ansible_collections.amazon.aws.plugins.module_utils.core import is_boto3_error_code from ansible_collections.amazon.aws.plugins.module_utils.ec2 import AWSRetry from ansible_collections.amazon.aws.plugins.module_utils.ec2 import ansible_dict_to_boto3_filter_list From 70abbf1e97334b82a2d8a023f0ddcd112a9caba3 Mon Sep 17 00:00:00 2001 From: Mark Chappell Date: Wed, 8 Mar 2023 12:07:26 +0100 Subject: [PATCH 24/34] Cleanup headers and imports (#1738) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cleanup headers and imports SUMMARY Mass update of imports, docs fragments and file headers Many of the amazon.aws module_utils and docs fragments got moved about, update community.aws to reflect this. Consistently apply the comment headers as documented at https://docs.ansible.com/ansible/devel/dev_guide/developing_modules_documenting.html#python-shebang-utf-8-coding ISSUE TYPE Docs Pull Request Feature Pull Request COMPONENT NAME ADDITIONAL INFORMATION Header cleanup based upon: https://docs.ansible.com/ansible/devel/dev_guide/developing_modules_documenting.html#python-shebang-utf-8-coding Begin your Ansible module with #!/usr/bin/python - this “shebang” allows ansible_python_interpreter to work. Follow the shebang immediately with # -*- coding: utf-8 -*- to clarify that the file is UTF-8 encoded. and https://docs.ansible.com/ansible/devel/dev_guide/developing_modules_documenting.html#copyright-and-license After the shebang and UTF-8 coding, add a copyright line with the original copyright holder and a license declaration. The license declaration should be ONLY one line, not the full GPL prefix. ... Additions to the module (for instance, rewrites) are not permitted to add additional copyright lines other than the default copyright statement if missing: Reviewed-by: Alina Buzachis This commit was initially merged in https://github.com/ansible-collections/community.aws See: https://github.com/ansible-collections/community.aws/commit/a4f20bf114bfab19b1c84c4ecf42efd5614ab80c --- plugins/modules/ec2_vpc_nacl.py | 35 +++++++++++++------------ plugins/modules/ec2_vpc_nacl_info.py | 39 ++++++++++++++-------------- 2 files changed, 38 insertions(+), 36 deletions(-) diff --git a/plugins/modules/ec2_vpc_nacl.py b/plugins/modules/ec2_vpc_nacl.py index 3b10a0a66f9..fa34ccd8118 100644 --- a/plugins/modules/ec2_vpc_nacl.py +++ b/plugins/modules/ec2_vpc_nacl.py @@ -1,12 +1,10 @@ #!/usr/bin/python +# -*- coding: utf-8 -*- + # 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 = r''' +DOCUMENTATION = r""" module: ec2_vpc_nacl short_description: create and delete Network ACLs version_added: 1.0.0 @@ -73,17 +71,18 @@ type: str choices: ['present', 'absent'] default: present -author: Mike Mochan (@mmochan) +author: + - Mike Mochan (@mmochan) +notes: + - Support for I(purge_tags) was added in release 4.0.0. extends_documentation_fragment: - - amazon.aws.aws - - amazon.aws.ec2 + - amazon.aws.common.modules + - amazon.aws.region.modules - amazon.aws.boto3 - amazon.aws.tags -notes: - - Support for I(purge_tags) was added in release 4.0.0. -''' +""" -EXAMPLES = r''' +EXAMPLES = r""" # Complete example to create and delete a network ACL # that allows SSH, HTTP and ICMP in, and all traffic out. @@ -141,8 +140,8 @@ community.aws.ec2_vpc_nacl: nacl_id: acl-33b4ee5b state: absent -''' -RETURN = r''' +""" +RETURN = r""" task: description: The result of the create, or delete action. returned: success @@ -152,18 +151,20 @@ returned: success type: str sample: acl-123456789abcdef01 -''' +""" try: import botocore except ImportError: pass # Handled by AnsibleAWSModule -from ansible_collections.community.aws.plugins.module_utils.modules import AnsibleCommunityAWSModule as AnsibleAWSModule -from ansible_collections.amazon.aws.plugins.module_utils.ec2 import AWSRetry from ansible_collections.amazon.aws.plugins.module_utils.ec2 import ensure_ec2_tags +from ansible_collections.amazon.aws.plugins.module_utils.retries import AWSRetry from ansible_collections.amazon.aws.plugins.module_utils.tagging import boto3_tag_specifications +from ansible_collections.community.aws.plugins.module_utils.modules import AnsibleCommunityAWSModule as AnsibleAWSModule + + # VPC-supported IANA protocol numbers # http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml PROTOCOL_NUMBERS = {'all': -1, 'icmp': 1, 'tcp': 6, 'udp': 17, 'ipv6-icmp': 58} diff --git a/plugins/modules/ec2_vpc_nacl_info.py b/plugins/modules/ec2_vpc_nacl_info.py index 3684d0d397b..3d37cf26524 100644 --- a/plugins/modules/ec2_vpc_nacl_info.py +++ b/plugins/modules/ec2_vpc_nacl_info.py @@ -1,18 +1,18 @@ #!/usr/bin/python -# 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 +# -*- coding: utf-8 -*- +# Copyright: Contributors to the Ansible project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) -DOCUMENTATION = r''' +DOCUMENTATION = r""" --- module: ec2_vpc_nacl_info version_added: 1.0.0 short_description: Gather information about Network ACLs in an AWS VPC description: - - Gather information about Network ACLs in an AWS VPC -author: "Brad Davidson (@brandond)" + - Gather information about Network ACLs in an AWS VPC +author: + - "Brad Davidson (@brandond)" options: nacl_ids: description: @@ -34,12 +34,12 @@ - By default, the module will return all Network ACLs. extends_documentation_fragment: -- amazon.aws.aws -- amazon.aws.ec2 -- amazon.aws.boto3 -''' + - amazon.aws.common.modules + - amazon.aws.region.modules + - amazon.aws.boto3 +""" -EXAMPLES = r''' +EXAMPLES = r""" # Note: These examples do not set authentication details, see the AWS Guide for details. # Gather information about all Network ACLs: @@ -55,9 +55,9 @@ filters: 'default': 'true' register: default_nacls -''' +""" -RETURN = r''' +RETURN = r""" nacls: description: Returns an array of complex objects as described below. returned: success @@ -100,7 +100,7 @@ type: list elements: list sample: [[100, 'all', 'allow', '0.0.0.0/0', null, null, null, null]] -''' +""" try: import botocore @@ -109,11 +109,12 @@ from ansible.module_utils.common.dict_transformations import camel_dict_to_snake_dict +from ansible_collections.amazon.aws.plugins.module_utils.botocore import is_boto3_error_code +from ansible_collections.amazon.aws.plugins.module_utils.retries import AWSRetry +from ansible_collections.amazon.aws.plugins.module_utils.tagging import boto3_tag_list_to_ansible_dict +from ansible_collections.amazon.aws.plugins.module_utils.transformation import ansible_dict_to_boto3_filter_list + from ansible_collections.community.aws.plugins.module_utils.modules import AnsibleCommunityAWSModule as AnsibleAWSModule -from ansible_collections.amazon.aws.plugins.module_utils.core import is_boto3_error_code -from ansible_collections.amazon.aws.plugins.module_utils.ec2 import AWSRetry -from ansible_collections.amazon.aws.plugins.module_utils.ec2 import ansible_dict_to_boto3_filter_list -from ansible_collections.amazon.aws.plugins.module_utils.ec2 import boto3_tag_list_to_ansible_dict # VPC-supported IANA protocol numbers From a08c97eeab68af325db29f14a889dbe1616265dd Mon Sep 17 00:00:00 2001 From: Mark Chappell Date: Wed, 26 Apr 2023 19:26:07 +0200 Subject: [PATCH 25/34] Big Black PR (#1784) * Black prep * Black * changelog * Fix pylint unused-import in tests * Split SSM connection plugin changes * disable glue tests - bucket's missing * Disable s3_logging and s3_sync tests This commit was initially merged in https://github.com/ansible-collections/community.aws See: https://github.com/ansible-collections/community.aws/commit/2c4575c248776c65d66b06cd60fa09b0dae1cd6f --- plugins/modules/ec2_vpc_nacl.py | 220 +++++++++++++-------------- plugins/modules/ec2_vpc_nacl_info.py | 96 ++++++------ 2 files changed, 162 insertions(+), 154 deletions(-) diff --git a/plugins/modules/ec2_vpc_nacl.py b/plugins/modules/ec2_vpc_nacl.py index fa34ccd8118..022f058d0f9 100644 --- a/plugins/modules/ec2_vpc_nacl.py +++ b/plugins/modules/ec2_vpc_nacl.py @@ -167,33 +167,33 @@ # VPC-supported IANA protocol numbers # http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml -PROTOCOL_NUMBERS = {'all': -1, 'icmp': 1, 'tcp': 6, 'udp': 17, 'ipv6-icmp': 58} +PROTOCOL_NUMBERS = {"all": -1, "icmp": 1, "tcp": 6, "udp": 17, "ipv6-icmp": 58} # Utility methods def icmp_present(entry): - if len(entry) == 6 and entry[1] in ['icmp', 'ipv6-icmp'] or entry[1] in [1, 58]: + if len(entry) == 6 and entry[1] in ["icmp", "ipv6-icmp"] or entry[1] in [1, 58]: return True def subnets_removed(nacl_id, subnets, client, module): results = find_acl_by_id(nacl_id, client, module) - associations = results['NetworkAcls'][0]['Associations'] - subnet_ids = [assoc['SubnetId'] for assoc in associations] + associations = results["NetworkAcls"][0]["Associations"] + subnet_ids = [assoc["SubnetId"] for assoc in associations] return [subnet for subnet in subnet_ids if subnet not in subnets] def subnets_added(nacl_id, subnets, client, module): results = find_acl_by_id(nacl_id, client, module) - associations = results['NetworkAcls'][0]['Associations'] - subnet_ids = [assoc['SubnetId'] for assoc in associations] + associations = results["NetworkAcls"][0]["Associations"] + subnet_ids = [assoc["SubnetId"] for assoc in associations] return [subnet for subnet in subnets if subnet not in subnet_ids] def subnets_changed(nacl, client, module): changed = False - vpc_id = module.params.get('vpc_id') - nacl_id = nacl['NetworkAcls'][0]['NetworkAclId'] + vpc_id = module.params.get("vpc_id") + nacl_id = nacl["NetworkAcls"][0]["NetworkAclId"] subnets = subnets_to_associate(nacl, client, module) if not subnets: default_nacl_id = find_default_vpc_nacl(vpc_id, client, module)[0] @@ -219,40 +219,41 @@ def subnets_changed(nacl, client, module): def nacls_changed(nacl, client, module): changed = False params = dict() - params['egress'] = module.params.get('egress') - params['ingress'] = module.params.get('ingress') + params["egress"] = module.params.get("egress") + params["ingress"] = module.params.get("ingress") - nacl_id = nacl['NetworkAcls'][0]['NetworkAclId'] + nacl_id = nacl["NetworkAcls"][0]["NetworkAclId"] nacl = describe_network_acl(client, module) - entries = nacl['NetworkAcls'][0]['Entries'] - egress = [rule for rule in entries if rule['Egress'] is True and rule['RuleNumber'] < 32767] - ingress = [rule for rule in entries if rule['Egress'] is False and rule['RuleNumber'] < 32767] - if rules_changed(egress, params['egress'], True, nacl_id, client, module): + entries = nacl["NetworkAcls"][0]["Entries"] + egress = [rule for rule in entries if rule["Egress"] is True and rule["RuleNumber"] < 32767] + ingress = [rule for rule in entries if rule["Egress"] is False and rule["RuleNumber"] < 32767] + if rules_changed(egress, params["egress"], True, nacl_id, client, module): changed = True - if rules_changed(ingress, params['ingress'], False, nacl_id, client, module): + if rules_changed(ingress, params["ingress"], False, nacl_id, client, module): changed = True return changed def tags_changed(nacl_id, client, module): - tags = module.params.get('tags') - name = module.params.get('name') - purge_tags = module.params.get('purge_tags') + tags = module.params.get("tags") + name = module.params.get("name") + purge_tags = module.params.get("purge_tags") if name is None and tags is None: return False - if module.params.get('tags') is None: + if module.params.get("tags") is None: # Only purge tags if tags is explicitly set to {} and purge_tags is True purge_tags = False new_tags = dict() - if module.params.get('name') is not None: - new_tags['Name'] = module.params.get('name') - new_tags.update(module.params.get('tags') or {}) + if module.params.get("name") is not None: + new_tags["Name"] = module.params.get("name") + new_tags.update(module.params.get("tags") or {}) - return ensure_ec2_tags(client, module, nacl_id, tags=new_tags, - purge_tags=purge_tags, retry_codes=['InvalidNetworkAclID.NotFound']) + return ensure_ec2_tags( + client, module, nacl_id, tags=new_tags, purge_tags=purge_tags, retry_codes=["InvalidNetworkAclID.NotFound"] + ) def rules_changed(aws_rules, param_rules, Egress, nacl_id, client, module): @@ -267,60 +268,60 @@ def rules_changed(aws_rules, param_rules, Egress, nacl_id, client, module): if removed_rules: params = dict() for rule in removed_rules: - params['NetworkAclId'] = nacl_id - params['RuleNumber'] = rule['RuleNumber'] - params['Egress'] = Egress + params["NetworkAclId"] = nacl_id + params["RuleNumber"] = rule["RuleNumber"] + params["Egress"] = Egress delete_network_acl_entry(params, client, module) changed = True added_rules = [x for x in rules if x not in aws_rules] if added_rules: for rule in added_rules: - rule['NetworkAclId'] = nacl_id + rule["NetworkAclId"] = nacl_id create_network_acl_entry(rule, client, module) changed = True return changed def is_ipv6(cidr): - return ':' in cidr + return ":" in cidr def process_rule_entry(entry, Egress): params = dict() - params['RuleNumber'] = entry[0] - params['Protocol'] = str(PROTOCOL_NUMBERS[entry[1]]) - params['RuleAction'] = entry[2] - params['Egress'] = Egress + params["RuleNumber"] = entry[0] + params["Protocol"] = str(PROTOCOL_NUMBERS[entry[1]]) + params["RuleAction"] = entry[2] + params["Egress"] = Egress if is_ipv6(entry[3]): - params['Ipv6CidrBlock'] = entry[3] + params["Ipv6CidrBlock"] = entry[3] else: - params['CidrBlock'] = entry[3] + params["CidrBlock"] = entry[3] if icmp_present(entry): - params['IcmpTypeCode'] = {"Type": int(entry[4]), "Code": int(entry[5])} + params["IcmpTypeCode"] = {"Type": int(entry[4]), "Code": int(entry[5])} else: if entry[6] or entry[7]: - params['PortRange'] = {"From": entry[6], 'To': entry[7]} + params["PortRange"] = {"From": entry[6], "To": entry[7]} return params def restore_default_associations(assoc_ids, default_nacl_id, client, module): if assoc_ids: params = dict() - params['NetworkAclId'] = default_nacl_id[0] + params["NetworkAclId"] = default_nacl_id[0] for assoc_id in assoc_ids: - params['AssociationId'] = assoc_id + params["AssociationId"] = assoc_id restore_default_acl_association(params, client, module) return True def construct_acl_entries(nacl, client, module): - for entry in module.params.get('ingress'): + for entry in module.params.get("ingress"): params = process_rule_entry(entry, Egress=False) - params['NetworkAclId'] = nacl['NetworkAcl']['NetworkAclId'] + params["NetworkAclId"] = nacl["NetworkAcl"]["NetworkAclId"] create_network_acl_entry(params, client, module) - for rule in module.params.get('egress'): + for rule in module.params.get("egress"): params = process_rule_entry(rule, Egress=True) - params['NetworkAclId'] = nacl['NetworkAcl']['NetworkAclId'] + params["NetworkAclId"] = nacl["NetworkAcl"]["NetworkAclId"] create_network_acl_entry(params, client, module) @@ -328,21 +329,21 @@ def construct_acl_entries(nacl, client, module): def setup_network_acl(client, module): changed = False nacl = describe_network_acl(client, module) - if not nacl['NetworkAcls']: + if not nacl["NetworkAcls"]: tags = {} - if module.params.get('name'): - tags['Name'] = module.params.get('name') - tags.update(module.params.get('tags') or {}) - nacl = create_network_acl(module.params.get('vpc_id'), client, module, tags) - nacl_id = nacl['NetworkAcl']['NetworkAclId'] + if module.params.get("name"): + tags["Name"] = module.params.get("name") + tags.update(module.params.get("tags") or {}) + nacl = create_network_acl(module.params.get("vpc_id"), client, module, tags) + nacl_id = nacl["NetworkAcl"]["NetworkAclId"] subnets = subnets_to_associate(nacl, client, module) replace_network_acl_association(nacl_id, subnets, client, module) construct_acl_entries(nacl, client, module) changed = True - return changed, nacl['NetworkAcl']['NetworkAclId'] + return changed, nacl["NetworkAcl"]["NetworkAclId"] else: changed = False - nacl_id = nacl['NetworkAcls'][0]['NetworkAclId'] + nacl_id = nacl["NetworkAcls"][0]["NetworkAclId"] changed |= subnets_changed(nacl, client, module) changed |= nacls_changed(nacl, client, module) changed |= tags_changed(nacl_id, client, module) @@ -353,11 +354,11 @@ def remove_network_acl(client, module): changed = False result = dict() nacl = describe_network_acl(client, module) - if nacl['NetworkAcls']: - nacl_id = nacl['NetworkAcls'][0]['NetworkAclId'] - vpc_id = nacl['NetworkAcls'][0]['VpcId'] - associations = nacl['NetworkAcls'][0]['Associations'] - assoc_ids = [a['NetworkAclAssociationId'] for a in associations] + if nacl["NetworkAcls"]: + nacl_id = nacl["NetworkAcls"][0]["NetworkAclId"] + vpc_id = nacl["NetworkAcls"][0]["VpcId"] + associations = nacl["NetworkAcls"][0]["Associations"] + assoc_ids = [a["NetworkAclAssociationId"] for a in associations] default_nacl_id = find_default_vpc_nacl(vpc_id, client, module) if not default_nacl_id: result = {vpc_id: "Default NACL ID not found - Check the VPC ID"} @@ -384,7 +385,7 @@ def _create_network_acl(client, *args, **kwargs): def create_network_acl(vpc_id, client, module, tags): params = dict(VpcId=vpc_id) if tags: - params['TagSpecifications'] = boto3_tag_specifications(tags, ['network-acl']) + params["TagSpecifications"] = boto3_tag_specifications(tags, ["network-acl"]) try: if module.check_mode: nacl = dict(NetworkAcl=dict(NetworkAclId="nacl-00000000")) @@ -395,7 +396,7 @@ def create_network_acl(vpc_id, client, module, tags): return nacl -@AWSRetry.jittered_backoff(catch_extra_error_codes=['InvalidNetworkAclID.NotFound']) +@AWSRetry.jittered_backoff(catch_extra_error_codes=["InvalidNetworkAclID.NotFound"]) def _create_network_acl_entry(client, *args, **kwargs): return client.create_network_acl_entry(*args, **kwargs) @@ -421,7 +422,7 @@ def delete_network_acl(nacl_id, client, module): module.fail_json_aws(e) -@AWSRetry.jittered_backoff(catch_extra_error_codes=['InvalidNetworkAclID.NotFound']) +@AWSRetry.jittered_backoff(catch_extra_error_codes=["InvalidNetworkAclID.NotFound"]) def _delete_network_acl_entry(client, *args, **kwargs): return client.delete_network_acl_entry(*args, **kwargs) @@ -439,7 +440,7 @@ def _describe_network_acls(client, **kwargs): return client.describe_network_acls(**kwargs) -@AWSRetry.jittered_backoff(catch_extra_error_codes=['InvalidNetworkAclID.NotFound']) +@AWSRetry.jittered_backoff(catch_extra_error_codes=["InvalidNetworkAclID.NotFound"]) def _describe_network_acls_retry_missing(client, **kwargs): return client.describe_network_acls(**kwargs) @@ -448,25 +449,23 @@ def describe_acl_associations(subnets, client, module): if not subnets: return [] try: - results = _describe_network_acls_retry_missing(client, Filters=[ - {'Name': 'association.subnet-id', 'Values': subnets} - ]) + results = _describe_network_acls_retry_missing( + client, Filters=[{"Name": "association.subnet-id", "Values": subnets}] + ) except botocore.exceptions.ClientError as e: module.fail_json_aws(e) - associations = results['NetworkAcls'][0]['Associations'] - return [a['NetworkAclAssociationId'] for a in associations if a['SubnetId'] in subnets] + associations = results["NetworkAcls"][0]["Associations"] + return [a["NetworkAclAssociationId"] for a in associations if a["SubnetId"] in subnets] def describe_network_acl(client, module): try: - if module.params.get('nacl_id'): - nacl = _describe_network_acls(client, Filters=[ - {'Name': 'network-acl-id', 'Values': [module.params.get('nacl_id')]} - ]) + if module.params.get("nacl_id"): + nacl = _describe_network_acls( + client, Filters=[{"Name": "network-acl-id", "Values": [module.params.get("nacl_id")]}] + ) else: - nacl = _describe_network_acls(client, Filters=[ - {'Name': 'tag:Name', 'Values': [module.params.get('name')]} - ]) + nacl = _describe_network_acls(client, Filters=[{"Name": "tag:Name", "Values": [module.params.get("name")]}]) except botocore.exceptions.ClientError as e: module.fail_json_aws(e) return nacl @@ -481,38 +480,37 @@ def find_acl_by_id(nacl_id, client, module): def find_default_vpc_nacl(vpc_id, client, module): try: - response = _describe_network_acls_retry_missing(client, Filters=[ - {'Name': 'vpc-id', 'Values': [vpc_id]}]) + response = _describe_network_acls_retry_missing(client, Filters=[{"Name": "vpc-id", "Values": [vpc_id]}]) except botocore.exceptions.ClientError as e: module.fail_json_aws(e) - nacls = response['NetworkAcls'] - return [n['NetworkAclId'] for n in nacls if n['IsDefault'] is True] + nacls = response["NetworkAcls"] + return [n["NetworkAclId"] for n in nacls if n["IsDefault"] is True] def find_subnet_ids_by_nacl_id(nacl_id, client, module): try: - results = _describe_network_acls_retry_missing(client, Filters=[ - {'Name': 'association.network-acl-id', 'Values': [nacl_id]} - ]) + results = _describe_network_acls_retry_missing( + client, Filters=[{"Name": "association.network-acl-id", "Values": [nacl_id]}] + ) except botocore.exceptions.ClientError as e: module.fail_json_aws(e) - if results['NetworkAcls']: - associations = results['NetworkAcls'][0]['Associations'] - return [s['SubnetId'] for s in associations if s['SubnetId']] + if results["NetworkAcls"]: + associations = results["NetworkAcls"][0]["Associations"] + return [s["SubnetId"] for s in associations if s["SubnetId"]] else: return [] -@AWSRetry.jittered_backoff(catch_extra_error_codes=['InvalidNetworkAclID.NotFound']) +@AWSRetry.jittered_backoff(catch_extra_error_codes=["InvalidNetworkAclID.NotFound"]) def _replace_network_acl_association(client, *args, **kwargs): return client.replace_network_acl_association(*args, **kwargs) def replace_network_acl_association(nacl_id, subnets, client, module): params = dict() - params['NetworkAclId'] = nacl_id + params["NetworkAclId"] = nacl_id for association in describe_acl_associations(subnets, client, module): - params['AssociationId'] = association + params["AssociationId"] = association try: if not module.check_mode: _replace_network_acl_association(client, **params) @@ -520,7 +518,7 @@ def replace_network_acl_association(nacl_id, subnets, client, module): module.fail_json_aws(e) -@AWSRetry.jittered_backoff(catch_extra_error_codes=['InvalidNetworkAclID.NotFound']) +@AWSRetry.jittered_backoff(catch_extra_error_codes=["InvalidNetworkAclID.NotFound"]) def _replace_network_acl_entry(client, *args, **kwargs): return client.replace_network_acl_entry(*args, **kwargs) @@ -528,7 +526,7 @@ def _replace_network_acl_entry(client, *args, **kwargs): def replace_network_acl_entry(entries, Egress, nacl_id, client, module): for entry in entries: params = entry - params['NetworkAclId'] = nacl_id + params["NetworkAclId"] = nacl_id try: if not module.check_mode: _replace_network_acl_entry(client, **params) @@ -536,7 +534,7 @@ def replace_network_acl_entry(entries, Egress, nacl_id, client, module): module.fail_json_aws(e) -@AWSRetry.jittered_backoff(catch_extra_error_codes=['InvalidNetworkAclID.NotFound']) +@AWSRetry.jittered_backoff(catch_extra_error_codes=["InvalidNetworkAclID.NotFound"]) def _replace_network_acl_association(client, *args, **kwargs): return client.replace_network_acl_association(*args, **kwargs) @@ -555,25 +553,23 @@ def _describe_subnets(client, *args, **kwargs): def subnets_to_associate(nacl, client, module): - params = list(module.params.get('subnets')) + params = list(module.params.get("subnets")) if not params: return [] all_found = [] if any(x.startswith("subnet-") for x in params): try: - subnets = _describe_subnets(client, Filters=[ - {'Name': 'subnet-id', 'Values': params}]) - all_found.extend(subnets.get('Subnets', [])) + subnets = _describe_subnets(client, Filters=[{"Name": "subnet-id", "Values": params}]) + all_found.extend(subnets.get("Subnets", [])) except botocore.exceptions.ClientError as e: module.fail_json_aws(e) if len(params) != len(all_found): try: - subnets = _describe_subnets(client, Filters=[ - {'Name': 'tag:Name', 'Values': params}]) - all_found.extend(subnets.get('Subnets', [])) + subnets = _describe_subnets(client, Filters=[{"Name": "tag:Name", "Values": params}]) + all_found.extend(subnets.get("Subnets", [])) except botocore.exceptions.ClientError as e: module.fail_json_aws(e) - return list(set(s['SubnetId'] for s in all_found if s.get('SubnetId'))) + return list(set(s["SubnetId"] for s in all_found if s.get("SubnetId"))) def main(): @@ -581,29 +577,31 @@ def main(): vpc_id=dict(), name=dict(), nacl_id=dict(), - subnets=dict(required=False, type='list', default=list(), elements='str'), - tags=dict(required=False, type='dict', aliases=['resource_tags']), - purge_tags=dict(required=False, type='bool', default=True), - ingress=dict(required=False, type='list', default=list(), elements='list'), - egress=dict(required=False, type='list', default=list(), elements='list'), - state=dict(default='present', choices=['present', 'absent']), + subnets=dict(required=False, type="list", default=list(), elements="str"), + tags=dict(required=False, type="dict", aliases=["resource_tags"]), + purge_tags=dict(required=False, type="bool", default=True), + ingress=dict(required=False, type="list", default=list(), elements="list"), + egress=dict(required=False, type="list", default=list(), elements="list"), + state=dict(default="present", choices=["present", "absent"]), + ) + module = AnsibleAWSModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_one_of=[["name", "nacl_id"]], + required_if=[["state", "present", ["vpc_id"]]], ) - module = AnsibleAWSModule(argument_spec=argument_spec, - supports_check_mode=True, - required_one_of=[['name', 'nacl_id']], - required_if=[['state', 'present', ['vpc_id']]]) - state = module.params.get('state').lower() + state = module.params.get("state").lower() - client = module.client('ec2') + client = module.client("ec2") invocations = { "present": setup_network_acl, - "absent": remove_network_acl + "absent": remove_network_acl, } (changed, results) = invocations[state](client, module) module.exit_json(changed=changed, nacl_id=results) -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/plugins/modules/ec2_vpc_nacl_info.py b/plugins/modules/ec2_vpc_nacl_info.py index 3d37cf26524..ecf530a9d74 100644 --- a/plugins/modules/ec2_vpc_nacl_info.py +++ b/plugins/modules/ec2_vpc_nacl_info.py @@ -119,11 +119,10 @@ # VPC-supported IANA protocol numbers # http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml -PROTOCOL_NAMES = {'-1': 'all', '1': 'icmp', '6': 'tcp', '17': 'udp'} +PROTOCOL_NAMES = {"-1": "all", "1": "icmp", "6": "tcp", "17": "udp"} def list_ec2_vpc_nacls(connection, module): - nacl_ids = module.params.get("nacl_ids") filters = ansible_dict_to_boto3_filter_list(module.params.get("filters")) @@ -132,86 +131,97 @@ def list_ec2_vpc_nacls(connection, module): try: nacls = connection.describe_network_acls(aws_retry=True, NetworkAclIds=nacl_ids, Filters=filters) - except is_boto3_error_code('InvalidNetworkAclID.NotFound'): - module.fail_json(msg='Unable to describe ACL. NetworkAcl does not exist') - except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: # pylint: disable=duplicate-except + except is_boto3_error_code("InvalidNetworkAclID.NotFound"): + module.fail_json(msg="Unable to describe ACL. NetworkAcl does not exist") + except ( + botocore.exceptions.ClientError, + botocore.exceptions.BotoCoreError, + ) as e: # pylint: disable=duplicate-except module.fail_json_aws(e, msg="Unable to describe network ACLs {0}".format(nacl_ids)) # Turn the boto3 result in to ansible_friendly_snaked_names snaked_nacls = [] - for nacl in nacls['NetworkAcls']: + for nacl in nacls["NetworkAcls"]: snaked_nacls.append(camel_dict_to_snake_dict(nacl)) # Turn the boto3 result in to ansible friendly tag dictionary for nacl in snaked_nacls: - if 'tags' in nacl: - nacl['tags'] = boto3_tag_list_to_ansible_dict(nacl['tags'], 'key', 'value') - if 'entries' in nacl: - nacl['egress'] = [nacl_entry_to_list(entry) for entry in nacl['entries'] - if entry['rule_number'] < 32767 and entry['egress']] - nacl['ingress'] = [nacl_entry_to_list(entry) for entry in nacl['entries'] - if entry['rule_number'] < 32767 and not entry['egress']] - del nacl['entries'] - if 'associations' in nacl: - nacl['subnets'] = [a['subnet_id'] for a in nacl['associations']] - del nacl['associations'] - if 'network_acl_id' in nacl: - nacl['nacl_id'] = nacl['network_acl_id'] - del nacl['network_acl_id'] + if "tags" in nacl: + nacl["tags"] = boto3_tag_list_to_ansible_dict(nacl["tags"], "key", "value") + if "entries" in nacl: + nacl["egress"] = [ + nacl_entry_to_list(entry) + for entry in nacl["entries"] + if entry["rule_number"] < 32767 and entry["egress"] + ] + nacl["ingress"] = [ + nacl_entry_to_list(entry) + for entry in nacl["entries"] + if entry["rule_number"] < 32767 and not entry["egress"] + ] + del nacl["entries"] + if "associations" in nacl: + nacl["subnets"] = [a["subnet_id"] for a in nacl["associations"]] + del nacl["associations"] + if "network_acl_id" in nacl: + nacl["nacl_id"] = nacl["network_acl_id"] + del nacl["network_acl_id"] module.exit_json(nacls=snaked_nacls) def nacl_entry_to_list(entry): - # entry list format # [ rule_num, protocol name or number, allow or deny, ipv4/6 cidr, icmp type, icmp code, port from, port to] elist = [] - elist.append(entry['rule_number']) + elist.append(entry["rule_number"]) - if entry.get('protocol') in PROTOCOL_NAMES: - elist.append(PROTOCOL_NAMES[entry['protocol']]) + if entry.get("protocol") in PROTOCOL_NAMES: + elist.append(PROTOCOL_NAMES[entry["protocol"]]) else: - elist.append(entry.get('protocol')) + elist.append(entry.get("protocol")) - elist.append(entry['rule_action']) + elist.append(entry["rule_action"]) - if entry.get('cidr_block'): - elist.append(entry['cidr_block']) - elif entry.get('ipv6_cidr_block'): - elist.append(entry['ipv6_cidr_block']) + if entry.get("cidr_block"): + elist.append(entry["cidr_block"]) + elif entry.get("ipv6_cidr_block"): + elist.append(entry["ipv6_cidr_block"]) else: elist.append(None) elist = elist + [None, None, None, None] - if entry['protocol'] in ('1', '58'): - elist[4] = entry.get('icmp_type_code', {}).get('type') - elist[5] = entry.get('icmp_type_code', {}).get('code') + if entry["protocol"] in ("1", "58"): + elist[4] = entry.get("icmp_type_code", {}).get("type") + elist[5] = entry.get("icmp_type_code", {}).get("code") - if entry['protocol'] not in ('1', '6', '17', '58'): + if entry["protocol"] not in ("1", "6", "17", "58"): elist[6] = 0 elist[7] = 65535 - elif 'port_range' in entry: - elist[6] = entry['port_range']['from'] - elist[7] = entry['port_range']['to'] + elif "port_range" in entry: + elist[6] = entry["port_range"]["from"] + elist[7] = entry["port_range"]["to"] return elist def main(): - argument_spec = dict( - nacl_ids=dict(default=[], type='list', aliases=['nacl_id'], elements='str'), - filters=dict(default={}, type='dict')) + nacl_ids=dict(default=[], type="list", aliases=["nacl_id"], elements="str"), + filters=dict(default={}, type="dict"), + ) - module = AnsibleAWSModule(argument_spec=argument_spec, supports_check_mode=True) + module = AnsibleAWSModule( + argument_spec=argument_spec, + supports_check_mode=True, + ) - connection = module.client('ec2', retry_decorator=AWSRetry.jittered_backoff()) + connection = module.client("ec2", retry_decorator=AWSRetry.jittered_backoff()) list_ec2_vpc_nacls(connection, module) -if __name__ == '__main__': +if __name__ == "__main__": main() From 92c73bd023a13d4d8e133ed9d50c3e3e5c00256a Mon Sep 17 00:00:00 2001 From: Mark Chappell Date: Mon, 8 May 2023 19:21:22 +0200 Subject: [PATCH 26/34] Bulk migration to Python 3.6 f-strings (#1810) Bulk migration to Python 3.6 f-strings SUMMARY We've dropped support for Python <3.6, bulk migrate to fstrings and perform some general string cleanup A combination of black --preview flynt some manual cleanup ISSUE TYPE Feature Pull Request COMPONENT NAME plugins/ tests/ ADDITIONAL INFORMATION Reviewed-by: Alina Buzachis This commit was initially merged in https://github.com/ansible-collections/community.aws See: https://github.com/ansible-collections/community.aws/commit/de338210dc1b0bb2eecee1dc16e073163b2d1df7 --- plugins/modules/ec2_vpc_nacl_info.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/modules/ec2_vpc_nacl_info.py b/plugins/modules/ec2_vpc_nacl_info.py index ecf530a9d74..40e0398b974 100644 --- a/plugins/modules/ec2_vpc_nacl_info.py +++ b/plugins/modules/ec2_vpc_nacl_info.py @@ -137,7 +137,7 @@ def list_ec2_vpc_nacls(connection, module): botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError, ) as e: # pylint: disable=duplicate-except - module.fail_json_aws(e, msg="Unable to describe network ACLs {0}".format(nacl_ids)) + module.fail_json_aws(e, msg=f"Unable to describe network ACLs {nacl_ids}") # Turn the boto3 result in to ansible_friendly_snaked_names snaked_nacls = [] From bc7d15e646fe5b8aff85cd611dfdc653d16b88e1 Mon Sep 17 00:00:00 2001 From: Mark Chappell Date: Thu, 31 Aug 2023 17:58:59 +0200 Subject: [PATCH 27/34] Mass update of docs and tests (credentials/session tokens) (#1921) Mass update of docs and tests (credentials/session tokens) SUMMARY We had a cleanup of credentials/session parameters which included a batch of deprecations and renames. Ensure that all of our tests and docs are using the 'canonical' names ISSUE TYPE Docs Pull Request COMPONENT NAME plugins/modules/batch_compute_environment.py plugins/modules/cloudformation_exports_info.py plugins/modules/ec2_vpc_vpn.py plugins/modules/elasticache.py plugins/modules/elasticache_parameter_group.py plugins/modules/elasticache_snapshot.py plugins/modules/ses_rule_set.py plugins/modules/sts_assume_role.py plugins/modules/sts_session_token.py tests/integration ADDITIONAL INFORMATION See also ansible-collections/amazon.aws#1172 ansible-collections/amazon.aws#1714 Reviewed-by: Alina Buzachis This commit was initially merged in https://github.com/ansible-collections/community.aws See: https://github.com/ansible-collections/community.aws/commit/4a5b50e9b9c0d6ca1a1f802f3b03d4f503c16885 --- tests/integration/targets/ec2_vpc_nacl/tasks/main.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/integration/targets/ec2_vpc_nacl/tasks/main.yml b/tests/integration/targets/ec2_vpc_nacl/tasks/main.yml index e1538049aba..36c7ab2d8bb 100644 --- a/tests/integration/targets/ec2_vpc_nacl/tasks/main.yml +++ b/tests/integration/targets/ec2_vpc_nacl/tasks/main.yml @@ -1,9 +1,9 @@ --- - module_defaults: group/aws: - aws_access_key: "{{ aws_access_key }}" - aws_secret_key: "{{ aws_secret_key }}" - security_token: "{{ security_token | default(omit) }}" + access_key: "{{ aws_access_key }}" + secret_key: "{{ aws_secret_key }}" + session_token: "{{ security_token | default(omit) }}" region: "{{ aws_region }}" collections: - amazon.aws From c08a37776ded9c01d90c7ff8c9dd7116290e47d0 Mon Sep 17 00:00:00 2001 From: Mark Chappell Date: Tue, 17 Oct 2023 21:27:02 +0200 Subject: [PATCH 28/34] Apply isort and flynt (#1962) SUMMARY Apply isort - see also ansible-collections/amazon.aws#1771 Apply flynt - see also ansible-collections/amazon.aws#1802 ISSUE TYPE Feature Pull Request COMPONENT NAME ADDITIONAL INFORMATION This commit was initially merged in https://github.com/ansible-collections/community.aws See: https://github.com/ansible-collections/community.aws/commit/c0117b5466958bd0f8b5fc620306adde1422a62d --- plugins/modules/ec2_vpc_nacl.py | 1 - plugins/modules/ec2_vpc_nacl_info.py | 1 - 2 files changed, 2 deletions(-) diff --git a/plugins/modules/ec2_vpc_nacl.py b/plugins/modules/ec2_vpc_nacl.py index 022f058d0f9..46f7086bc85 100644 --- a/plugins/modules/ec2_vpc_nacl.py +++ b/plugins/modules/ec2_vpc_nacl.py @@ -164,7 +164,6 @@ from ansible_collections.community.aws.plugins.module_utils.modules import AnsibleCommunityAWSModule as AnsibleAWSModule - # VPC-supported IANA protocol numbers # http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml PROTOCOL_NUMBERS = {"all": -1, "icmp": 1, "tcp": 6, "udp": 17, "ipv6-icmp": 58} diff --git a/plugins/modules/ec2_vpc_nacl_info.py b/plugins/modules/ec2_vpc_nacl_info.py index 40e0398b974..d95508a894e 100644 --- a/plugins/modules/ec2_vpc_nacl_info.py +++ b/plugins/modules/ec2_vpc_nacl_info.py @@ -116,7 +116,6 @@ from ansible_collections.community.aws.plugins.module_utils.modules import AnsibleCommunityAWSModule as AnsibleAWSModule - # VPC-supported IANA protocol numbers # http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml PROTOCOL_NAMES = {"-1": "all", "1": "icmp", "6": "tcp", "17": "udp"} From fda62445ded7c964a03c97685b6872719f0ee653 Mon Sep 17 00:00:00 2001 From: Mark Chappell Date: Fri, 5 Jan 2024 18:42:41 +0100 Subject: [PATCH 29/34] ansible-lint (documentation) cleanup for plugins/ (#2036) ansible-lint (documentation) cleanup for plugins/ SUMMARY Fixes an array of ansible-lint failures in plugins/ Adds ansible-lint plugins/ to tox -m lint ISSUE TYPE Docs Pull Request COMPONENT NAME plugins/ ADDITIONAL INFORMATION docs changes only (no changelog fragment needed) Reviewed-by: Alina Buzachis This commit was initially merged in https://github.com/ansible-collections/community.aws See: https://github.com/ansible-collections/community.aws/commit/6dd4a00b8c18fe3499bad04f90c8ac7832ade8bb --- plugins/modules/ec2_vpc_nacl.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/plugins/modules/ec2_vpc_nacl.py b/plugins/modules/ec2_vpc_nacl.py index 46f7086bc85..cf109de1c8b 100644 --- a/plugins/modules/ec2_vpc_nacl.py +++ b/plugins/modules/ec2_vpc_nacl.py @@ -83,7 +83,6 @@ """ EXAMPLES = r""" - # Complete example to create and delete a network ACL # that allows SSH, HTTP and ICMP in, and all traffic out. - name: "Create and associate production DMZ network ACL with DMZ subnets" @@ -97,16 +96,16 @@ Project: phoenix Description: production DMZ ingress: - # rule no, protocol, allow/deny, cidr, icmp_type, icmp_code, - # port from, port to - - [100, 'tcp', 'allow', '0.0.0.0/0', null, null, 22, 22] - - [200, 'tcp', 'allow', '0.0.0.0/0', null, null, 80, 80] - - [205, 'tcp', 'allow', '::/0', null, null, 80, 80] - - [300, 'icmp', 'allow', '0.0.0.0/0', 0, 8] - - [305, 'ipv6-icmp', 'allow', '::/0', 0, 8] + # rule no, protocol, allow/deny, cidr, icmp_type, icmp_code, + # port from, port to + - [100, 'tcp', 'allow', '0.0.0.0/0', null, null, 22, 22] + - [200, 'tcp', 'allow', '0.0.0.0/0', null, null, 80, 80] + - [205, 'tcp', 'allow', '::/0', null, null, 80, 80] + - [300, 'icmp', 'allow', '0.0.0.0/0', 0, 8] + - [305, 'ipv6-icmp', 'allow', '::/0', 0, 8] egress: - - [100, 'all', 'allow', '0.0.0.0/0', null, null, null, null] - - [105, 'all', 'allow', '::/0', null, null, null, null] + - [100, 'all', 'allow', '0.0.0.0/0', null, null, null, null] + - [105, 'all', 'allow', '::/0', null, null, null, null] state: 'present' - name: "Remove the ingress and egress rules - defaults to deny all" @@ -141,6 +140,7 @@ nacl_id: acl-33b4ee5b state: absent """ + RETURN = r""" task: description: The result of the create, or delete action. From fd0f65226948256a7968ea4201d5cca924105d17 Mon Sep 17 00:00:00 2001 From: Bikouo Aubin <79859644+abikouo@users.noreply.github.com> Date: Mon, 14 Oct 2024 12:34:05 +0200 Subject: [PATCH 30/34] Prepare modules ec2_vpc_nacl and ec2_vpc_nacl_info for promotion (#2159) SUMMARY Use shared code from amazon.aws.plugins.module_utils.ec2 Refactor module ec2_vpc_nacl and ec2_vpc_nacl_info ISSUE TYPE Feature Pull Request Reviewed-by: Alina Buzachis Reviewed-by: Bikouo Aubin Reviewed-by: GomathiselviS This commit was initially merged in https://github.com/ansible-collections/community.aws See: https://github.com/ansible-collections/community.aws/commit/86d268f3391b49c5767d2243de7a5f0d74e49cb5 --- plugins/modules/ec2_vpc_nacl.py | 606 ++++++++---------- plugins/modules/ec2_vpc_nacl_info.py | 109 ++-- .../ec2_vpc_nacl/tasks/ingress_and_egress.yml | 75 +-- .../targets/ec2_vpc_nacl/tasks/ipv6.yml | 57 +- .../targets/ec2_vpc_nacl/tasks/main.yml | 101 ++- .../targets/ec2_vpc_nacl/tasks/subnet_ids.yml | 76 +-- .../ec2_vpc_nacl/tasks/subnet_names.yml | 59 +- .../targets/ec2_vpc_nacl/tasks/tags.yml | 224 +++---- 8 files changed, 631 insertions(+), 676 deletions(-) diff --git a/plugins/modules/ec2_vpc_nacl.py b/plugins/modules/ec2_vpc_nacl.py index cf109de1c8b..bc92003d17c 100644 --- a/plugins/modules/ec2_vpc_nacl.py +++ b/plugins/modules/ec2_vpc_nacl.py @@ -15,13 +15,15 @@ name: description: - Tagged name identifying a network ACL. - - One and only one of the I(name) or I(nacl_id) is required. + - One and only one of the O(name) or O(nacl_id) is required. + - Mutually exclusive with O(nacl_id). required: false type: str nacl_id: description: - NACL id identifying a network ACL. - - One and only one of the I(name) or I(nacl_id) is required. + - One and only one of the O(name) or O(nacl_id) is required. + - Mutually exclusive with O(name). required: false type: str vpc_id: @@ -142,25 +144,27 @@ """ RETURN = r""" -task: - description: The result of the create, or delete action. - returned: success - type: dict nacl_id: - description: The id of the NACL (when creating or updating an ACL) + description: The id of the NACL (when creating or updating an ACL). returned: success type: str - sample: acl-123456789abcdef01 + sample: "acl-123456789abcdef01" """ -try: - import botocore -except ImportError: - pass # Handled by AnsibleAWSModule - +from typing import Any +from typing import Dict +from typing import List +from typing import Optional + +from ansible_collections.amazon.aws.plugins.module_utils.ec2 import AnsibleEC2Error +from ansible_collections.amazon.aws.plugins.module_utils.ec2 import create_network_acl +from ansible_collections.amazon.aws.plugins.module_utils.ec2 import create_network_acl_entry +from ansible_collections.amazon.aws.plugins.module_utils.ec2 import delete_network_acl +from ansible_collections.amazon.aws.plugins.module_utils.ec2 import delete_network_acl_entry +from ansible_collections.amazon.aws.plugins.module_utils.ec2 import describe_network_acls +from ansible_collections.amazon.aws.plugins.module_utils.ec2 import describe_subnets from ansible_collections.amazon.aws.plugins.module_utils.ec2 import ensure_ec2_tags -from ansible_collections.amazon.aws.plugins.module_utils.retries import AWSRetry -from ansible_collections.amazon.aws.plugins.module_utils.tagging import boto3_tag_specifications +from ansible_collections.amazon.aws.plugins.module_utils.ec2 import replace_network_acl_association from ansible_collections.community.aws.plugins.module_utils.modules import AnsibleCommunityAWSModule as AnsibleAWSModule @@ -170,70 +174,63 @@ # Utility methods -def icmp_present(entry): - if len(entry) == 6 and entry[1] in ["icmp", "ipv6-icmp"] or entry[1] in [1, 58]: - return True - - -def subnets_removed(nacl_id, subnets, client, module): - results = find_acl_by_id(nacl_id, client, module) - associations = results["NetworkAcls"][0]["Associations"] - subnet_ids = [assoc["SubnetId"] for assoc in associations] - return [subnet for subnet in subnet_ids if subnet not in subnets] +def icmp_present(entry: List[str]) -> bool: + return len(entry) == 6 and entry[1] in ["icmp", "ipv6-icmp"] or entry[1] in [1, 58] -def subnets_added(nacl_id, subnets, client, module): - results = find_acl_by_id(nacl_id, client, module) - associations = results["NetworkAcls"][0]["Associations"] - subnet_ids = [assoc["SubnetId"] for assoc in associations] - return [subnet for subnet in subnets if subnet not in subnet_ids] - - -def subnets_changed(nacl, client, module): +def subnets_changed(client, module: AnsibleAWSModule, nacl_id: str, subnets_ids: List[str]) -> bool: changed = False vpc_id = module.params.get("vpc_id") - nacl_id = nacl["NetworkAcls"][0]["NetworkAclId"] - subnets = subnets_to_associate(nacl, client, module) - if not subnets: - default_nacl_id = find_default_vpc_nacl(vpc_id, client, module)[0] - subnets = find_subnet_ids_by_nacl_id(nacl_id, client, module) - if subnets: - replace_network_acl_association(default_nacl_id, subnets, client, module) - changed = True - return changed - changed = False + + if not subnets_ids: + default_nacl_id = find_default_vpc_nacl(client, vpc_id) + # Find subnets by Network ACL ids + network_acls = describe_network_acls( + client, Filters=[{"Name": "association.network-acl-id", "Values": [nacl_id]}] + ) + subnets = [ + association["SubnetId"] + for nacl in network_acls + for association in nacl["Associations"] + if association["SubnetId"] + ] + changed = associate_nacl_to_subnets(client, module, default_nacl_id, subnets) return changed - subs_added = subnets_added(nacl_id, subnets, client, module) - if subs_added: - replace_network_acl_association(nacl_id, subs_added, client, module) - changed = True - subs_removed = subnets_removed(nacl_id, subnets, client, module) - if subs_removed: - default_nacl_id = find_default_vpc_nacl(vpc_id, client, module)[0] - replace_network_acl_association(default_nacl_id, subs_removed, client, module) - changed = True + + network_acls = describe_network_acls(client, NetworkAclIds=[nacl_id]) + current_subnets = [ + association["SubnetId"] + for nacl in network_acls + for association in nacl["Associations"] + if association["SubnetId"] + ] + subnets_added = [subnet for subnet in subnets_ids if subnet not in current_subnets] + subnets_removed = [subnet for subnet in current_subnets if subnet not in subnets_ids] + + if subnets_added: + changed |= associate_nacl_to_subnets(client, module, nacl_id, subnets_added) + if subnets_removed: + default_nacl_id = find_default_vpc_nacl(client, vpc_id) + changed |= associate_nacl_to_subnets(client, module, default_nacl_id, subnets_removed) + return changed -def nacls_changed(nacl, client, module): +def nacls_changed(client, module: AnsibleAWSModule, nacl_info: Dict[str, Any]) -> bool: changed = False - params = dict() - params["egress"] = module.params.get("egress") - params["ingress"] = module.params.get("ingress") - - nacl_id = nacl["NetworkAcls"][0]["NetworkAclId"] - nacl = describe_network_acl(client, module) - entries = nacl["NetworkAcls"][0]["Entries"] - egress = [rule for rule in entries if rule["Egress"] is True and rule["RuleNumber"] < 32767] - ingress = [rule for rule in entries if rule["Egress"] is False and rule["RuleNumber"] < 32767] - if rules_changed(egress, params["egress"], True, nacl_id, client, module): - changed = True - if rules_changed(ingress, params["ingress"], False, nacl_id, client, module): - changed = True + entries = nacl_info["Entries"] + nacl_id = nacl_info["NetworkAclId"] + aws_egress_rules = [rule for rule in entries if rule["Egress"] is True and rule["RuleNumber"] < 32767] + aws_ingress_rules = [rule for rule in entries if rule["Egress"] is False and rule["RuleNumber"] < 32767] + + # Egress Rules + changed |= rules_changed(client, nacl_id, module.params.get("egress"), aws_egress_rules, True, module.check_mode) + # Ingress Rules + changed |= rules_changed(client, nacl_id, module.params.get("ingress"), aws_ingress_rules, False, module.check_mode) return changed -def tags_changed(nacl_id, client, module): +def tags_changed(client, module: AnsibleAWSModule, nacl_id: str) -> bool: tags = module.params.get("tags") name = module.params.get("name") purge_tags = module.params.get("purge_tags") @@ -255,42 +252,84 @@ def tags_changed(nacl_id, client, module): ) -def rules_changed(aws_rules, param_rules, Egress, nacl_id, client, module): +def ansible_to_boto3_dict_rule(ansible_rule: List[Any], egress: bool) -> Dict[str, Any]: + boto3_rule = {} + if isinstance(ansible_rule, list): + boto3_rule["RuleNumber"] = ansible_rule[0] + boto3_rule["Protocol"] = str(PROTOCOL_NUMBERS[ansible_rule[1]]) + boto3_rule["RuleAction"] = ansible_rule[2] + boto3_rule["Egress"] = egress + if is_ipv6(ansible_rule[3]): + boto3_rule["Ipv6CidrBlock"] = ansible_rule[3] + else: + boto3_rule["CidrBlock"] = ansible_rule[3] + if icmp_present(ansible_rule): + boto3_rule["IcmpTypeCode"] = {"Type": int(ansible_rule[4]), "Code": int(ansible_rule[5])} + else: + if ansible_rule[6] or ansible_rule[7]: + boto3_rule["PortRange"] = {"From": ansible_rule[6], "To": ansible_rule[7]} + return boto3_rule + + +def find_added_rules(rules_a: List[Dict[str, Any]], rules_b: List[Dict[str, Any]]) -> List[Dict[str, Any]]: + results = [] + # A rule is considered as a new rule if either the RuleNumber does exist in the list of + # current Rules stored in AWS or if the Rule differs with the Rule stored in AWS with the same RuleNumber + for a in rules_a: + if not any(a["RuleNumber"] == b["RuleNumber"] and a == b for b in rules_b): + results.append(a) + return results + + +def rules_changed( + client, + nacl_id: str, + ansible_rules: List[List[str]], + aws_rules: List[Dict[str, Any]], + egress: bool, + check_mode: bool, +) -> bool: + # transform rules: from ansible list to boto3 dict + ansible_rules = [ansible_to_boto3_dict_rule(r, egress) for r in ansible_rules] + + # find added rules + added_rules = find_added_rules(ansible_rules, aws_rules) + # find removed rules + removed_rules = find_added_rules(aws_rules, ansible_rules) + changed = False - rules = list() - for entry in param_rules: - rules.append(process_rule_entry(entry, Egress)) - if rules == aws_rules: - return changed - else: - removed_rules = [x for x in aws_rules if x not in rules] - if removed_rules: - params = dict() - for rule in removed_rules: - params["NetworkAclId"] = nacl_id - params["RuleNumber"] = rule["RuleNumber"] - params["Egress"] = Egress - delete_network_acl_entry(params, client, module) - changed = True - added_rules = [x for x in rules if x not in aws_rules] - if added_rules: - for rule in added_rules: - rule["NetworkAclId"] = nacl_id - create_network_acl_entry(rule, client, module) - changed = True + for rule in added_rules: + changed = True + if not check_mode: + rule_number = rule.pop("RuleNumber") + protocol = rule.pop("Protocol") + rule_action = rule.pop("RuleAction") + egress = rule.pop("Egress") + create_network_acl_entry( + client, + network_acl_id=nacl_id, + protocol=protocol, + egress=egress, + rule_action=rule_action, + rule_number=rule_number, + **rule, + ) + + # Removed Rules + for rule in removed_rules: + changed = True + if not check_mode: + delete_network_acl_entry(client, network_acl_id=nacl_id, rule_number=rule["RuleNumber"], egress=egress) + return changed -def is_ipv6(cidr): +def is_ipv6(cidr: str) -> bool: return ":" in cidr -def process_rule_entry(entry, Egress): - params = dict() - params["RuleNumber"] = entry[0] - params["Protocol"] = str(PROTOCOL_NUMBERS[entry[1]]) - params["RuleAction"] = entry[2] - params["Egress"] = Egress +def process_rule_entry(entry: List[Any]) -> Dict[str, Any]: + params = {} if is_ipv6(entry[3]): params["Ipv6CidrBlock"] = entry[3] else: @@ -300,275 +339,161 @@ def process_rule_entry(entry, Egress): else: if entry[6] or entry[7]: params["PortRange"] = {"From": entry[6], "To": entry[7]} - return params - -def restore_default_associations(assoc_ids, default_nacl_id, client, module): - if assoc_ids: - params = dict() - params["NetworkAclId"] = default_nacl_id[0] - for assoc_id in assoc_ids: - params["AssociationId"] = assoc_id - restore_default_acl_association(params, client, module) - return True - - -def construct_acl_entries(nacl, client, module): - for entry in module.params.get("ingress"): - params = process_rule_entry(entry, Egress=False) - params["NetworkAclId"] = nacl["NetworkAcl"]["NetworkAclId"] - create_network_acl_entry(params, client, module) - for rule in module.params.get("egress"): - params = process_rule_entry(rule, Egress=True) - params["NetworkAclId"] = nacl["NetworkAcl"]["NetworkAclId"] - create_network_acl_entry(params, client, module) + return params -# Module invocations -def setup_network_acl(client, module): +def add_network_acl_entries( + client, nacl_id: str, ansible_entries: List[List[str]], egress: bool, check_mode: bool +) -> bool: changed = False - nacl = describe_network_acl(client, module) - if not nacl["NetworkAcls"]: - tags = {} - if module.params.get("name"): - tags["Name"] = module.params.get("name") - tags.update(module.params.get("tags") or {}) - nacl = create_network_acl(module.params.get("vpc_id"), client, module, tags) - nacl_id = nacl["NetworkAcl"]["NetworkAclId"] - subnets = subnets_to_associate(nacl, client, module) - replace_network_acl_association(nacl_id, subnets, client, module) - construct_acl_entries(nacl, client, module) + for entry in ansible_entries: changed = True - return changed, nacl["NetworkAcl"]["NetworkAclId"] - else: - changed = False - nacl_id = nacl["NetworkAcls"][0]["NetworkAclId"] - changed |= subnets_changed(nacl, client, module) - changed |= nacls_changed(nacl, client, module) - changed |= tags_changed(nacl_id, client, module) - return changed, nacl_id + if not check_mode: + create_network_acl_entry( + client, + network_acl_id=nacl_id, + protocol=str(PROTOCOL_NUMBERS[entry[1]]), + egress=egress, + rule_action=entry[2], + rule_number=entry[0], + **process_rule_entry(entry), + ) + return changed -def remove_network_acl(client, module): +def associate_nacl_to_subnets(client, module: AnsibleAWSModule, nacl_id: str, subnets_ids: List[str]) -> bool: changed = False - result = dict() - nacl = describe_network_acl(client, module) - if nacl["NetworkAcls"]: - nacl_id = nacl["NetworkAcls"][0]["NetworkAclId"] - vpc_id = nacl["NetworkAcls"][0]["VpcId"] - associations = nacl["NetworkAcls"][0]["Associations"] - assoc_ids = [a["NetworkAclAssociationId"] for a in associations] - default_nacl_id = find_default_vpc_nacl(vpc_id, client, module) - if not default_nacl_id: - result = {vpc_id: "Default NACL ID not found - Check the VPC ID"} - return changed, result - if restore_default_associations(assoc_ids, default_nacl_id, client, module): - delete_network_acl(nacl_id, client, module) + if subnets_ids: + network_acls = describe_network_acls(client, Filters=[{"Name": "association.subnet-id", "Values": subnets_ids}]) + associations = [ + association["NetworkAclAssociationId"] + for nacl in network_acls + for association in nacl["Associations"] + if association["SubnetId"] in subnets_ids + ] + for association_id in associations: changed = True - result[nacl_id] = "Successfully deleted" - return changed, result - if not assoc_ids: - delete_network_acl(nacl_id, client, module) - changed = True - result[nacl_id] = "Successfully deleted" - return changed, result - return changed, result - + if not module.check_mode: + replace_network_acl_association(client, network_acl_id=nacl_id, association_id=association_id) + return changed -# Boto3 client methods -@AWSRetry.jittered_backoff() -def _create_network_acl(client, *args, **kwargs): - return client.create_network_acl(*args, **kwargs) +def ensure_present(client, module: AnsibleAWSModule) -> None: + changed = False + nacl = describe_network_acl(client, module) + nacl_id = None + subnets_ids = [] + subnets = module.params.get("subnets") + if subnets: + subnets_ids = find_subnets_ids(client, module, subnets) -def create_network_acl(vpc_id, client, module, tags): - params = dict(VpcId=vpc_id) - if tags: - params["TagSpecifications"] = boto3_tag_specifications(tags, ["network-acl"]) - try: + if not nacl: if module.check_mode: - nacl = dict(NetworkAcl=dict(NetworkAclId="nacl-00000000")) - else: - nacl = _create_network_acl(client, **params) - except botocore.exceptions.ClientError as e: - module.fail_json_aws(e) - return nacl - + module.exit_json(changed=True, msg="Would have created Network ACL if not in check mode.") -@AWSRetry.jittered_backoff(catch_extra_error_codes=["InvalidNetworkAclID.NotFound"]) -def _create_network_acl_entry(client, *args, **kwargs): - return client.create_network_acl_entry(*args, **kwargs) - - -def create_network_acl_entry(params, client, module): - try: - if not module.check_mode: - _create_network_acl_entry(client, **params) - except botocore.exceptions.ClientError as e: - module.fail_json_aws(e) + # Create Network ACL + tags = {} + name = module.params.get("name") + vpc_id = module.params.get("vpc_id") + if name: + tags["Name"] = name + if module.params.get("tags"): + tags.update(module.params.get("tags")) + nacl = create_network_acl(client, vpc_id, tags) + changed = True + # Associate Subnets to Network ACL + nacl_id = nacl["NetworkAclId"] + changed |= associate_nacl_to_subnets(client, module, nacl_id, subnets_ids) -@AWSRetry.jittered_backoff() -def _delete_network_acl(client, *args, **kwargs): - return client.delete_network_acl(*args, **kwargs) + # Create Network ACL entries (ingress and egress) + changed |= add_network_acl_entries( + client, nacl_id, module.params.get("ingress"), egress=False, check_mode=module.check_mode + ) + changed |= add_network_acl_entries( + client, nacl_id, module.params.get("egress"), egress=True, check_mode=module.check_mode + ) + else: + nacl_id = nacl["NetworkAclId"] + changed |= subnets_changed(client, module, nacl_id, subnets_ids) + changed |= nacls_changed(client, module, nacl) + changed |= tags_changed(client, module, nacl_id) + module.exit_json(changed=changed, nacl_id=nacl_id) -def delete_network_acl(nacl_id, client, module): - try: - if not module.check_mode: - _delete_network_acl(client, NetworkAclId=nacl_id) - except botocore.exceptions.ClientError as e: - module.fail_json_aws(e) +def ensure_absent(client, module: AnsibleAWSModule) -> None: + changed = False + result = {} + nacl = describe_network_acl(client, module) + if not nacl: + module.exit_json(changed=changed) -@AWSRetry.jittered_backoff(catch_extra_error_codes=["InvalidNetworkAclID.NotFound"]) -def _delete_network_acl_entry(client, *args, **kwargs): - return client.delete_network_acl_entry(*args, **kwargs) + nacl_id = nacl["NetworkAclId"] + vpc_id = nacl["VpcId"] + associations = nacl["Associations"] + assoc_ids = [a["NetworkAclAssociationId"] for a in associations] + # Find default NACL associated to the VPC + default_nacl_id = find_default_vpc_nacl(client, vpc_id) + if not default_nacl_id: + module.exit_json(changed=changed, msg="Default NACL ID not found - Check the VPC ID") -def delete_network_acl_entry(params, client, module): - try: + # Replace Network ACL association + for assoc_id in assoc_ids: + changed = True if not module.check_mode: - _delete_network_acl_entry(client, **params) - except botocore.exceptions.ClientError as e: - module.fail_json_aws(e) - - -@AWSRetry.jittered_backoff() -def _describe_network_acls(client, **kwargs): - return client.describe_network_acls(**kwargs) - - -@AWSRetry.jittered_backoff(catch_extra_error_codes=["InvalidNetworkAclID.NotFound"]) -def _describe_network_acls_retry_missing(client, **kwargs): - return client.describe_network_acls(**kwargs) + replace_network_acl_association(client, network_acl_id=default_nacl_id, association_id=assoc_id) + # Delete Network ACL + changed = True + if module.check_mode: + module.exit_json(changed=changed, msg=f"Would have deleted Network ACL id '{nacl_id}' if not in check mode.") -def describe_acl_associations(subnets, client, module): - if not subnets: - return [] - try: - results = _describe_network_acls_retry_missing( - client, Filters=[{"Name": "association.subnet-id", "Values": subnets}] - ) - except botocore.exceptions.ClientError as e: - module.fail_json_aws(e) - associations = results["NetworkAcls"][0]["Associations"] - return [a["NetworkAclAssociationId"] for a in associations if a["SubnetId"] in subnets] - + changed = delete_network_acl(client, network_acl_id=nacl_id) + module.exit_json(changed=changed, msg=f"Network ACL id '{nacl_id}' successfully deleted.") -def describe_network_acl(client, module): - try: - if module.params.get("nacl_id"): - nacl = _describe_network_acls( - client, Filters=[{"Name": "network-acl-id", "Values": [module.params.get("nacl_id")]}] - ) - else: - nacl = _describe_network_acls(client, Filters=[{"Name": "tag:Name", "Values": [module.params.get("name")]}]) - except botocore.exceptions.ClientError as e: - module.fail_json_aws(e) - return nacl - - -def find_acl_by_id(nacl_id, client, module): - try: - return _describe_network_acls_retry_missing(client, NetworkAclIds=[nacl_id]) - except botocore.exceptions.ClientError as e: - module.fail_json_aws(e) - - -def find_default_vpc_nacl(vpc_id, client, module): - try: - response = _describe_network_acls_retry_missing(client, Filters=[{"Name": "vpc-id", "Values": [vpc_id]}]) - except botocore.exceptions.ClientError as e: - module.fail_json_aws(e) - nacls = response["NetworkAcls"] - return [n["NetworkAclId"] for n in nacls if n["IsDefault"] is True] +def describe_network_acl(client, module: AnsibleAWSModule) -> Optional[Dict[str, Any]]: + nacl_id = module.params.get("nacl_id") + name = module.params.get("name") -def find_subnet_ids_by_nacl_id(nacl_id, client, module): - try: - results = _describe_network_acls_retry_missing( - client, Filters=[{"Name": "association.network-acl-id", "Values": [nacl_id]}] - ) - except botocore.exceptions.ClientError as e: - module.fail_json_aws(e) - if results["NetworkAcls"]: - associations = results["NetworkAcls"][0]["Associations"] - return [s["SubnetId"] for s in associations if s["SubnetId"]] + if nacl_id: + filters = [{"Name": "network-acl-id", "Values": [nacl_id]}] else: - return [] - - -@AWSRetry.jittered_backoff(catch_extra_error_codes=["InvalidNetworkAclID.NotFound"]) -def _replace_network_acl_association(client, *args, **kwargs): - return client.replace_network_acl_association(*args, **kwargs) + filters = [{"Name": "tag:Name", "Values": [name]}] + network_acls = describe_network_acls(client, Filters=filters) + return None if not network_acls else network_acls[0] -def replace_network_acl_association(nacl_id, subnets, client, module): - params = dict() - params["NetworkAclId"] = nacl_id - for association in describe_acl_associations(subnets, client, module): - params["AssociationId"] = association - try: - if not module.check_mode: - _replace_network_acl_association(client, **params) - except botocore.exceptions.ClientError as e: - module.fail_json_aws(e) - - -@AWSRetry.jittered_backoff(catch_extra_error_codes=["InvalidNetworkAclID.NotFound"]) -def _replace_network_acl_entry(client, *args, **kwargs): - return client.replace_network_acl_entry(*args, **kwargs) +def find_default_vpc_nacl(client, vpc_id: str) -> Optional[str]: + default_nacl_id = None + for nacl in describe_network_acls(client, Filters=[{"Name": "vpc-id", "Values": [vpc_id]}]): + if nacl.get("IsDefault", False): + default_nacl_id = nacl["NetworkAclId"] + break + return default_nacl_id -def replace_network_acl_entry(entries, Egress, nacl_id, client, module): - for entry in entries: - params = entry - params["NetworkAclId"] = nacl_id - try: - if not module.check_mode: - _replace_network_acl_entry(client, **params) - except botocore.exceptions.ClientError as e: - module.fail_json_aws(e) - +def find_subnets_ids(client, module: AnsibleAWSModule, subnets_ids_or_names: List[str]) -> List[str]: + subnets_ids = [] + subnets_names = [] -@AWSRetry.jittered_backoff(catch_extra_error_codes=["InvalidNetworkAclID.NotFound"]) -def _replace_network_acl_association(client, *args, **kwargs): - return client.replace_network_acl_association(*args, **kwargs) + # Find Subnets by ID + subnets = describe_subnets(client, Filters=[{"Name": "subnet-id", "Values": subnets_ids_or_names}]) + subnets_ids += [subnet["SubnetId"] for subnet in subnets] + subnets_names += [tag["Value"] for subnet in subnets for tag in subnet.get("Tags", []) if tag["Key"] == "Name"] + # Find Subnets by Name + subnets = describe_subnets(client, Filters=[{"Name": "tag:Name", "Values": subnets_ids_or_names}]) + subnets_ids += [subnet["SubnetId"] for subnet in subnets] + subnets_names += [tag["Value"] for subnet in subnets for tag in subnet.get("Tags", []) if tag["Key"] == "Name"] -def restore_default_acl_association(params, client, module): - try: - if not module.check_mode: - _replace_network_acl_association(client, **params) - except botocore.exceptions.ClientError as e: - module.fail_json_aws(e) - - -@AWSRetry.jittered_backoff() -def _describe_subnets(client, *args, **kwargs): - return client.describe_subnets(*args, **kwargs) - - -def subnets_to_associate(nacl, client, module): - params = list(module.params.get("subnets")) - if not params: - return [] - all_found = [] - if any(x.startswith("subnet-") for x in params): - try: - subnets = _describe_subnets(client, Filters=[{"Name": "subnet-id", "Values": params}]) - all_found.extend(subnets.get("Subnets", [])) - except botocore.exceptions.ClientError as e: - module.fail_json_aws(e) - if len(params) != len(all_found): - try: - subnets = _describe_subnets(client, Filters=[{"Name": "tag:Name", "Values": params}]) - all_found.extend(subnets.get("Subnets", [])) - except botocore.exceptions.ClientError as e: - module.fail_json_aws(e) - return list(set(s["SubnetId"] for s in all_found if s.get("SubnetId"))) + unexisting_subnets = [s for s in subnets_ids_or_names if s not in subnets_names + subnets_ids] + if unexisting_subnets: + module.fail_json(msg=f"The following subnets do not exist: {unexisting_subnets}") + return subnets_ids def main(): @@ -576,30 +501,35 @@ def main(): vpc_id=dict(), name=dict(), nacl_id=dict(), - subnets=dict(required=False, type="list", default=list(), elements="str"), + subnets=dict(required=False, type="list", default=[], elements="str"), tags=dict(required=False, type="dict", aliases=["resource_tags"]), purge_tags=dict(required=False, type="bool", default=True), ingress=dict(required=False, type="list", default=list(), elements="list"), egress=dict(required=False, type="list", default=list(), elements="list"), state=dict(default="present", choices=["present", "absent"]), ) + + mutually_exclusive = [ + ["name", "nacl_id"], + ] + module = AnsibleAWSModule( argument_spec=argument_spec, supports_check_mode=True, required_one_of=[["name", "nacl_id"]], required_if=[["state", "present", ["vpc_id"]]], + mutually_exclusive=mutually_exclusive, ) - state = module.params.get("state").lower() - client = module.client("ec2") - invocations = { - "present": setup_network_acl, - "absent": remove_network_acl, - } - (changed, results) = invocations[state](client, module) - module.exit_json(changed=changed, nacl_id=results) + try: + if module.params.get("state") == "present": + ensure_present(client, module) + else: + ensure_absent(client, module) + except AnsibleEC2Error as e: + module.fail_json_aws_error(e) if __name__ == "__main__": diff --git a/plugins/modules/ec2_vpc_nacl_info.py b/plugins/modules/ec2_vpc_nacl_info.py index d95508a894e..9e0bc4e7f05 100644 --- a/plugins/modules/ec2_vpc_nacl_info.py +++ b/plugins/modules/ec2_vpc_nacl_info.py @@ -102,15 +102,15 @@ sample: [[100, 'all', 'allow', '0.0.0.0/0', null, null, null, null]] """ -try: - import botocore -except ImportError: - pass # caught by AnsibleAWSModule +from typing import Any +from typing import Dict +from typing import List +from typing import Union from ansible.module_utils.common.dict_transformations import camel_dict_to_snake_dict -from ansible_collections.amazon.aws.plugins.module_utils.botocore import is_boto3_error_code -from ansible_collections.amazon.aws.plugins.module_utils.retries import AWSRetry +from ansible_collections.amazon.aws.plugins.module_utils.ec2 import AnsibleEC2Error +from ansible_collections.amazon.aws.plugins.module_utils.ec2 import describe_network_acls from ansible_collections.amazon.aws.plugins.module_utils.tagging import boto3_tag_list_to_ansible_dict from ansible_collections.amazon.aws.plugins.module_utils.transformation import ansible_dict_to_boto3_filter_list @@ -121,55 +121,60 @@ PROTOCOL_NAMES = {"-1": "all", "1": "icmp", "6": "tcp", "17": "udp"} -def list_ec2_vpc_nacls(connection, module): +def format_nacl(nacl: Dict[str, Any]) -> Dict[str, Any]: + # Turn the boto3 result into ansible friendly snake cases + nacl = camel_dict_to_snake_dict(nacl) + + # convert boto3 tags list into ansible dict + if "tags" in nacl: + nacl["tags"] = boto3_tag_list_to_ansible_dict(nacl["tags"], "key", "value") + + # Convert NACL entries + if "entries" in nacl: + nacl["egress"] = [ + nacl_entry_to_list(entry) for entry in nacl["entries"] if entry["rule_number"] < 32767 and entry["egress"] + ] + nacl["ingress"] = [ + nacl_entry_to_list(entry) + for entry in nacl["entries"] + if entry["rule_number"] < 32767 and not entry["egress"] + ] + del nacl["entries"] + + # Read subnets from NACL Associations + if "associations" in nacl: + nacl["subnets"] = [a["subnet_id"] for a in nacl["associations"]] + del nacl["associations"] + + # Read Network ACL id + if "network_acl_id" in nacl: + nacl["nacl_id"] = nacl["network_acl_id"] + del nacl["network_acl_id"] + + return nacl + + +def list_ec2_vpc_nacls(connection, module: AnsibleAWSModule) -> None: nacl_ids = module.params.get("nacl_ids") - filters = ansible_dict_to_boto3_filter_list(module.params.get("filters")) + filters = module.params.get("filters") - if nacl_ids is None: - nacl_ids = [] + params = {} + if filters: + params["Filters"] = ansible_dict_to_boto3_filter_list(filters) + if nacl_ids: + params["NetworkAclIds"] = nacl_ids try: - nacls = connection.describe_network_acls(aws_retry=True, NetworkAclIds=nacl_ids, Filters=filters) - except is_boto3_error_code("InvalidNetworkAclID.NotFound"): - module.fail_json(msg="Unable to describe ACL. NetworkAcl does not exist") - except ( - botocore.exceptions.ClientError, - botocore.exceptions.BotoCoreError, - ) as e: # pylint: disable=duplicate-except - module.fail_json_aws(e, msg=f"Unable to describe network ACLs {nacl_ids}") - - # Turn the boto3 result in to ansible_friendly_snaked_names - snaked_nacls = [] - for nacl in nacls["NetworkAcls"]: - snaked_nacls.append(camel_dict_to_snake_dict(nacl)) - - # Turn the boto3 result in to ansible friendly tag dictionary - for nacl in snaked_nacls: - if "tags" in nacl: - nacl["tags"] = boto3_tag_list_to_ansible_dict(nacl["tags"], "key", "value") - if "entries" in nacl: - nacl["egress"] = [ - nacl_entry_to_list(entry) - for entry in nacl["entries"] - if entry["rule_number"] < 32767 and entry["egress"] - ] - nacl["ingress"] = [ - nacl_entry_to_list(entry) - for entry in nacl["entries"] - if entry["rule_number"] < 32767 and not entry["egress"] - ] - del nacl["entries"] - if "associations" in nacl: - nacl["subnets"] = [a["subnet_id"] for a in nacl["associations"]] - del nacl["associations"] - if "network_acl_id" in nacl: - nacl["nacl_id"] = nacl["network_acl_id"] - del nacl["network_acl_id"] - - module.exit_json(nacls=snaked_nacls) - - -def nacl_entry_to_list(entry): + network_acls = describe_network_acls(connection, **params) + if not network_acls: + module.fail_json(msg="Unable to describe ACL. NetworkAcl does not exist") + except AnsibleEC2Error as e: + module.fail_json_aws_error(e) + + module.exit_json(nacls=[format_nacl(nacl) for nacl in network_acls]) + + +def nacl_entry_to_list(entry: Dict[str, Any]) -> List[Union[str, int, None]]: # entry list format # [ rule_num, protocol name or number, allow or deny, ipv4/6 cidr, icmp type, icmp code, port from, port to] elist = [] @@ -217,7 +222,7 @@ def main(): supports_check_mode=True, ) - connection = module.client("ec2", retry_decorator=AWSRetry.jittered_backoff()) + connection = module.client("ec2") list_ec2_vpc_nacls(connection, module) diff --git a/tests/integration/targets/ec2_vpc_nacl/tasks/ingress_and_egress.yml b/tests/integration/targets/ec2_vpc_nacl/tasks/ingress_and_egress.yml index 875e7f0b2d7..432aaf3ba99 100644 --- a/tests/integration/targets/ec2_vpc_nacl/tasks/ingress_and_egress.yml +++ b/tests/integration/targets/ec2_vpc_nacl/tasks/ingress_and_egress.yml @@ -1,7 +1,8 @@ # ============================================================ -- block: - - name: create ingress and egress rules using subnet IDs - ec2_vpc_nacl: +- name: Test Ingress and Egress rules + block: + - name: Create ingress and egress rules using subnet IDs + community.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" name: "{{ nacl_name }}" subnets: "{{ subnet_ids }}" @@ -16,20 +17,20 @@ state: 'present' register: nacl - - name: assert the network acl was created - assert: + - name: Assert the network acl was created + ansible.builtin.assert: that: - nacl.changed - nacl.nacl_id.startswith('acl-') - - name: get network ACL facts - ec2_vpc_nacl_info: + - name: Get network ACL facts + community.aws.ec2_vpc_nacl_info: nacl_ids: - "{{ nacl.nacl_id }}" register: nacl_facts - - name: assert the nacl has the correct attributes - assert: + - name: Assert the nacl has the correct attributes + ansible.builtin.assert: that: - nacl_facts.nacls | length == 1 - nacl_facts.nacls[0].ingress | length == 3 @@ -37,8 +38,8 @@ # ============================================================ - - name: remove an ingress rule - ec2_vpc_nacl: + - name: Remove an ingress rule + community.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" name: "{{ nacl_name }}" subnets: "{{ subnet_ids }}" @@ -52,20 +53,20 @@ state: 'present' register: nacl - - name: assert the network acl changed - assert: + - name: Assert the network acl changed + ansible.builtin.assert: that: - nacl.changed - nacl.nacl_id.startswith('acl-') - - name: get network ACL facts - ec2_vpc_nacl_info: + - name: Get network ACL facts + community.aws.ec2_vpc_nacl_info: nacl_ids: - "{{ nacl.nacl_id }}" register: nacl_facts - - name: assert the nacl has the correct attributes - assert: + - name: Assert the nacl has the correct attributes + ansible.builtin.assert: that: - nacl_facts.nacls | length == 1 - nacl_facts.nacls[0].ingress | length == 2 @@ -73,8 +74,8 @@ # ============================================================ - - name: remove the egress rule - ec2_vpc_nacl: + - name: Remove the egress rule + community.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" name: "{{ nacl_name }}" subnets: "{{ subnet_ids }}" @@ -87,20 +88,20 @@ state: 'present' register: nacl - - name: assert the network acl changed - assert: + - name: Assert the network acl changed + ansible.builtin.assert: that: - nacl.changed - nacl.nacl_id.startswith('acl-') - - name: get network ACL facts - ec2_vpc_nacl_info: + - name: Get network ACL facts + community.aws.ec2_vpc_nacl_info: nacl_ids: - "{{ nacl.nacl_id }}" register: nacl_facts - - name: assert the nacl has the correct attributes - assert: + - name: Assert the nacl has the correct attributes + ansible.builtin.assert: that: - nacl_facts.nacls | length == 1 - nacl_facts.nacls[0].ingress | length == 2 @@ -108,8 +109,8 @@ # ============================================================ - - name: add egress rules - ec2_vpc_nacl: + - name: Add egress rules + community.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" name: "{{ nacl_name }}" subnets: "{{ subnet_ids }}" @@ -124,20 +125,20 @@ state: 'present' register: nacl - - name: assert the network acl changed - assert: + - name: Assert the network acl changed + ansible.builtin.assert: that: - nacl.changed - nacl.nacl_id.startswith('acl-') - - name: get network ACL facts - ec2_vpc_nacl_info: + - name: Get network ACL facts + community.aws.ec2_vpc_nacl_info: nacl_ids: - "{{ nacl.nacl_id }}" register: nacl_facts - - name: assert the nacl has the correct attributes - assert: + - name: Assert the nacl has the correct attributes + ansible.builtin.assert: that: - nacl_facts.nacls | length == 1 - nacl_facts.nacls[0].ingress | length == 2 @@ -145,14 +146,14 @@ # ============================================================ - - name: remove the network ACL - ec2_vpc_nacl: + - name: Remove the network ACL + community.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" name: "{{ nacl_name }}" state: absent register: nacl - - name: assert nacl was removed - assert: + - name: Assert nacl was removed + ansible.builtin.assert: that: - nacl.changed diff --git a/tests/integration/targets/ec2_vpc_nacl/tasks/ipv6.yml b/tests/integration/targets/ec2_vpc_nacl/tasks/ipv6.yml index 1366971613a..2113fb4aa9c 100644 --- a/tests/integration/targets/ec2_vpc_nacl/tasks/ipv6.yml +++ b/tests/integration/targets/ec2_vpc_nacl/tasks/ipv6.yml @@ -1,9 +1,10 @@ -- block: +- name: Test using IPv6 + block: # ============================================================ - - name: create ingress and egress rules using subnet names - ec2_vpc_nacl: + - name: Create ingress and egress rules using subnet names + community.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_ipv6_id }}" name: "{{ nacl_name }}" subnets: @@ -18,15 +19,18 @@ - [100, 'all', 'allow', '0.0.0.0/0', null, null, null, null] state: 'present' register: nacl - - assert: + + - name: Assert that module returned the Network ACL id + ansible.builtin.assert: that: - nacl.nacl_id - - set_fact: + - name: Set fact for Network ACL ID + ansible.builtin.set_fact: nacl_id: "{{ nacl.nacl_id }}" - - name: add ipv6 entries - ec2_vpc_nacl: + - name: Add ipv6 entries + community.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_ipv6_id }}" name: "{{ nacl_name }}" subnets: @@ -45,26 +49,27 @@ state: 'present' register: nacl - - assert: + - name: Assert that module reported change while the Network ACL remained unchanged + ansible.builtin.assert: that: - nacl.changed - nacl.nacl_id == nacl_id - - name: get network ACL facts (test that it works with ipv6 entries) - ec2_vpc_nacl_info: + - name: Get network ACL facts (test that it works with ipv6 entries) + community.aws.ec2_vpc_nacl_info: nacl_ids: - "{{ nacl_id }}" register: nacl_facts - - name: assert the nacl has the correct attributes - assert: + - name: Assert the nacl has the correct attributes + ansible.builtin.assert: that: - nacl_facts.nacls | length == 1 - nacl_facts.nacls[0].ingress | length == 5 - nacl_facts.nacls[0].egress | length == 2 - - name: purge ingress entries - ec2_vpc_nacl: + - name: Purge ingress entries + community.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_ipv6_id }}" name: "{{ nacl_name }}" subnets: @@ -78,13 +83,14 @@ state: 'present' register: nacl - - assert: + - name: Assert that module reported change while the Network ACL remained unchanged + ansible.builtin.assert: that: - nacl.changed - nacl.nacl_id == nacl_id - - name: purge egress entries - ec2_vpc_nacl: + - name: Purge egress entries + community.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_ipv6_id }}" name: "{{ nacl_name }}" subnets: @@ -96,18 +102,19 @@ state: 'present' register: nacl - - assert: + - name: Assert that module reported change + ansible.builtin.assert: that: - nacl.changed - - name: get network ACL facts (test that removed entries are gone) - ec2_vpc_nacl_info: + - name: Get network ACL facts (test that removed entries are gone) + community.aws.ec2_vpc_nacl_info: nacl_ids: - "{{ nacl_id }}" register: nacl_facts - - name: assert the nacl has the correct attributes - assert: + - name: Assert the nacl has the correct attributes + ansible.builtin.assert: that: - nacl_facts.nacls | length == 1 - nacl_facts.nacls[0].ingress | length == 0 @@ -115,10 +122,10 @@ always: - - name: remove network ACL - ec2_vpc_nacl: + - name: Remove network ACL + community.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_ipv6_id }}" name: "{{ nacl_name }}" state: absent register: removed_acl - ignore_errors: yes + ignore_errors: true diff --git a/tests/integration/targets/ec2_vpc_nacl/tasks/main.yml b/tests/integration/targets/ec2_vpc_nacl/tasks/main.yml index 36c7ab2d8bb..445161ccd82 100644 --- a/tests/integration/targets/ec2_vpc_nacl/tasks/main.yml +++ b/tests/integration/targets/ec2_vpc_nacl/tasks/main.yml @@ -5,40 +5,39 @@ secret_key: "{{ aws_secret_key }}" session_token: "{{ security_token | default(omit) }}" region: "{{ aws_region }}" - collections: - - amazon.aws + block: # ============================================================ - - name: test without any parameters - ec2_vpc_nacl: + - name: Test without any parameters + community.aws.ec2_vpc_nacl: register: result - ignore_errors: yes + ignore_errors: true - - name: assert required parameters - assert: + - name: Assert required parameters + ansible.builtin.assert: that: - result.failed - "result.msg == 'one of the following is required: name, nacl_id'" - - name: get network ACL info without any parameters - ec2_vpc_nacl_info: + - name: Get network ACL info without any parameters + community.aws.ec2_vpc_nacl_info: register: nacl_facts - - name: assert we don't error + - name: Assert we don't error assert: that: - nacl_facts is succeeded - - name: get network ACL info with invalid ID - ec2_vpc_nacl_info: + - name: Get network ACL info with invalid ID + community.aws.ec2_vpc_nacl_info: nacl_ids: - 'acl-000000000000' register: nacl_facts - ignore_errors: yes + ignore_errors: true - - name: assert message mentions missing ACLs + - name: Assert message mentions missing ACLs assert: that: - nacl_facts is failed @@ -46,34 +45,34 @@ # ============================================================ - - name: fetch AZ availability - aws_az_info: + - name: Fetch AZ availability + amazon.aws.aws_az_info: register: az_info - name: Assert that we have multiple AZs available to us - assert: + ansible.builtin.assert: that: az_info.availability_zones | length >= 2 - - name: pick AZs - set_fact: + - name: Pick AZs + ansible.builtin.set_fact: az_one: '{{ az_info.availability_zones[0].zone_name }}' az_two: '{{ az_info.availability_zones[1].zone_name }}' # ============================================================ - - name: create a VPC - ec2_vpc_net: + - name: Create a VPC + amazon.aws.ec2_vpc_net: cidr_block: "{{ vpc_cidr }}" name: "{{ vpc_name }}" state: present register: vpc - name: Save VPC ID for later - set_fact: + ansible.builtin.set_fact: vpc_id: "{{ vpc.vpc.id }}" - - name: create subnets - ec2_vpc_subnet: + - name: Create subnets + amazon.aws.ec2_vpc_subnet: cidr: "{{ item.cidr }}" az: "{{ item.az }}" vpc_id: "{{ vpc_id }}" @@ -95,27 +94,29 @@ name: "{{ subnet_name }}-4" register: subnets - - name: set helpful facts about subnets - set_fact: + - name: Set helpful facts about subnets + ansible.builtin.set_fact: subnet_ids: "{{ subnets | community.general.json_query('results[*].subnet.id') }}" subnet_names: "{{ subnets | community.general.json_query('results[*].subnet.tags.Name') }}" - - name: create VPC for IPv6 tests - ec2_vpc_net: + - name: Create VPC for IPv6 tests + amazon.aws.ec2_vpc_net: cidr_block: "{{ vpc_ipv6_cidr }}" name: "{{ vpc_ipv6_name }}" state: present - ipv6_cidr: yes + ipv6_cidr: true register: vpc_result - - set_fact: + + - name: Set helpful IPv6 facts + ansible.builtin.set_fact: vpc_ipv6_id: "{{ vpc_result.vpc.id }}" vpc_ipv6_cidr_v6: "{{ _ipv6_cidr }}" subnet_ipv6: "{{ _ipv6_cidr | regex_replace('::/56', '::/64') }}" vars: _ipv6_cidr: "{{ vpc_result.vpc.ipv6_cidr_block_association_set[0].ipv6_cidr_block }}" - - name: create subnet with IPv6 - ec2_vpc_subnet: + - name: Create subnet with IPv6 + amazon.aws.ec2_vpc_subnet: cidr: "{{ vpc_ipv6_cidr }}" vpc_id: "{{ vpc_ipv6_id }}" ipv6_cidr: "{{ subnet_ipv6 }}" @@ -124,31 +125,29 @@ Name: "{{ subnet_name }}-ipv6" # ============================================================ - - - include_tasks: tasks/subnet_ids.yml - - - include_tasks: tasks/subnet_names.yml - - - include_tasks: tasks/tags.yml - - - include_tasks: tasks/ingress_and_egress.yml - - - include_tasks: tasks/ipv6.yml + - name: Run individual tasks + ansible.builtin.include_tasks: "tasks/{{ item }}.yml" + with_items: + - subnet_ids + - subnet_names + - tags + - ingress_and_egress + - ipv6 # ============================================================ always: - - name: remove network ACL - ec2_vpc_nacl: + - name: Remove network ACL + community.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" name: "{{ nacl_name }}" state: absent register: removed_acl - ignore_errors: yes + ignore_errors: true - - name: remove subnets - ec2_vpc_subnet: + - name: Remove subnets + amazon.aws.ec2_vpc_subnet: cidr: "{{ item.cidr }}" vpc_id: "{{ item.vpc_id | default(vpc_id) }}" state: absent @@ -159,14 +158,14 @@ - cidr: "{{ subnet_4 }}" - cidr: "{{ vpc_ipv6_cidr }}" vpc_id: "{{ vpc_ipv6_id }}" - ignore_errors: yes + ignore_errors: true register: removed_subnets - - name: remove the VPCs - ec2_vpc_net: + - name: Remove the VPCs + amazon.aws.ec2_vpc_net: vpc_id: "{{ item }}" state: absent - ignore_errors: yes + ignore_errors: true register: removed_vpc with_items: - '{{ vpc_id }}' diff --git a/tests/integration/targets/ec2_vpc_nacl/tasks/subnet_ids.yml b/tests/integration/targets/ec2_vpc_nacl/tasks/subnet_ids.yml index 4e1affa1f34..3a367e84f89 100644 --- a/tests/integration/targets/ec2_vpc_nacl/tasks/subnet_ids.yml +++ b/tests/integration/targets/ec2_vpc_nacl/tasks/subnet_ids.yml @@ -1,7 +1,7 @@ # ============================================================ -- name: create ingress and egress rules using subnet IDs - ec2_vpc_nacl: +- name: Create ingress and egress rules using subnet IDs + community.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" name: "{{ nacl_name }}" subnets: "{{ subnet_ids }}" @@ -16,23 +16,24 @@ state: 'present' register: nacl -- set_fact: +- name: Set helpful fact for Network ACL ID + ansible.builtin.set_fact: nacl_id: "{{ nacl.nacl_id }}" -- name: assert the network acl was created - assert: +- name: Assert the network acl was created + ansible.builtin.assert: that: - nacl.changed - nacl.nacl_id.startswith('acl-') -- name: get network ACL facts - ec2_vpc_nacl_info: +- name: Get network ACL facts + community.aws.ec2_vpc_nacl_info: nacl_ids: - "{{ nacl_id }}" register: nacl_facts -- name: assert the nacl has the correct attributes - assert: +- name: Assert the nacl has the correct attributes + ansible.builtin.assert: that: - nacl_facts.nacls | length == 1 - nacl_facts.nacls[0].nacl_id == nacl_id @@ -44,8 +45,8 @@ # ============================================================ -- name: test idempotence - ec2_vpc_nacl: +- name: Test idempotence + community.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" name: "{{ nacl_name }}" subnets: "{{ subnet_ids }}" @@ -60,28 +61,28 @@ state: 'present' register: nacl -- name: assert the network acl already existed - assert: +- name: Assert the network acl already existed + ansible.builtin.assert: that: - not nacl.changed - nacl.nacl_id == nacl_id - nacl.nacl_id.startswith('acl-') -- name: get network ACL facts - ec2_vpc_nacl_info: +- name: Get network ACL facts + community.aws.ec2_vpc_nacl_info: nacl_ids: - "{{ nacl.nacl_id }}" register: nacl_facts_idem -- name: assert the facts are the same as before - assert: +- name: Assert the facts are the same as before + ansible.builtin.assert: that: - nacl_facts_idem == nacl_facts # ============================================================ -- name: remove a subnet from the network ACL - ec2_vpc_nacl: +- name: Remove a subnet from the network ACL + community.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" name: "{{ nacl_name }}" subnets: @@ -99,21 +100,21 @@ state: 'present' register: nacl -- name: assert the network ACL changed - assert: +- name: Assert the network ACL changed + ansible.builtin.assert: that: - nacl.changed - nacl.nacl_id.startswith('acl-') - nacl.nacl_id == nacl_id -- name: get network ACL facts - ec2_vpc_nacl_info: +- name: Get network ACL facts + community.aws.ec2_vpc_nacl_info: nacl_id: - "{{ nacl.nacl_id }}" register: nacl_facts -- name: assert the nacl has the correct attributes - assert: +- name: Assert the nacl has the correct attributes + ansible.builtin.assert: that: - nacl_facts.nacls | length == 1 - nacl_facts.nacls[0].nacl_id == nacl_id @@ -125,37 +126,38 @@ # ============================================================ -- name: remove the network ACL - ec2_vpc_nacl: +- name: Remove the network ACL + community.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" name: "{{ nacl_name }}" state: absent register: nacl -- name: assert nacl was removed - assert: +- name: Assert nacl was removed + ansible.builtin.assert: that: - nacl.changed -- name: re-remove the network ACL by name (test idempotency) - ec2_vpc_nacl: +- name: Re-remove the network ACL by name (test idempotency) + community.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" name: "{{ nacl_name }}" state: absent register: nacl -- name: assert nacl was removed - assert: + +- name: Assert nacl was removed + ansible.builtin.assert: that: - nacl is not changed -- name: re-remove the network ACL by id (test idempotency) - ec2_vpc_nacl: +- name: Re-remove the network ACL by id (test idempotency) + community.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" nacl_id: "{{ nacl_id }}" state: absent register: nacl -- name: assert nacl was removed - assert: +- name: Assert nacl was removed + ansible.builtin.assert: that: - nacl is not changed diff --git a/tests/integration/targets/ec2_vpc_nacl/tasks/subnet_names.yml b/tests/integration/targets/ec2_vpc_nacl/tasks/subnet_names.yml index 4db7e1b2068..dc44fef804a 100644 --- a/tests/integration/targets/ec2_vpc_nacl/tasks/subnet_names.yml +++ b/tests/integration/targets/ec2_vpc_nacl/tasks/subnet_names.yml @@ -1,7 +1,7 @@ # ============================================================ -- name: create ingress and egress rules using subnet names - ec2_vpc_nacl: +- name: Create ingress and egress rules using subnet names + community.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" name: "{{ nacl_name }}" subnets: "{{ subnet_names }}" @@ -16,23 +16,24 @@ state: 'present' register: nacl -- set_fact: +- name: Set helpful fact for Network ACL ID + ansible.builtin.set_fact: nacl_id: "{{ nacl.nacl_id }}" -- name: assert the network acl was created - assert: +- name: Assert the network acl was created + ansible.builtin.assert: that: - nacl.changed - nacl.nacl_id.startswith('acl-') -- name: get network ACL facts - ec2_vpc_nacl_info: +- name: Get network ACL facts + community.aws.ec2_vpc_nacl_info: nacl_ids: - "{{ nacl_id }}" register: nacl_facts -- name: assert the nacl has the correct attributes - assert: +- name: Assert the nacl has the correct attributes + ansible.builtin.assert: that: - nacl_facts.nacls | length == 1 - nacl_facts.nacls[0].nacl_id == nacl_id @@ -43,8 +44,8 @@ # ============================================================ -- name: test idempotence - ec2_vpc_nacl: +- name: Test idempotence + community.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" name: "{{ nacl_name }}" subnets: "{{ subnet_names }}" @@ -59,28 +60,28 @@ state: 'present' register: nacl -- name: assert the network acl already existed - assert: +- name: Assert the network acl already existed + ansible.builtin.assert: that: - not nacl.changed - nacl.nacl_id == nacl_id - nacl.nacl_id.startswith('acl-') -- name: get network ACL facts - ec2_vpc_nacl_info: +- name: Get network ACL facts + community.aws.ec2_vpc_nacl_info: nacl_ids: - "{{ nacl.nacl_id }}" register: nacl_facts_idem -- name: assert the facts are the same as before - assert: +- name: Assert the facts are the same as before + ansible.builtin.assert: that: - nacl_facts_idem == nacl_facts # ============================================================ -- name: remove a subnet from the network ACL - ec2_vpc_nacl: +- name: Remove a subnet from the network ACL + community.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" name: "{{ nacl_name }}" subnets: @@ -98,21 +99,21 @@ state: 'present' register: nacl -- name: assert the network ACL changed - assert: +- name: Assert the network ACL changed + ansible.builtin.assert: that: - nacl.changed - nacl.nacl_id == nacl_id - nacl.nacl_id.startswith('acl-') -- name: get network ACL facts - ec2_vpc_nacl_info: +- name: Get network ACL facts + community.aws.ec2_vpc_nacl_info: nacl_ids: - "{{ nacl.nacl_id }}" register: nacl_facts -- name: assert the nacl has the correct attributes - assert: +- name: Assert the nacl has the correct attributes + ansible.builtin.assert: that: - nacl_facts.nacls | length == 1 - nacl_facts.nacls[0].nacl_id == nacl_id @@ -123,14 +124,14 @@ # ============================================================ -- name: remove the network ACL - ec2_vpc_nacl: +- name: Remove the network ACL + community.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" name: "{{ nacl_name }}" state: absent register: nacl -- name: assert nacl was removed - assert: +- name: Assert nacl was removed + ansible.builtin.assert: that: - nacl.changed diff --git a/tests/integration/targets/ec2_vpc_nacl/tasks/tags.yml b/tests/integration/targets/ec2_vpc_nacl/tasks/tags.yml index da3ad71dda3..0e69ce760ac 100644 --- a/tests/integration/targets/ec2_vpc_nacl/tasks/tags.yml +++ b/tests/integration/targets/ec2_vpc_nacl/tasks/tags.yml @@ -1,4 +1,5 @@ -- vars: +- name: Run test from tags.yml + vars: first_tags: 'Key with Spaces': Value with spaces CamelCaseKey: CamelCaseValue @@ -30,40 +31,40 @@ # ============================================================ - - name: create a network ACL using subnet IDs - ec2_vpc_nacl: + - name: Create a network ACL using subnet IDs + community.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" name: "{{ nacl_name }}" subnets: "{{ subnet_ids }}" state: 'present' register: nacl - - name: assert the network acl was created - assert: + - name: Assert the network acl was created + ansible.builtin.assert: that: - nacl.changed - nacl.nacl_id.startswith('acl-') - name: Store NACL ID - set_fact: + ansible.builtin.set_fact: nacl_id: '{{ nacl.nacl_id }}' - - name: get network ACL facts - ec2_vpc_nacl_info: + - name: Get network ACL facts + community.aws.ec2_vpc_nacl_info: nacl_ids: - "{{ nacl_id }}" register: nacl_info - - name: assert the nacl has the correct attributes - assert: + - name: Assert the nacl has the correct attributes + ansible.builtin.assert: that: - nacl_info.nacls[0].nacl_id == nacl_id - nacl_info.nacls[0].tags == name_tags # ============================================================ - - name: (check) add tags - ec2_vpc_nacl: + - name: Add tags (check mode) + community.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" name: "{{ nacl_name }}" subnets: "{{ subnet_ids }}" @@ -72,36 +73,37 @@ register: nacl check_mode: True - - name: assert would change - assert: + - name: Assert would change + ansible.builtin.assert: that: - nacl is changed - nacl.nacl_id == nacl_id - - name: add tags - ec2_vpc_nacl: + - name: Add tags + community.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" name: "{{ nacl_name }}" subnets: "{{ subnet_ids }}" tags: "{{ first_tags }}" state: 'present' register: nacl - - name: get network ACL facts - ec2_vpc_nacl_info: + + - name: Get network ACL facts + community.aws.ec2_vpc_nacl_info: nacl_ids: - "{{ nacl.nacl_id }}" register: nacl_info - - name: verify the tags were added - assert: + - name: Verify the tags were added + ansible.builtin.assert: that: - nacl is changed - nacl.nacl_id == nacl_id - nacl_info.nacls[0].nacl_id == nacl_id - nacl_info.nacls[0].tags == ( first_tags | combine(name_tags) ) - - name: (check) add tags - IDEMPOTENCY - ec2_vpc_nacl: + - name: Add tags - IDEMPOTENCY (check mode) + community.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" name: "{{ nacl_name }}" subnets: "{{ subnet_ids }}" @@ -110,28 +112,29 @@ register: nacl check_mode: True - - name: assert would not change - assert: + - name: Assert would not change + ansible.builtin.assert: that: - nacl is not changed - nacl.nacl_id == nacl_id - - name: add tags - IDEMPOTENCY - ec2_vpc_nacl: + - name: Add tags - IDEMPOTENCY + community.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" name: "{{ nacl_name }}" subnets: "{{ subnet_ids }}" tags: "{{ first_tags }}" state: 'present' register: nacl - - name: get network ACL facts - ec2_vpc_nacl_info: + + - name: Get network ACL facts + community.aws.ec2_vpc_nacl_info: nacl_ids: - "{{ nacl.nacl_id }}" register: nacl_info - - name: verify no change - assert: + - name: Verify no change + ansible.builtin.assert: that: - nacl is not changed - nacl.nacl_id == nacl_id @@ -140,14 +143,14 @@ # ============================================================ - - name: get network ACL facts by filter - ec2_vpc_nacl_info: + - name: Get network ACL facts by filter + community.aws.ec2_vpc_nacl_info: filters: "tag:Name": "{{ nacl_name }}" register: nacl_info - - name: assert the facts are the same as before - assert: + - name: Assert the facts are the same as before + ansible.builtin.assert: that: - nacl_info.nacls | length == 1 - nacl.nacl_id == nacl_id @@ -155,8 +158,8 @@ # ============================================================ - - name: (check) modify tags with purge - ec2_vpc_nacl: + - name: Modify tags with purge (check mode) + community.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" name: "{{ nacl_name }}" subnets: "{{ subnet_ids }}" @@ -165,36 +168,37 @@ register: nacl check_mode: True - - name: assert would change - assert: + - name: Assert would change + ansible.builtin.assert: that: - nacl is changed - nacl.nacl_id == nacl_id - - name: modify tags with purge - ec2_vpc_nacl: + - name: Modify tags with purge + community.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" name: "{{ nacl_name }}" subnets: "{{ subnet_ids }}" tags: "{{ second_tags }}" state: 'present' register: nacl - - name: get network ACL facts - ec2_vpc_nacl_info: + + - name: Get network ACL facts + community.aws.ec2_vpc_nacl_info: nacl_ids: - "{{ nacl.nacl_id }}" register: nacl_info - - name: verify the tags were added - assert: + - name: Verify the tags were added + ansible.builtin.assert: that: - nacl is changed - nacl.nacl_id == nacl_id - nacl_info.nacls[0].nacl_id == nacl_id - nacl_info.nacls[0].tags == ( second_tags | combine(name_tags) ) - - name: (check) modify tags with purge - IDEMPOTENCY - ec2_vpc_nacl: + - name: Modify tags with purge - IDEMPOTENCY (check mode) + community.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" name: "{{ nacl_name }}" subnets: "{{ subnet_ids }}" @@ -203,28 +207,29 @@ register: nacl check_mode: True - - name: assert would not change - assert: + - name: Assert would not change + ansible.builtin.assert: that: - nacl is not changed - nacl.nacl_id == nacl_id - - name: modify tags with purge - IDEMPOTENCY - ec2_vpc_nacl: + - name: Modify tags with purge - IDEMPOTENCY + community.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" name: "{{ nacl_name }}" subnets: "{{ subnet_ids }}" tags: "{{ second_tags }}" state: 'present' register: nacl - - name: get network ACL facts - ec2_vpc_nacl_info: + + - name: Get network ACL facts + community.aws.ec2_vpc_nacl_info: nacl_ids: - "{{ nacl.nacl_id }}" register: nacl_info - - name: verify no change - assert: + - name: Verify no change + ansible.builtin.assert: that: - nacl is not changed - nacl.nacl_id == nacl_id @@ -233,8 +238,8 @@ # ============================================================ - - name: (check) modify tags without purge - ec2_vpc_nacl: + - name: Modify tags without purge (check mode) + community.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" name: "{{ nacl_name }}" subnets: "{{ subnet_ids }}" @@ -244,14 +249,14 @@ register: nacl check_mode: True - - name: assert would change - assert: + - name: Assert would change + ansible.builtin.assert: that: - nacl is changed - nacl.nacl_id == nacl_id - - name: modify tags without purge - ec2_vpc_nacl: + - name: Modify tags without purge + community.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" name: "{{ nacl_name }}" subnets: "{{ subnet_ids }}" @@ -259,22 +264,23 @@ state: 'present' purge_tags: False register: nacl - - name: get network ACL facts - ec2_vpc_nacl_info: + + - name: Get network ACL facts + community.aws.ec2_vpc_nacl_info: nacl_ids: - "{{ nacl.nacl_id }}" register: nacl_info - - name: verify the tags were added - assert: + - name: Verify the tags were added + ansible.builtin.assert: that: - nacl is changed - nacl.nacl_id == nacl_id - nacl_info.nacls[0].nacl_id == nacl_id - nacl_info.nacls[0].tags == ( final_tags | combine(name_tags) ) - - name: (check) modify tags without purge - IDEMPOTENCY - ec2_vpc_nacl: + - name: Modify tags without purge - IDEMPOTENCY (check mode) + community.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" name: "{{ nacl_name }}" subnets: "{{ subnet_ids }}" @@ -284,14 +290,14 @@ register: nacl check_mode: True - - name: assert would not change - assert: + - name: Assert would not change + ansible.builtin.assert: that: - nacl is not changed - nacl.nacl_id == nacl_id - - name: modify tags without purge - IDEMPOTENCY - ec2_vpc_nacl: + - name: Modify tags without purge - IDEMPOTENCY + community.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" name: "{{ nacl_name }}" subnets: "{{ subnet_ids }}" @@ -299,14 +305,15 @@ state: 'present' purge_tags: False register: nacl - - name: get network ACL facts - ec2_vpc_nacl_info: + + - name: Get network ACL facts + community.aws.ec2_vpc_nacl_info: nacl_ids: - "{{ nacl.nacl_id }}" register: nacl_info - - name: verify no change - assert: + - name: Verify no change + ansible.builtin.assert: that: - nacl is not changed - nacl.nacl_id == nacl_id @@ -315,8 +322,8 @@ # ============================================================ - - name: (check) No change to tags without setting tags - ec2_vpc_nacl: + - name: No change to tags without setting tags (check mode) + community.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" name: "{{ nacl_name }}" subnets: "{{ subnet_ids }}" @@ -324,27 +331,28 @@ register: nacl check_mode: True - - name: assert would change - assert: + - name: Assert would change + ansible.builtin.assert: that: - nacl is not changed - nacl.nacl_id == nacl_id - name: No change to tags without setting tags - ec2_vpc_nacl: + community.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" name: "{{ nacl_name }}" subnets: "{{ subnet_ids }}" state: 'present' register: nacl - - name: get network ACL facts - ec2_vpc_nacl_info: + + - name: Get network ACL facts + community.aws.ec2_vpc_nacl_info: nacl_ids: - "{{ nacl.nacl_id }}" register: nacl_info - - name: verify the tags were added - assert: + - name: Verify the tags were added + ansible.builtin.assert: that: - nacl is not changed - nacl.nacl_id == nacl_id @@ -353,8 +361,8 @@ # ============================================================ - - name: (check) remove non name tags - ec2_vpc_nacl: + - name: Remove non name tags (check mode) + community.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" name: "{{ nacl_name }}" subnets: "{{ subnet_ids }}" @@ -363,36 +371,37 @@ register: nacl check_mode: True - - name: assert would change - assert: + - name: Assert would change + ansible.builtin.assert: that: - nacl is changed - nacl.nacl_id == nacl_id - - name: remove non name tags - ec2_vpc_nacl: + - name: Remove non name tags + community.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" name: "{{ nacl_name }}" subnets: "{{ subnet_ids }}" tags: {} state: 'present' register: nacl - - name: get network ACL facts - ec2_vpc_nacl_info: + + - name: Get network ACL facts + community.aws.ec2_vpc_nacl_info: nacl_ids: - "{{ nacl.nacl_id }}" register: nacl_info - - name: verify the tags were added - assert: + - name: Verify the tags were added + ansible.builtin.assert: that: - nacl is changed - nacl.nacl_id == nacl_id - nacl_info.nacls[0].nacl_id == nacl_id - nacl_info.nacls[0].tags == name_tags - - name: (check) remove non name tags - IDEMPOTENCY - ec2_vpc_nacl: + - name: Remove non name tags - IDEMPOTENCY (check mode) + community.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" name: "{{ nacl_name }}" subnets: "{{ subnet_ids }}" @@ -401,28 +410,29 @@ register: nacl check_mode: True - - name: assert would not change - assert: + - name: Assert would not change + ansible.builtin.assert: that: - nacl is not changed - nacl.nacl_id == nacl_id - - name: remove non name tags - IDEMPOTENCY - ec2_vpc_nacl: + - name: Remove non name tags - IDEMPOTENCY + community.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" name: "{{ nacl_name }}" subnets: "{{ subnet_ids }}" tags: {} state: 'present' register: nacl - - name: get network ACL facts - ec2_vpc_nacl_info: + + - name: Get network ACL facts + community.aws.ec2_vpc_nacl_info: nacl_ids: - "{{ nacl.nacl_id }}" register: nacl_info - - name: verify no change - assert: + - name: Verify no change + ansible.builtin.assert: that: - nacl is not changed - nacl.nacl_id == nacl_id @@ -432,14 +442,14 @@ # ============================================================ always: - - name: remove the network ACL - ec2_vpc_nacl: + - name: Remove the network ACL + community.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" name: "{{ nacl_name }}" state: absent register: nacl - - name: assert nacl was removed - assert: + - name: Assert nacl was removed + ansible.builtin.assert: that: - nacl.changed From fe4eab6dd7ce82f48a7c392648cbdba95cae85e1 Mon Sep 17 00:00:00 2001 From: abikouo Date: Tue, 15 Oct 2024 16:14:32 +0200 Subject: [PATCH 31/34] update meta/runtime.yml, modules and tests --- meta/runtime.yml | 12 ++-- plugins/modules/ec2_vpc_nacl.py | 13 ++-- plugins/modules/ec2_vpc_nacl_info.py | 7 ++- .../ec2_vpc_nacl/tasks/ingress_and_egress.yml | 18 +++--- .../targets/ec2_vpc_nacl/tasks/ipv6.yml | 14 ++--- .../targets/ec2_vpc_nacl/tasks/main.yml | 8 +-- .../targets/ec2_vpc_nacl/tasks/subnet_ids.yml | 18 +++--- .../ec2_vpc_nacl/tasks/subnet_names.yml | 14 ++--- .../targets/ec2_vpc_nacl/tasks/tags.yml | 62 +++++++++---------- 9 files changed, 85 insertions(+), 81 deletions(-) diff --git a/meta/runtime.yml b/meta/runtime.yml index b62a89aae8d..af73d43dd52 100644 --- a/meta/runtime.yml +++ b/meta/runtime.yml @@ -62,6 +62,8 @@ action_groups: - ec2_vpc_endpoint_service_info - ec2_vpc_igw - ec2_vpc_igw_info + - ec2_vpc_nacl + - ec2_vpc_nacl_info - ec2_vpc_nat_gateway - ec2_vpc_nat_gateway_info - ec2_vpc_net @@ -164,14 +166,14 @@ plugin_routing: rds_param_group: redirect: amazon.aws.rds_instance_param_group deprecation: - removal_version: 10.0.0 - warning_text: >- - rds_param_group has been renamed to rds_instance_param_group. - Please update your tasks. + removal_version: 10.0.0 + warning_text: >- + rds_param_group has been renamed to rds_instance_param_group. + Please update your tasks. lookup: aws_ssm: # Deprecation for this alias should not *start* prior to 2024-09-01 redirect: amazon.aws.ssm_parameter aws_secret: # Deprecation for this alias should not *start* prior to 2024-09-01 - redirect: amazon.aws.secretsmanager_secret + redirect: amazon.aws.secretsmanager_secret \ No newline at end of file diff --git a/plugins/modules/ec2_vpc_nacl.py b/plugins/modules/ec2_vpc_nacl.py index bc92003d17c..0539d7bda05 100644 --- a/plugins/modules/ec2_vpc_nacl.py +++ b/plugins/modules/ec2_vpc_nacl.py @@ -8,6 +8,7 @@ module: ec2_vpc_nacl short_description: create and delete Network ACLs version_added: 1.0.0 +version_added_collection: community.aws description: - Read the AWS documentation for Network ACLS U(https://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_ACLs.html) @@ -88,7 +89,7 @@ # Complete example to create and delete a network ACL # that allows SSH, HTTP and ICMP in, and all traffic out. - name: "Create and associate production DMZ network ACL with DMZ subnets" - community.aws.ec2_vpc_nacl: + amazon.aws.ec2_vpc_nacl: vpc_id: vpc-12345678 name: prod-dmz-nacl region: ap-southeast-2 @@ -111,7 +112,7 @@ state: 'present' - name: "Remove the ingress and egress rules - defaults to deny all" - community.aws.ec2_vpc_nacl: + amazon.aws.ec2_vpc_nacl: vpc_id: vpc-12345678 name: prod-dmz-nacl region: ap-southeast-2 @@ -125,20 +126,20 @@ state: present - name: "Remove the NACL subnet associations and tags" - community.aws.ec2_vpc_nacl: + amazon.aws.ec2_vpc_nacl: vpc_id: 'vpc-12345678' name: prod-dmz-nacl region: ap-southeast-2 state: present - name: "Delete nacl and subnet associations" - community.aws.ec2_vpc_nacl: + amazon.aws.ec2_vpc_nacl: vpc_id: vpc-12345678 name: prod-dmz-nacl state: absent - name: "Delete nacl by its id" - community.aws.ec2_vpc_nacl: + amazon.aws.ec2_vpc_nacl: nacl_id: acl-33b4ee5b state: absent """ @@ -166,7 +167,7 @@ from ansible_collections.amazon.aws.plugins.module_utils.ec2 import ensure_ec2_tags from ansible_collections.amazon.aws.plugins.module_utils.ec2 import replace_network_acl_association -from ansible_collections.community.aws.plugins.module_utils.modules import AnsibleCommunityAWSModule as AnsibleAWSModule +from ansible_collections.amazon.aws.plugins.module_utils.modules import AnsibleAWSModule # VPC-supported IANA protocol numbers # http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml diff --git a/plugins/modules/ec2_vpc_nacl_info.py b/plugins/modules/ec2_vpc_nacl_info.py index 9e0bc4e7f05..143076b2e17 100644 --- a/plugins/modules/ec2_vpc_nacl_info.py +++ b/plugins/modules/ec2_vpc_nacl_info.py @@ -8,6 +8,7 @@ --- module: ec2_vpc_nacl_info version_added: 1.0.0 +version_added_collection: community.aws short_description: Gather information about Network ACLs in an AWS VPC description: - Gather information about Network ACLs in an AWS VPC @@ -44,13 +45,13 @@ # Gather information about all Network ACLs: - name: Get All NACLs - community.aws.ec2_vpc_nacl_info: + amazon.aws.ec2_vpc_nacl_info: region: us-west-2 register: all_nacls # Retrieve default Network ACLs: - name: Get Default NACLs - community.aws.ec2_vpc_nacl_info: + amazon.aws.ec2_vpc_nacl_info: region: us-west-2 filters: 'default': 'true' @@ -114,7 +115,7 @@ from ansible_collections.amazon.aws.plugins.module_utils.tagging import boto3_tag_list_to_ansible_dict from ansible_collections.amazon.aws.plugins.module_utils.transformation import ansible_dict_to_boto3_filter_list -from ansible_collections.community.aws.plugins.module_utils.modules import AnsibleCommunityAWSModule as AnsibleAWSModule +from ansible_collections.amazon.aws.plugins.module_utils.modules import AnsibleAWSModule # VPC-supported IANA protocol numbers # http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml diff --git a/tests/integration/targets/ec2_vpc_nacl/tasks/ingress_and_egress.yml b/tests/integration/targets/ec2_vpc_nacl/tasks/ingress_and_egress.yml index 432aaf3ba99..584a9bcec0f 100644 --- a/tests/integration/targets/ec2_vpc_nacl/tasks/ingress_and_egress.yml +++ b/tests/integration/targets/ec2_vpc_nacl/tasks/ingress_and_egress.yml @@ -2,7 +2,7 @@ - name: Test Ingress and Egress rules block: - name: Create ingress and egress rules using subnet IDs - community.aws.ec2_vpc_nacl: + amazon.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" name: "{{ nacl_name }}" subnets: "{{ subnet_ids }}" @@ -24,7 +24,7 @@ - nacl.nacl_id.startswith('acl-') - name: Get network ACL facts - community.aws.ec2_vpc_nacl_info: + amazon.aws.ec2_vpc_nacl_info: nacl_ids: - "{{ nacl.nacl_id }}" register: nacl_facts @@ -39,7 +39,7 @@ # ============================================================ - name: Remove an ingress rule - community.aws.ec2_vpc_nacl: + amazon.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" name: "{{ nacl_name }}" subnets: "{{ subnet_ids }}" @@ -60,7 +60,7 @@ - nacl.nacl_id.startswith('acl-') - name: Get network ACL facts - community.aws.ec2_vpc_nacl_info: + amazon.aws.ec2_vpc_nacl_info: nacl_ids: - "{{ nacl.nacl_id }}" register: nacl_facts @@ -75,7 +75,7 @@ # ============================================================ - name: Remove the egress rule - community.aws.ec2_vpc_nacl: + amazon.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" name: "{{ nacl_name }}" subnets: "{{ subnet_ids }}" @@ -95,7 +95,7 @@ - nacl.nacl_id.startswith('acl-') - name: Get network ACL facts - community.aws.ec2_vpc_nacl_info: + amazon.aws.ec2_vpc_nacl_info: nacl_ids: - "{{ nacl.nacl_id }}" register: nacl_facts @@ -110,7 +110,7 @@ # ============================================================ - name: Add egress rules - community.aws.ec2_vpc_nacl: + amazon.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" name: "{{ nacl_name }}" subnets: "{{ subnet_ids }}" @@ -132,7 +132,7 @@ - nacl.nacl_id.startswith('acl-') - name: Get network ACL facts - community.aws.ec2_vpc_nacl_info: + amazon.aws.ec2_vpc_nacl_info: nacl_ids: - "{{ nacl.nacl_id }}" register: nacl_facts @@ -147,7 +147,7 @@ # ============================================================ - name: Remove the network ACL - community.aws.ec2_vpc_nacl: + amazon.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" name: "{{ nacl_name }}" state: absent diff --git a/tests/integration/targets/ec2_vpc_nacl/tasks/ipv6.yml b/tests/integration/targets/ec2_vpc_nacl/tasks/ipv6.yml index 2113fb4aa9c..5ac3819723e 100644 --- a/tests/integration/targets/ec2_vpc_nacl/tasks/ipv6.yml +++ b/tests/integration/targets/ec2_vpc_nacl/tasks/ipv6.yml @@ -4,7 +4,7 @@ # ============================================================ - name: Create ingress and egress rules using subnet names - community.aws.ec2_vpc_nacl: + amazon.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_ipv6_id }}" name: "{{ nacl_name }}" subnets: @@ -30,7 +30,7 @@ nacl_id: "{{ nacl.nacl_id }}" - name: Add ipv6 entries - community.aws.ec2_vpc_nacl: + amazon.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_ipv6_id }}" name: "{{ nacl_name }}" subnets: @@ -56,7 +56,7 @@ - nacl.nacl_id == nacl_id - name: Get network ACL facts (test that it works with ipv6 entries) - community.aws.ec2_vpc_nacl_info: + amazon.aws.ec2_vpc_nacl_info: nacl_ids: - "{{ nacl_id }}" register: nacl_facts @@ -69,7 +69,7 @@ - nacl_facts.nacls[0].egress | length == 2 - name: Purge ingress entries - community.aws.ec2_vpc_nacl: + amazon.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_ipv6_id }}" name: "{{ nacl_name }}" subnets: @@ -90,7 +90,7 @@ - nacl.nacl_id == nacl_id - name: Purge egress entries - community.aws.ec2_vpc_nacl: + amazon.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_ipv6_id }}" name: "{{ nacl_name }}" subnets: @@ -108,7 +108,7 @@ - nacl.changed - name: Get network ACL facts (test that removed entries are gone) - community.aws.ec2_vpc_nacl_info: + amazon.aws.ec2_vpc_nacl_info: nacl_ids: - "{{ nacl_id }}" register: nacl_facts @@ -123,7 +123,7 @@ always: - name: Remove network ACL - community.aws.ec2_vpc_nacl: + amazon.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_ipv6_id }}" name: "{{ nacl_name }}" state: absent diff --git a/tests/integration/targets/ec2_vpc_nacl/tasks/main.yml b/tests/integration/targets/ec2_vpc_nacl/tasks/main.yml index 445161ccd82..0225056152b 100644 --- a/tests/integration/targets/ec2_vpc_nacl/tasks/main.yml +++ b/tests/integration/targets/ec2_vpc_nacl/tasks/main.yml @@ -11,7 +11,7 @@ # ============================================================ - name: Test without any parameters - community.aws.ec2_vpc_nacl: + amazon.aws.ec2_vpc_nacl: register: result ignore_errors: true @@ -22,7 +22,7 @@ - "result.msg == 'one of the following is required: name, nacl_id'" - name: Get network ACL info without any parameters - community.aws.ec2_vpc_nacl_info: + amazon.aws.ec2_vpc_nacl_info: register: nacl_facts - name: Assert we don't error @@ -31,7 +31,7 @@ - nacl_facts is succeeded - name: Get network ACL info with invalid ID - community.aws.ec2_vpc_nacl_info: + amazon.aws.ec2_vpc_nacl_info: nacl_ids: - 'acl-000000000000' register: nacl_facts @@ -139,7 +139,7 @@ always: - name: Remove network ACL - community.aws.ec2_vpc_nacl: + amazon.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" name: "{{ nacl_name }}" state: absent diff --git a/tests/integration/targets/ec2_vpc_nacl/tasks/subnet_ids.yml b/tests/integration/targets/ec2_vpc_nacl/tasks/subnet_ids.yml index 3a367e84f89..5aaed181bef 100644 --- a/tests/integration/targets/ec2_vpc_nacl/tasks/subnet_ids.yml +++ b/tests/integration/targets/ec2_vpc_nacl/tasks/subnet_ids.yml @@ -1,7 +1,7 @@ # ============================================================ - name: Create ingress and egress rules using subnet IDs - community.aws.ec2_vpc_nacl: + amazon.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" name: "{{ nacl_name }}" subnets: "{{ subnet_ids }}" @@ -27,7 +27,7 @@ - nacl.nacl_id.startswith('acl-') - name: Get network ACL facts - community.aws.ec2_vpc_nacl_info: + amazon.aws.ec2_vpc_nacl_info: nacl_ids: - "{{ nacl_id }}" register: nacl_facts @@ -46,7 +46,7 @@ # ============================================================ - name: Test idempotence - community.aws.ec2_vpc_nacl: + amazon.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" name: "{{ nacl_name }}" subnets: "{{ subnet_ids }}" @@ -69,7 +69,7 @@ - nacl.nacl_id.startswith('acl-') - name: Get network ACL facts - community.aws.ec2_vpc_nacl_info: + amazon.aws.ec2_vpc_nacl_info: nacl_ids: - "{{ nacl.nacl_id }}" register: nacl_facts_idem @@ -82,7 +82,7 @@ # ============================================================ - name: Remove a subnet from the network ACL - community.aws.ec2_vpc_nacl: + amazon.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" name: "{{ nacl_name }}" subnets: @@ -108,7 +108,7 @@ - nacl.nacl_id == nacl_id - name: Get network ACL facts - community.aws.ec2_vpc_nacl_info: + amazon.aws.ec2_vpc_nacl_info: nacl_id: - "{{ nacl.nacl_id }}" register: nacl_facts @@ -127,7 +127,7 @@ # ============================================================ - name: Remove the network ACL - community.aws.ec2_vpc_nacl: + amazon.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" name: "{{ nacl_name }}" state: absent @@ -139,7 +139,7 @@ - nacl.changed - name: Re-remove the network ACL by name (test idempotency) - community.aws.ec2_vpc_nacl: + amazon.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" name: "{{ nacl_name }}" state: absent @@ -151,7 +151,7 @@ - nacl is not changed - name: Re-remove the network ACL by id (test idempotency) - community.aws.ec2_vpc_nacl: + amazon.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" nacl_id: "{{ nacl_id }}" state: absent diff --git a/tests/integration/targets/ec2_vpc_nacl/tasks/subnet_names.yml b/tests/integration/targets/ec2_vpc_nacl/tasks/subnet_names.yml index dc44fef804a..78831afface 100644 --- a/tests/integration/targets/ec2_vpc_nacl/tasks/subnet_names.yml +++ b/tests/integration/targets/ec2_vpc_nacl/tasks/subnet_names.yml @@ -1,7 +1,7 @@ # ============================================================ - name: Create ingress and egress rules using subnet names - community.aws.ec2_vpc_nacl: + amazon.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" name: "{{ nacl_name }}" subnets: "{{ subnet_names }}" @@ -27,7 +27,7 @@ - nacl.nacl_id.startswith('acl-') - name: Get network ACL facts - community.aws.ec2_vpc_nacl_info: + amazon.aws.ec2_vpc_nacl_info: nacl_ids: - "{{ nacl_id }}" register: nacl_facts @@ -45,7 +45,7 @@ # ============================================================ - name: Test idempotence - community.aws.ec2_vpc_nacl: + amazon.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" name: "{{ nacl_name }}" subnets: "{{ subnet_names }}" @@ -68,7 +68,7 @@ - nacl.nacl_id.startswith('acl-') - name: Get network ACL facts - community.aws.ec2_vpc_nacl_info: + amazon.aws.ec2_vpc_nacl_info: nacl_ids: - "{{ nacl.nacl_id }}" register: nacl_facts_idem @@ -81,7 +81,7 @@ # ============================================================ - name: Remove a subnet from the network ACL - community.aws.ec2_vpc_nacl: + amazon.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" name: "{{ nacl_name }}" subnets: @@ -107,7 +107,7 @@ - nacl.nacl_id.startswith('acl-') - name: Get network ACL facts - community.aws.ec2_vpc_nacl_info: + amazon.aws.ec2_vpc_nacl_info: nacl_ids: - "{{ nacl.nacl_id }}" register: nacl_facts @@ -125,7 +125,7 @@ # ============================================================ - name: Remove the network ACL - community.aws.ec2_vpc_nacl: + amazon.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" name: "{{ nacl_name }}" state: absent diff --git a/tests/integration/targets/ec2_vpc_nacl/tasks/tags.yml b/tests/integration/targets/ec2_vpc_nacl/tasks/tags.yml index 0e69ce760ac..556ab45494a 100644 --- a/tests/integration/targets/ec2_vpc_nacl/tasks/tags.yml +++ b/tests/integration/targets/ec2_vpc_nacl/tasks/tags.yml @@ -32,7 +32,7 @@ # ============================================================ - name: Create a network ACL using subnet IDs - community.aws.ec2_vpc_nacl: + amazon.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" name: "{{ nacl_name }}" subnets: "{{ subnet_ids }}" @@ -50,7 +50,7 @@ nacl_id: '{{ nacl.nacl_id }}' - name: Get network ACL facts - community.aws.ec2_vpc_nacl_info: + amazon.aws.ec2_vpc_nacl_info: nacl_ids: - "{{ nacl_id }}" register: nacl_info @@ -64,7 +64,7 @@ # ============================================================ - name: Add tags (check mode) - community.aws.ec2_vpc_nacl: + amazon.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" name: "{{ nacl_name }}" subnets: "{{ subnet_ids }}" @@ -80,7 +80,7 @@ - nacl.nacl_id == nacl_id - name: Add tags - community.aws.ec2_vpc_nacl: + amazon.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" name: "{{ nacl_name }}" subnets: "{{ subnet_ids }}" @@ -89,7 +89,7 @@ register: nacl - name: Get network ACL facts - community.aws.ec2_vpc_nacl_info: + amazon.aws.ec2_vpc_nacl_info: nacl_ids: - "{{ nacl.nacl_id }}" register: nacl_info @@ -103,7 +103,7 @@ - nacl_info.nacls[0].tags == ( first_tags | combine(name_tags) ) - name: Add tags - IDEMPOTENCY (check mode) - community.aws.ec2_vpc_nacl: + amazon.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" name: "{{ nacl_name }}" subnets: "{{ subnet_ids }}" @@ -119,7 +119,7 @@ - nacl.nacl_id == nacl_id - name: Add tags - IDEMPOTENCY - community.aws.ec2_vpc_nacl: + amazon.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" name: "{{ nacl_name }}" subnets: "{{ subnet_ids }}" @@ -128,7 +128,7 @@ register: nacl - name: Get network ACL facts - community.aws.ec2_vpc_nacl_info: + amazon.aws.ec2_vpc_nacl_info: nacl_ids: - "{{ nacl.nacl_id }}" register: nacl_info @@ -144,7 +144,7 @@ # ============================================================ - name: Get network ACL facts by filter - community.aws.ec2_vpc_nacl_info: + amazon.aws.ec2_vpc_nacl_info: filters: "tag:Name": "{{ nacl_name }}" register: nacl_info @@ -159,7 +159,7 @@ # ============================================================ - name: Modify tags with purge (check mode) - community.aws.ec2_vpc_nacl: + amazon.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" name: "{{ nacl_name }}" subnets: "{{ subnet_ids }}" @@ -175,7 +175,7 @@ - nacl.nacl_id == nacl_id - name: Modify tags with purge - community.aws.ec2_vpc_nacl: + amazon.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" name: "{{ nacl_name }}" subnets: "{{ subnet_ids }}" @@ -184,7 +184,7 @@ register: nacl - name: Get network ACL facts - community.aws.ec2_vpc_nacl_info: + amazon.aws.ec2_vpc_nacl_info: nacl_ids: - "{{ nacl.nacl_id }}" register: nacl_info @@ -198,7 +198,7 @@ - nacl_info.nacls[0].tags == ( second_tags | combine(name_tags) ) - name: Modify tags with purge - IDEMPOTENCY (check mode) - community.aws.ec2_vpc_nacl: + amazon.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" name: "{{ nacl_name }}" subnets: "{{ subnet_ids }}" @@ -214,7 +214,7 @@ - nacl.nacl_id == nacl_id - name: Modify tags with purge - IDEMPOTENCY - community.aws.ec2_vpc_nacl: + amazon.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" name: "{{ nacl_name }}" subnets: "{{ subnet_ids }}" @@ -223,7 +223,7 @@ register: nacl - name: Get network ACL facts - community.aws.ec2_vpc_nacl_info: + amazon.aws.ec2_vpc_nacl_info: nacl_ids: - "{{ nacl.nacl_id }}" register: nacl_info @@ -239,7 +239,7 @@ # ============================================================ - name: Modify tags without purge (check mode) - community.aws.ec2_vpc_nacl: + amazon.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" name: "{{ nacl_name }}" subnets: "{{ subnet_ids }}" @@ -256,7 +256,7 @@ - nacl.nacl_id == nacl_id - name: Modify tags without purge - community.aws.ec2_vpc_nacl: + amazon.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" name: "{{ nacl_name }}" subnets: "{{ subnet_ids }}" @@ -266,7 +266,7 @@ register: nacl - name: Get network ACL facts - community.aws.ec2_vpc_nacl_info: + amazon.aws.ec2_vpc_nacl_info: nacl_ids: - "{{ nacl.nacl_id }}" register: nacl_info @@ -280,7 +280,7 @@ - nacl_info.nacls[0].tags == ( final_tags | combine(name_tags) ) - name: Modify tags without purge - IDEMPOTENCY (check mode) - community.aws.ec2_vpc_nacl: + amazon.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" name: "{{ nacl_name }}" subnets: "{{ subnet_ids }}" @@ -297,7 +297,7 @@ - nacl.nacl_id == nacl_id - name: Modify tags without purge - IDEMPOTENCY - community.aws.ec2_vpc_nacl: + amazon.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" name: "{{ nacl_name }}" subnets: "{{ subnet_ids }}" @@ -307,7 +307,7 @@ register: nacl - name: Get network ACL facts - community.aws.ec2_vpc_nacl_info: + amazon.aws.ec2_vpc_nacl_info: nacl_ids: - "{{ nacl.nacl_id }}" register: nacl_info @@ -323,7 +323,7 @@ # ============================================================ - name: No change to tags without setting tags (check mode) - community.aws.ec2_vpc_nacl: + amazon.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" name: "{{ nacl_name }}" subnets: "{{ subnet_ids }}" @@ -338,7 +338,7 @@ - nacl.nacl_id == nacl_id - name: No change to tags without setting tags - community.aws.ec2_vpc_nacl: + amazon.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" name: "{{ nacl_name }}" subnets: "{{ subnet_ids }}" @@ -346,7 +346,7 @@ register: nacl - name: Get network ACL facts - community.aws.ec2_vpc_nacl_info: + amazon.aws.ec2_vpc_nacl_info: nacl_ids: - "{{ nacl.nacl_id }}" register: nacl_info @@ -362,7 +362,7 @@ # ============================================================ - name: Remove non name tags (check mode) - community.aws.ec2_vpc_nacl: + amazon.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" name: "{{ nacl_name }}" subnets: "{{ subnet_ids }}" @@ -378,7 +378,7 @@ - nacl.nacl_id == nacl_id - name: Remove non name tags - community.aws.ec2_vpc_nacl: + amazon.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" name: "{{ nacl_name }}" subnets: "{{ subnet_ids }}" @@ -387,7 +387,7 @@ register: nacl - name: Get network ACL facts - community.aws.ec2_vpc_nacl_info: + amazon.aws.ec2_vpc_nacl_info: nacl_ids: - "{{ nacl.nacl_id }}" register: nacl_info @@ -401,7 +401,7 @@ - nacl_info.nacls[0].tags == name_tags - name: Remove non name tags - IDEMPOTENCY (check mode) - community.aws.ec2_vpc_nacl: + amazon.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" name: "{{ nacl_name }}" subnets: "{{ subnet_ids }}" @@ -417,7 +417,7 @@ - nacl.nacl_id == nacl_id - name: Remove non name tags - IDEMPOTENCY - community.aws.ec2_vpc_nacl: + amazon.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" name: "{{ nacl_name }}" subnets: "{{ subnet_ids }}" @@ -426,7 +426,7 @@ register: nacl - name: Get network ACL facts - community.aws.ec2_vpc_nacl_info: + amazon.aws.ec2_vpc_nacl_info: nacl_ids: - "{{ nacl.nacl_id }}" register: nacl_info @@ -443,7 +443,7 @@ always: - name: Remove the network ACL - community.aws.ec2_vpc_nacl: + amazon.aws.ec2_vpc_nacl: vpc_id: "{{ vpc_id }}" name: "{{ nacl_name }}" state: absent From 88363d1f2ecfec9cce073b4d1231c58314a7f25d Mon Sep 17 00:00:00 2001 From: abikouo Date: Tue, 15 Oct 2024 16:14:38 +0200 Subject: [PATCH 32/34] add changelog file --- .../fragments/migrate_ec2_vpc_nacl_ec2_vpc_nacl_info.yaml | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 changelogs/fragments/migrate_ec2_vpc_nacl_ec2_vpc_nacl_info.yaml diff --git a/changelogs/fragments/migrate_ec2_vpc_nacl_ec2_vpc_nacl_info.yaml b/changelogs/fragments/migrate_ec2_vpc_nacl_ec2_vpc_nacl_info.yaml new file mode 100644 index 00000000000..e6259b3f59c --- /dev/null +++ b/changelogs/fragments/migrate_ec2_vpc_nacl_ec2_vpc_nacl_info.yaml @@ -0,0 +1,8 @@ +--- +major_changes: + - ec2_vpc_nacl - The module has been migrated from the ``community.aws`` collection. + Playbooks using the Fully Qualified Collection Name for this module should be + updated to use ``amazon.aws.ec2_vpc_nacl`` (https://github.com/ansible-collections/amazon.aws/pull/2339). + - ec2_vpc_nacl_info - The module has been migrated from the ``community.aws`` collection. + Playbooks using the Fully Qualified Collection Name for this module should be + updated to use ``amazon.aws.ec2_vpc_nacl_info`` (https://github.com/ansible-collections/amazon.aws/pull/2339). From 5e4a6f98db20f67a1e1783a6d0bc26bb97043b46 Mon Sep 17 00:00:00 2001 From: Figrol <37486360+Figrol@users.noreply.github.com> Date: Wed, 16 Oct 2024 15:06:36 +0100 Subject: [PATCH 33/34] Corrected spelling of word (#2306) Corrected spelling of the word to SUMMARY Small spelling mistake the current word of "ton" does not make sense and assume it should be "to". ISSUE TYPE Docs Pull Request COMPONENT NAME Doc spelling correction ADDITIONAL INFORMATION Reviewed-by: Alina Buzachis Reviewed-by: Bikouo Aubin --- plugins/modules/ec2_instance.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/modules/ec2_instance.py b/plugins/modules/ec2_instance.py index 639ee189fdc..95269c43401 100644 --- a/plugins/modules/ec2_instance.py +++ b/plugins/modules/ec2_instance.py @@ -82,7 +82,7 @@ callback (Linux only). - For Windows instances, to enable remote access via Ansible set O(aap_callback.windows) to V(true), and optionally set an admin password. - - If using O(aap_callback.windows) and O(aap_callback.set_password), callback ton Ansible Automation Platform will not + - If using O(aap_callback.windows) and O(aap_callback.set_password), callback to Ansible Automation Platform will not be performed but the instance will be ready to receive winrm connections from Ansible. - Mutually exclusive with O(user_data). type: dict From fc3e13b76f260b85fc9de93f2869a475f0057946 Mon Sep 17 00:00:00 2001 From: abikouo Date: Wed, 16 Oct 2024 12:13:00 +0200 Subject: [PATCH 34/34] Fix isort issue --- plugins/modules/ec2_vpc_nacl.py | 7 +++---- plugins/modules/ec2_vpc_nacl_info.py | 13 ++++++------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/plugins/modules/ec2_vpc_nacl.py b/plugins/modules/ec2_vpc_nacl.py index 0539d7bda05..7abe96d301f 100644 --- a/plugins/modules/ec2_vpc_nacl.py +++ b/plugins/modules/ec2_vpc_nacl.py @@ -11,7 +11,7 @@ version_added_collection: community.aws description: - Read the AWS documentation for Network ACLS - U(https://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_ACLs.html) + U(https://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_ACLs.html). options: name: description: @@ -68,8 +68,8 @@ elements: list state: description: - - Creates or modifies an existing NACL - - Deletes a NACL and reassociates subnets to the default NACL + - Creates or modifies an existing NACL. + - Deletes a NACL and reassociates subnets to the default NACL. required: false type: str choices: ['present', 'absent'] @@ -166,7 +166,6 @@ from ansible_collections.amazon.aws.plugins.module_utils.ec2 import describe_subnets from ansible_collections.amazon.aws.plugins.module_utils.ec2 import ensure_ec2_tags from ansible_collections.amazon.aws.plugins.module_utils.ec2 import replace_network_acl_association - from ansible_collections.amazon.aws.plugins.module_utils.modules import AnsibleAWSModule # VPC-supported IANA protocol numbers diff --git a/plugins/modules/ec2_vpc_nacl_info.py b/plugins/modules/ec2_vpc_nacl_info.py index 143076b2e17..88bef9360d0 100644 --- a/plugins/modules/ec2_vpc_nacl_info.py +++ b/plugins/modules/ec2_vpc_nacl_info.py @@ -11,7 +11,7 @@ version_added_collection: community.aws short_description: Gather information about Network ACLs in an AWS VPC description: - - Gather information about Network ACLs in an AWS VPC + - Gather information about Network ACLs in an AWS VPC. author: - "Brad Davidson (@brandond)" options: @@ -87,16 +87,16 @@ elements: str ingress: description: - - A list of NACL ingress rules with the following format. - - "C([rule no, protocol, allow/deny, v4 or v6 cidr, icmp_type, icmp_code, port from, port to])" + - A list of NACL ingress rules. + - The rule format is C([rule no, protocol, allow/deny, v4 or v6 cidr, icmp_type, icmp_code, port from, port to]). returned: always type: list elements: list sample: [[100, 'tcp', 'allow', '0.0.0.0/0', null, null, 22, 22]] egress: description: - - A list of NACL egress rules with the following format. - - "C([rule no, protocol, allow/deny, v4 or v6 cidr, icmp_type, icmp_code, port from, port to])" + - A list of NACL egress rules. + - The rule format is C([rule no, protocol, allow/deny, v4 or v6 cidr, icmp_type, icmp_code, port from, port to]). returned: always type: list elements: list @@ -112,11 +112,10 @@ from ansible_collections.amazon.aws.plugins.module_utils.ec2 import AnsibleEC2Error from ansible_collections.amazon.aws.plugins.module_utils.ec2 import describe_network_acls +from ansible_collections.amazon.aws.plugins.module_utils.modules import AnsibleAWSModule from ansible_collections.amazon.aws.plugins.module_utils.tagging import boto3_tag_list_to_ansible_dict from ansible_collections.amazon.aws.plugins.module_utils.transformation import ansible_dict_to_boto3_filter_list -from ansible_collections.amazon.aws.plugins.module_utils.modules import AnsibleAWSModule - # VPC-supported IANA protocol numbers # http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml PROTOCOL_NAMES = {"-1": "all", "1": "icmp", "6": "tcp", "17": "udp"}