From 6e3e99c4e55266ab71f6258d72ac0b1b09df5a92 Mon Sep 17 00:00:00 2001 From: Bikouo Aubin <79859644+abikouo@users.noreply.github.com> Date: Fri, 25 Oct 2024 12:47:14 +0200 Subject: [PATCH] DNM - Migrate modules ec2_vpc_nacl,ec2_vpc_nacl_info and tests (#2178) Depends-On: ansible-collections/amazon.aws#2339 Remove ec2_vpc_nacl,ec2_vpc_nacl_info modules and tests, these modules have been migrated to amazon.aws collection. Update runtime.yml with redirects to that collection Update ignore files Reviewed-by: GomathiselviS Reviewed-by: Mandar Kulkarni --- ...igrate_ec2_vpc_nacl_ec2_vpc_nacl_info.yaml | 8 + meta/runtime.yml | 6 +- plugins/modules/ec2_vpc_nacl.py | 536 ------------------ plugins/modules/ec2_vpc_nacl_info.py | 231 -------- .../integration/targets/ec2_vpc_nacl/aliases | 3 - .../targets/ec2_vpc_nacl/defaults/main.yml | 12 - .../targets/ec2_vpc_nacl/meta/main.yml | 1 - .../ec2_vpc_nacl/tasks/ingress_and_egress.yml | 159 ------ .../targets/ec2_vpc_nacl/tasks/ipv6.yml | 131 ----- .../targets/ec2_vpc_nacl/tasks/main.yml | 174 ------ .../targets/ec2_vpc_nacl/tasks/subnet_ids.yml | 163 ------ .../ec2_vpc_nacl/tasks/subnet_names.yml | 137 ----- .../targets/ec2_vpc_nacl/tasks/tags.yml | 455 --------------- 13 files changed, 12 insertions(+), 2004 deletions(-) create mode 100644 changelogs/fragments/migrate_ec2_vpc_nacl_ec2_vpc_nacl_info.yaml delete mode 100644 plugins/modules/ec2_vpc_nacl.py delete mode 100644 plugins/modules/ec2_vpc_nacl_info.py delete mode 100644 tests/integration/targets/ec2_vpc_nacl/aliases delete mode 100644 tests/integration/targets/ec2_vpc_nacl/defaults/main.yml delete mode 100644 tests/integration/targets/ec2_vpc_nacl/meta/main.yml delete mode 100644 tests/integration/targets/ec2_vpc_nacl/tasks/ingress_and_egress.yml delete mode 100644 tests/integration/targets/ec2_vpc_nacl/tasks/ipv6.yml delete mode 100644 tests/integration/targets/ec2_vpc_nacl/tasks/main.yml delete mode 100644 tests/integration/targets/ec2_vpc_nacl/tasks/subnet_ids.yml delete mode 100644 tests/integration/targets/ec2_vpc_nacl/tasks/subnet_names.yml delete mode 100644 tests/integration/targets/ec2_vpc_nacl/tasks/tags.yml 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..15a0f626e45 --- /dev/null +++ b/changelogs/fragments/migrate_ec2_vpc_nacl_ec2_vpc_nacl_info.yaml @@ -0,0 +1,8 @@ +--- +breaking_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/community.aws/pull/2178). + - 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/community.aws/pull/2178). diff --git a/meta/runtime.yml b/meta/runtime.yml index 662ded07df1..7340441a8f9 100644 --- a/meta/runtime.yml +++ b/meta/runtime.yml @@ -114,8 +114,6 @@ action_groups: - ec2_transit_gateway_info - ec2_transit_gateway_vpc_attachment - ec2_transit_gateway_vpc_attachment_info - - ec2_vpc_nacl - - ec2_vpc_nacl_info - ec2_vpc_peer - ec2_vpc_peering_info - ec2_vpc_vgw @@ -526,6 +524,10 @@ plugin_routing: redirect: amazon.aws.ec2_transit_gateway_vpc_attachment_info elb_classic_lb_info: redirect: amazon.aws.elb_classic_lb_info + ec2_vpc_nacl: + redirect: amazon.aws.ec2_vpc_nacl + ec2_vpc_nacl_info: + redirect: amazon.aws.ec2_vpc_nacl_info module_utils: route53: redirect: amazon.aws.route53 diff --git a/plugins/modules/ec2_vpc_nacl.py b/plugins/modules/ec2_vpc_nacl.py deleted file mode 100644 index bc92003d17c..00000000000 --- a/plugins/modules/ec2_vpc_nacl.py +++ /dev/null @@ -1,536 +0,0 @@ -#!/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) - -DOCUMENTATION = r""" -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) -options: - name: - description: - - Tagged name identifying a network ACL. - - 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 O(name) or O(nacl_id) is required. - - Mutually exclusive with O(name). - 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 - elements: str - default: [] - 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', '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. - default: [] - required: false - type: list - elements: 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', '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. - default: [] - required: false - type: list - elements: list - 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) -notes: - - Support for I(purge_tags) was added in release 4.0.0. -extends_documentation_fragment: - - amazon.aws.common.modules - - amazon.aws.region.modules - - amazon.aws.boto3 - - amazon.aws.tags -""" - -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" - community.aws.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] - - [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" - community.aws.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" - 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" - community.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: - nacl_id: acl-33b4ee5b - state: absent -""" - -RETURN = r""" -nacl_id: - description: The id of the NACL (when creating or updating an ACL). - returned: success - type: str - sample: "acl-123456789abcdef01" -""" - -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.ec2 import replace_network_acl_association - -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} - - -# Utility methods -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_changed(client, module: AnsibleAWSModule, nacl_id: str, subnets_ids: List[str]) -> bool: - changed = False - vpc_id = module.params.get("vpc_id") - - 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 - - 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(client, module: AnsibleAWSModule, nacl_info: Dict[str, Any]) -> bool: - changed = False - 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(client, module: AnsibleAWSModule, nacl_id: str) -> bool: - 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: - # 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 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 - 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: str) -> bool: - return ":" in cidr - - -def process_rule_entry(entry: List[Any]) -> Dict[str, Any]: - params = {} - 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: - if entry[6] or entry[7]: - params["PortRange"] = {"From": entry[6], "To": entry[7]} - - return params - - -def add_network_acl_entries( - client, nacl_id: str, ansible_entries: List[List[str]], egress: bool, check_mode: bool -) -> bool: - changed = False - for entry in ansible_entries: - changed = True - 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 associate_nacl_to_subnets(client, module: AnsibleAWSModule, nacl_id: str, subnets_ids: List[str]) -> bool: - changed = False - 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 - if not module.check_mode: - replace_network_acl_association(client, network_acl_id=nacl_id, association_id=association_id) - return changed - - -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) - - if not nacl: - if module.check_mode: - module.exit_json(changed=True, msg="Would have created Network ACL if not in check mode.") - - # 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) - - # 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 ensure_absent(client, module: AnsibleAWSModule) -> None: - changed = False - result = {} - nacl = describe_network_acl(client, module) - if not nacl: - module.exit_json(changed=changed) - - 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") - - # Replace Network ACL association - for assoc_id in assoc_ids: - changed = True - if not module.check_mode: - 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.") - - 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: AnsibleAWSModule) -> Optional[Dict[str, Any]]: - nacl_id = module.params.get("nacl_id") - name = module.params.get("name") - - if nacl_id: - filters = [{"Name": "network-acl-id", "Values": [nacl_id]}] - else: - 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 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 find_subnets_ids(client, module: AnsibleAWSModule, subnets_ids_or_names: List[str]) -> List[str]: - subnets_ids = [] - subnets_names = [] - - # 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"] - - 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(): - argument_spec = dict( - vpc_id=dict(), - name=dict(), - nacl_id=dict(), - 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, - ) - - client = module.client("ec2") - - 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__": - main() diff --git a/plugins/modules/ec2_vpc_nacl_info.py b/plugins/modules/ec2_vpc_nacl_info.py deleted file mode 100644 index 9e0bc4e7f05..00000000000 --- a/plugins/modules/ec2_vpc_nacl_info.py +++ /dev/null @@ -1,231 +0,0 @@ -#!/usr/bin/python -# -*- 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""" ---- -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)" -options: - nacl_ids: - description: - - A list of Network ACL IDs to retrieve information about. - required: false - 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 - 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: - - amazon.aws.common.modules - - amazon.aws.region.modules - - amazon.aws.boto3 -""" - -EXAMPLES = r""" -# Note: These examples do not set authentication details, see the AWS Guide for details. - -# Gather information about all Network ACLs: -- name: Get All NACLs - community.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: - region: us-west-2 - filters: - 'default': 'true' - register: default_nacls -""" - -RETURN = r""" -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]] -""" - -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.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 - -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"} - - -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 = module.params.get("filters") - - params = {} - if filters: - params["Filters"] = ansible_dict_to_boto3_filter_list(filters) - if nacl_ids: - params["NetworkAclIds"] = nacl_ids - - try: - 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 = [] - - 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"], elements="str"), - filters=dict(default={}, type="dict"), - ) - - module = AnsibleAWSModule( - argument_spec=argument_spec, - supports_check_mode=True, - ) - - connection = module.client("ec2") - - 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 deleted file mode 100644 index 04109c2687b..00000000000 --- a/tests/integration/targets/ec2_vpc_nacl/aliases +++ /dev/null @@ -1,3 +0,0 @@ -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 deleted file mode 100644 index 5ac931209fb..00000000000 --- a/tests/integration/targets/ec2_vpc_nacl/defaults/main.yml +++ /dev/null @@ -1,12 +0,0 @@ ---- -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/meta/main.yml b/tests/integration/targets/ec2_vpc_nacl/meta/main.yml deleted file mode 100644 index 32cf5dda7ed..00000000000 --- a/tests/integration/targets/ec2_vpc_nacl/meta/main.yml +++ /dev/null @@ -1 +0,0 @@ -dependencies: [] 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 deleted file mode 100644 index 432aaf3ba99..00000000000 --- a/tests/integration/targets/ec2_vpc_nacl/tasks/ingress_and_egress.yml +++ /dev/null @@ -1,159 +0,0 @@ -# ============================================================ -- 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 }}" - 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 - ansible.builtin.assert: - that: - - nacl.changed - - nacl.nacl_id.startswith('acl-') - - - 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 - ansible.builtin.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 - community.aws.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 - ansible.builtin.assert: - that: - - nacl.changed - - nacl.nacl_id.startswith('acl-') - - - 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 - ansible.builtin.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 - community.aws.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 - ansible.builtin.assert: - that: - - nacl.changed - - nacl.nacl_id.startswith('acl-') - - - 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 - ansible.builtin.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 - community.aws.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 - ansible.builtin.assert: - that: - - nacl.changed - - nacl.nacl_id.startswith('acl-') - - - 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 - ansible.builtin.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 - community.aws.ec2_vpc_nacl: - vpc_id: "{{ vpc_id }}" - name: "{{ nacl_name }}" - state: absent - register: nacl - - - 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 deleted file mode 100644 index 2113fb4aa9c..00000000000 --- a/tests/integration/targets/ec2_vpc_nacl/tasks/ipv6.yml +++ /dev/null @@ -1,131 +0,0 @@ -- name: Test using IPv6 - block: - - # ============================================================ - - - name: Create ingress and egress rules using subnet names - community.aws.ec2_vpc_nacl: - vpc_id: "{{ vpc_ipv6_id }}" - name: "{{ nacl_name }}" - subnets: - - "{{ subnet_name }}-ipv6" - 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 that module returned the Network ACL id - ansible.builtin.assert: - that: - - nacl.nacl_id - - - name: Set fact for Network ACL ID - ansible.builtin.set_fact: - nacl_id: "{{ nacl.nacl_id }}" - - - name: Add ipv6 entries - community.aws.ec2_vpc_nacl: - vpc_id: "{{ vpc_ipv6_id }}" - name: "{{ nacl_name }}" - subnets: - - "{{ subnet_name }}-ipv6" - 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, '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 - - - 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) - community.aws.ec2_vpc_nacl_info: - nacl_ids: - - "{{ nacl_id }}" - register: nacl_facts - - - 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 - community.aws.ec2_vpc_nacl: - vpc_id: "{{ vpc_ipv6_id }}" - name: "{{ nacl_name }}" - subnets: - - "{{ subnet_name }}-ipv6" - 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 - - - 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 - community.aws.ec2_vpc_nacl: - vpc_id: "{{ vpc_ipv6_id }}" - name: "{{ nacl_name }}" - subnets: - - "{{ subnet_name }}-ipv6" - tags: - Created_by: "Ansible test {{ resource_prefix }}" - ingress: [] - egress: [] - state: 'present' - register: nacl - - - name: Assert that module reported change - ansible.builtin.assert: - that: - - nacl.changed - - - 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 - ansible.builtin.assert: - that: - - nacl_facts.nacls | length == 1 - - nacl_facts.nacls[0].ingress | length == 0 - - nacl_facts.nacls[0].egress | length == 0 - - always: - - - name: Remove network ACL - community.aws.ec2_vpc_nacl: - vpc_id: "{{ vpc_ipv6_id }}" - name: "{{ nacl_name }}" - state: absent - register: removed_acl - 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 deleted file mode 100644 index 445161ccd82..00000000000 --- a/tests/integration/targets/ec2_vpc_nacl/tasks/main.yml +++ /dev/null @@ -1,174 +0,0 @@ ---- -- module_defaults: - group/aws: - access_key: "{{ aws_access_key }}" - secret_key: "{{ aws_secret_key }}" - session_token: "{{ security_token | default(omit) }}" - region: "{{ aws_region }}" - - block: - - # ============================================================ - - - name: Test without any parameters - community.aws.ec2_vpc_nacl: - register: result - ignore_errors: true - - - 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 - community.aws.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 - community.aws.ec2_vpc_nacl_info: - nacl_ids: - - 'acl-000000000000' - register: nacl_facts - ignore_errors: true - - - name: Assert message mentions missing ACLs - assert: - that: - - nacl_facts is failed - - '"does not exist" in nacl_facts.msg' - - # ============================================================ - - - name: Fetch AZ availability - amazon.aws.aws_az_info: - register: az_info - - - name: Assert that we have multiple AZs available to us - ansible.builtin.assert: - that: az_info.availability_zones | length >= 2 - - - 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 - amazon.aws.ec2_vpc_net: - cidr_block: "{{ vpc_cidr }}" - name: "{{ vpc_name }}" - state: present - register: vpc - - - name: Save VPC ID for later - ansible.builtin.set_fact: - vpc_id: "{{ vpc.vpc.id }}" - - - name: Create subnets - amazon.aws.ec2_vpc_subnet: - cidr: "{{ item.cidr }}" - az: "{{ item.az }}" - vpc_id: "{{ vpc_id }}" - state: present - tags: - Name: "{{ item.name }}" - with_items: - - cidr: "{{ subnet_1 }}" - az: "{{ az_one }}" - name: "{{ subnet_name }}-1" - - cidr: "{{ subnet_2 }}" - az: "{{ az_two }}" - name: "{{ subnet_name }}-2" - - cidr: "{{ subnet_3 }}" - az: "{{ az_one }}" - name: "{{ subnet_name }}-3" - - cidr: "{{ subnet_4 }}" - az: "{{ az_two }}" - name: "{{ subnet_name }}-4" - register: subnets - - - 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 - amazon.aws.ec2_vpc_net: - cidr_block: "{{ vpc_ipv6_cidr }}" - name: "{{ vpc_ipv6_name }}" - state: present - ipv6_cidr: true - register: vpc_result - - - 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 - amazon.aws.ec2_vpc_subnet: - cidr: "{{ vpc_ipv6_cidr }}" - vpc_id: "{{ vpc_ipv6_id }}" - ipv6_cidr: "{{ subnet_ipv6 }}" - state: present - tags: - Name: "{{ subnet_name }}-ipv6" - - # ============================================================ - - 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 - community.aws.ec2_vpc_nacl: - vpc_id: "{{ vpc_id }}" - name: "{{ nacl_name }}" - state: absent - register: removed_acl - ignore_errors: true - - - name: Remove subnets - amazon.aws.ec2_vpc_subnet: - cidr: "{{ item.cidr }}" - vpc_id: "{{ item.vpc_id | default(vpc_id) }}" - state: absent - with_items: - - cidr: "{{ subnet_1 }}" - - cidr: "{{ subnet_2 }}" - - cidr: "{{ subnet_3 }}" - - cidr: "{{ subnet_4 }}" - - cidr: "{{ vpc_ipv6_cidr }}" - vpc_id: "{{ vpc_ipv6_id }}" - ignore_errors: true - register: removed_subnets - - - name: Remove the VPCs - amazon.aws.ec2_vpc_net: - vpc_id: "{{ item }}" - state: absent - ignore_errors: true - register: removed_vpc - 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 deleted file mode 100644 index 3a367e84f89..00000000000 --- a/tests/integration/targets/ec2_vpc_nacl/tasks/subnet_ids.yml +++ /dev/null @@ -1,163 +0,0 @@ -# ============================================================ - -- name: Create ingress and egress rules using subnet IDs - community.aws.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: Set helpful fact for Network ACL ID - ansible.builtin.set_fact: - nacl_id: "{{ nacl.nacl_id }}" - -- name: Assert the network acl was created - ansible.builtin.assert: - that: - - nacl.changed - - nacl.nacl_id.startswith('acl-') - -- 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 - ansible.builtin.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 == nacl_name - -# ============================================================ - -- name: Test idempotence - community.aws.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 already existed - ansible.builtin.assert: - that: - - not nacl.changed - - nacl.nacl_id == nacl_id - - nacl.nacl_id.startswith('acl-') - -- 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 - ansible.builtin.assert: - that: - - nacl_facts_idem == nacl_facts - -# ============================================================ - -- name: Remove a subnet from the network ACL - community.aws.ec2_vpc_nacl: - vpc_id: "{{ vpc_id }}" - name: "{{ nacl_name }}" - 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 - ansible.builtin.assert: - that: - - nacl.changed - - nacl.nacl_id.startswith('acl-') - - nacl.nacl_id == nacl_id - -- 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 - ansible.builtin.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 == nacl_name - -# ============================================================ - -- 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 - ansible.builtin.assert: - that: - - nacl.changed - -- 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 - ansible.builtin.assert: - that: - - nacl is not changed - -- 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 - 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 deleted file mode 100644 index dc44fef804a..00000000000 --- a/tests/integration/targets/ec2_vpc_nacl/tasks/subnet_names.yml +++ /dev/null @@ -1,137 +0,0 @@ -# ============================================================ - -- name: Create ingress and egress rules using subnet names - community.aws.ec2_vpc_nacl: - vpc_id: "{{ vpc_id }}" - name: "{{ nacl_name }}" - 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: Set helpful fact for Network ACL ID - ansible.builtin.set_fact: - nacl_id: "{{ nacl.nacl_id }}" - -- name: Assert the network acl was created - ansible.builtin.assert: - that: - - nacl.changed - - nacl.nacl_id.startswith('acl-') - -- 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 - ansible.builtin.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 == nacl_name - -# ============================================================ - -- name: Test idempotence - community.aws.ec2_vpc_nacl: - vpc_id: "{{ vpc_id }}" - name: "{{ nacl_name }}" - 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 - ansible.builtin.assert: - that: - - not nacl.changed - - nacl.nacl_id == nacl_id - - nacl.nacl_id.startswith('acl-') - -- 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 - ansible.builtin.assert: - that: - - nacl_facts_idem == nacl_facts - -# ============================================================ - -- name: Remove a subnet from the network ACL - community.aws.ec2_vpc_nacl: - vpc_id: "{{ vpc_id }}" - name: "{{ nacl_name }}" - 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 - ansible.builtin.assert: - that: - - nacl.changed - - nacl.nacl_id == nacl_id - - nacl.nacl_id.startswith('acl-') - -- 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 - ansible.builtin.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 == nacl_name - -# ============================================================ - -- 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 - 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 deleted file mode 100644 index 0e69ce760ac..00000000000 --- a/tests/integration/targets/ec2_vpc_nacl/tasks/tags.yml +++ /dev/null @@ -1,455 +0,0 @@ -- name: Run test from tags.yml - 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 - 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 - ansible.builtin.assert: - that: - - nacl.changed - - nacl.nacl_id.startswith('acl-') - - - name: Store NACL ID - ansible.builtin.set_fact: - nacl_id: '{{ nacl.nacl_id }}' - - - 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 - ansible.builtin.assert: - that: - - nacl_info.nacls[0].nacl_id == nacl_id - - nacl_info.nacls[0].tags == name_tags - - # ============================================================ - - - name: Add tags (check mode) - community.aws.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 - ansible.builtin.assert: - that: - - nacl is changed - - nacl.nacl_id == nacl_id - - - 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 - community.aws.ec2_vpc_nacl_info: - nacl_ids: - - "{{ nacl.nacl_id }}" - register: nacl_info - - - 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: Add tags - IDEMPOTENCY (check mode) - community.aws.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 - ansible.builtin.assert: - that: - - nacl is not changed - - nacl.nacl_id == nacl_id - - - 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 - community.aws.ec2_vpc_nacl_info: - nacl_ids: - - "{{ nacl.nacl_id }}" - register: nacl_info - - - name: Verify no change - ansible.builtin.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 - community.aws.ec2_vpc_nacl_info: - filters: - "tag:Name": "{{ nacl_name }}" - register: nacl_info - - - name: Assert the facts are the same as before - ansible.builtin.assert: - that: - - nacl_info.nacls | length == 1 - - nacl.nacl_id == nacl_id - - nacl_info.nacls[0].nacl_id == nacl_id - - # ============================================================ - - - name: Modify tags with purge (check mode) - community.aws.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 - ansible.builtin.assert: - that: - - nacl is changed - - nacl.nacl_id == nacl_id - - - 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 - community.aws.ec2_vpc_nacl_info: - nacl_ids: - - "{{ nacl.nacl_id }}" - register: nacl_info - - - 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: Modify tags with purge - IDEMPOTENCY (check mode) - community.aws.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 - ansible.builtin.assert: - that: - - nacl is not changed - - nacl.nacl_id == nacl_id - - - 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 - community.aws.ec2_vpc_nacl_info: - nacl_ids: - - "{{ nacl.nacl_id }}" - register: nacl_info - - - name: Verify no change - ansible.builtin.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: Modify tags without purge (check mode) - community.aws.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 - ansible.builtin.assert: - that: - - nacl is changed - - nacl.nacl_id == nacl_id - - - name: Modify tags without purge - community.aws.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 - community.aws.ec2_vpc_nacl_info: - nacl_ids: - - "{{ nacl.nacl_id }}" - register: nacl_info - - - 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: Modify tags without purge - IDEMPOTENCY (check mode) - community.aws.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 - ansible.builtin.assert: - that: - - nacl is not changed - - nacl.nacl_id == nacl_id - - - name: Modify tags without purge - IDEMPOTENCY - community.aws.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 - community.aws.ec2_vpc_nacl_info: - nacl_ids: - - "{{ nacl.nacl_id }}" - register: nacl_info - - - name: Verify no change - ansible.builtin.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: No change to tags without setting tags (check mode) - community.aws.ec2_vpc_nacl: - vpc_id: "{{ vpc_id }}" - name: "{{ nacl_name }}" - subnets: "{{ subnet_ids }}" - state: 'present' - register: nacl - check_mode: True - - - 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 - community.aws.ec2_vpc_nacl: - vpc_id: "{{ vpc_id }}" - name: "{{ nacl_name }}" - subnets: "{{ subnet_ids }}" - state: 'present' - register: nacl - - - 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 - ansible.builtin.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: Remove non name tags (check mode) - community.aws.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 - ansible.builtin.assert: - that: - - nacl is changed - - nacl.nacl_id == nacl_id - - - 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 - community.aws.ec2_vpc_nacl_info: - nacl_ids: - - "{{ nacl.nacl_id }}" - register: nacl_info - - - 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: Remove non name tags - IDEMPOTENCY (check mode) - community.aws.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 - ansible.builtin.assert: - that: - - nacl is not changed - - nacl.nacl_id == nacl_id - - - 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 - community.aws.ec2_vpc_nacl_info: - nacl_ids: - - "{{ nacl.nacl_id }}" - register: nacl_info - - - name: Verify no change - ansible.builtin.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 - community.aws.ec2_vpc_nacl: - vpc_id: "{{ vpc_id }}" - name: "{{ nacl_name }}" - state: absent - register: nacl - - - name: Assert nacl was removed - ansible.builtin.assert: - that: - - nacl.changed