From 6a0194b9c119d7fa0303b3bea83dd7c5a530246c Mon Sep 17 00:00:00 2001 From: Mandar Kulkarni Date: Fri, 15 Oct 2021 13:47:36 -0700 Subject: [PATCH] ec2_eni: Add check_mode support to ec2_eni (#534) ec2_eni: Add check_mode support to ec2_eni SUMMARY Add check_mode support to ec2_eni. ISSUE TYPE Feature Pull Request COMPONENT NAME ec2_eni Reviewed-by: Mark Chappell Reviewed-by: None --- .../534-ec2_eni_add_check_mode_support.yml | 2 + plugins/modules/ec2_eni.py | 168 +++++++++++------- .../ec2_eni/tasks/test_attachment.yaml | 58 ++++++ .../targets/ec2_eni/tasks/test_deletion.yaml | 26 +++ .../tasks/test_eni_basic_creation.yaml | 26 +++ .../ec2_eni/tasks/test_ipaddress_assign.yaml | 58 ++++++ .../test_modifying_delete_on_termination.yaml | 48 +++++ .../test_modifying_source_dest_check.yaml | 24 +++ .../ec2_eni/tasks/test_modifying_tags.yaml | 38 ++++ 9 files changed, 379 insertions(+), 69 deletions(-) create mode 100644 changelogs/fragments/534-ec2_eni_add_check_mode_support.yml diff --git a/changelogs/fragments/534-ec2_eni_add_check_mode_support.yml b/changelogs/fragments/534-ec2_eni_add_check_mode_support.yml new file mode 100644 index 00000000000..c33a9586d88 --- /dev/null +++ b/changelogs/fragments/534-ec2_eni_add_check_mode_support.yml @@ -0,0 +1,2 @@ +minor_changes: +- ec2_eni - add check mode support (https://github.com/ansible-collections/amazon.aws/pull/534). diff --git a/plugins/modules/ec2_eni.py b/plugins/modules/ec2_eni.py index fe7b3981555..87f3ae90aa0 100644 --- a/plugins/modules/ec2_eni.py +++ b/plugins/modules/ec2_eni.py @@ -293,6 +293,8 @@ ''' import time +from ipaddress import ip_address +from ipaddress import ip_network try: import botocore.exceptions @@ -302,6 +304,7 @@ from ..module_utils.core import AnsibleAWSModule from ..module_utils.core import is_boto3_error_code from ..module_utils.ec2 import AWSRetry +from ..module_utils.ec2 import ansible_dict_to_boto3_tag_list from ..module_utils.ec2 import get_ec2_security_group_ids_from_names from ..module_utils.tagging import boto3_tag_list_to_ansible_dict from ..module_utils.tagging import boto3_tag_specifications @@ -441,6 +444,14 @@ def create_eni(connection, vpc_id, module): if tags: args["TagSpecifications"] = boto3_tag_specifications(tags, types='network-interface') + # check if provided private_ip_address is within the subnet's address range + cidr_block = connection.describe_subnets(SubnetIds=[str(subnet_id)])['Subnets'][0]['CidrBlock'] + valid_private_ip = ip_address(private_ip_address) in ip_network(cidr_block) + if not valid_private_ip: + module.fail_json(changed=False, msg="Error: cannot create ENI - Address does not fall within the subnet's address range.") + if module.check_mode: + module.exit_json(changed=True, msg="Would have created ENI if not in check mode.") + eni_dict = connection.create_network_interface(aws_retry=True, **args) eni = eni_dict["NetworkInterface"] # Once we have an ID make sure we're always modifying the same object @@ -521,43 +532,47 @@ def modify_eni(connection, module, eni): try: if description is not None: if "Description" not in eni or eni["Description"] != description: - connection.modify_network_interface_attribute( - aws_retry=True, - NetworkInterfaceId=eni_id, - Description={'Value': description} - ) + if not module.check_mode: + connection.modify_network_interface_attribute( + aws_retry=True, + NetworkInterfaceId=eni_id, + Description={'Value': description} + ) changed = True if len(security_groups) > 0: groups = get_ec2_security_group_ids_from_names(security_groups, connection, vpc_id=eni["VpcId"], boto3=True) if sorted(get_sec_group_list(eni["Groups"])) != sorted(groups): - connection.modify_network_interface_attribute( - aws_retry=True, - NetworkInterfaceId=eni_id, - Groups=groups - ) + if not module.check_mode: + connection.modify_network_interface_attribute( + aws_retry=True, + NetworkInterfaceId=eni_id, + Groups=groups + ) changed = True if source_dest_check is not None: if "SourceDestCheck" not in eni or eni["SourceDestCheck"] != source_dest_check: - connection.modify_network_interface_attribute( - aws_retry=True, - NetworkInterfaceId=eni_id, - SourceDestCheck={'Value': source_dest_check} - ) + if not module.check_mode: + connection.modify_network_interface_attribute( + aws_retry=True, + NetworkInterfaceId=eni_id, + SourceDestCheck={'Value': source_dest_check} + ) changed = True if delete_on_termination is not None and "Attachment" in eni: if eni["Attachment"]["DeleteOnTermination"] is not delete_on_termination: - connection.modify_network_interface_attribute( - aws_retry=True, - NetworkInterfaceId=eni_id, - Attachment={'AttachmentId': eni["Attachment"]["AttachmentId"], - 'DeleteOnTermination': delete_on_termination} - ) + if not module.check_mode: + connection.modify_network_interface_attribute( + aws_retry=True, + NetworkInterfaceId=eni_id, + Attachment={'AttachmentId': eni["Attachment"]["AttachmentId"], + 'DeleteOnTermination': delete_on_termination} + ) + if delete_on_termination: + waiter = "network_interface_delete_on_terminate" + else: + waiter = "network_interface_no_delete_on_terminate" + get_waiter(connection, waiter).wait(NetworkInterfaceIds=[eni_id]) changed = True - if delete_on_termination: - waiter = "network_interface_delete_on_terminate" - else: - waiter = "network_interface_no_delete_on_terminate" - get_waiter(connection, waiter).wait(NetworkInterfaceIds=[eni_id]) current_secondary_addresses = [] if "PrivateIpAddresses" in eni: @@ -566,65 +581,71 @@ def modify_eni(connection, module, eni): if secondary_private_ip_addresses is not None: secondary_addresses_to_remove = list(set(current_secondary_addresses) - set(secondary_private_ip_addresses)) if secondary_addresses_to_remove and purge_secondary_private_ip_addresses: - connection.unassign_private_ip_addresses( - aws_retry=True, - NetworkInterfaceId=eni_id, - PrivateIpAddresses=list(set(current_secondary_addresses) - set(secondary_private_ip_addresses)), - ) - wait_for(absent_ips, connection, secondary_addresses_to_remove, module, eni_id) + if not module.check_mode: + connection.unassign_private_ip_addresses( + aws_retry=True, + NetworkInterfaceId=eni_id, + PrivateIpAddresses=list(set(current_secondary_addresses) - set(secondary_private_ip_addresses)), + ) + wait_for(absent_ips, connection, secondary_addresses_to_remove, module, eni_id) changed = True secondary_addresses_to_add = list(set(secondary_private_ip_addresses) - set(current_secondary_addresses)) if secondary_addresses_to_add: - connection.assign_private_ip_addresses( - aws_retry=True, - NetworkInterfaceId=eni_id, - PrivateIpAddresses=secondary_addresses_to_add, - AllowReassignment=allow_reassignment - ) - wait_for(correct_ips, connection, secondary_addresses_to_add, module, eni_id) + if not module.check_mode: + connection.assign_private_ip_addresses( + aws_retry=True, + NetworkInterfaceId=eni_id, + PrivateIpAddresses=secondary_addresses_to_add, + AllowReassignment=allow_reassignment + ) + wait_for(correct_ips, connection, secondary_addresses_to_add, module, eni_id) changed = True if secondary_private_ip_address_count is not None: current_secondary_address_count = len(current_secondary_addresses) if secondary_private_ip_address_count > current_secondary_address_count: - connection.assign_private_ip_addresses( - aws_retry=True, - NetworkInterfaceId=eni_id, - SecondaryPrivateIpAddressCount=(secondary_private_ip_address_count - current_secondary_address_count), - AllowReassignment=allow_reassignment - ) - wait_for(correct_ip_count, connection, secondary_private_ip_address_count, module, eni_id) + if not module.check_mode: + connection.assign_private_ip_addresses( + aws_retry=True, + NetworkInterfaceId=eni_id, + SecondaryPrivateIpAddressCount=(secondary_private_ip_address_count - current_secondary_address_count), + AllowReassignment=allow_reassignment + ) + wait_for(correct_ip_count, connection, secondary_private_ip_address_count, module, eni_id) changed = True elif secondary_private_ip_address_count < current_secondary_address_count: # How many of these addresses do we want to remove - secondary_addresses_to_remove_count = current_secondary_address_count - secondary_private_ip_address_count - connection.unassign_private_ip_addresses( - aws_retry=True, - NetworkInterfaceId=eni_id, - PrivateIpAddresses=current_secondary_addresses[:secondary_addresses_to_remove_count] - ) - wait_for(correct_ip_count, connection, secondary_private_ip_address_count, module, eni_id) + if not module.check_mode: + secondary_addresses_to_remove_count = current_secondary_address_count - secondary_private_ip_address_count + connection.unassign_private_ip_addresses( + aws_retry=True, + NetworkInterfaceId=eni_id, + PrivateIpAddresses=current_secondary_addresses[:secondary_addresses_to_remove_count] + ) + wait_for(correct_ip_count, connection, secondary_private_ip_address_count, module, eni_id) changed = True if attached is True: if "Attachment" in eni and eni["Attachment"]["InstanceId"] != instance_id: - detach_eni(connection, eni, module) - connection.attach_network_interface( - aws_retry=True, - InstanceId=instance_id, - DeviceIndex=device_index, - NetworkInterfaceId=eni_id, - ) - get_waiter(connection, 'network_interface_attached').wait(NetworkInterfaceIds=[eni_id]) + if not module.check_mode: + detach_eni(connection, eni, module) + connection.attach_network_interface( + aws_retry=True, + InstanceId=instance_id, + DeviceIndex=device_index, + NetworkInterfaceId=eni_id, + ) + get_waiter(connection, 'network_interface_attached').wait(NetworkInterfaceIds=[eni_id]) changed = True if "Attachment" not in eni: - connection.attach_network_interface( - aws_retry=True, - InstanceId=instance_id, - DeviceIndex=device_index, - NetworkInterfaceId=eni_id, - ) - get_waiter(connection, 'network_interface_attached').wait(NetworkInterfaceIds=[eni_id]) + if not module.check_mode: + connection.attach_network_interface( + aws_retry=True, + InstanceId=instance_id, + DeviceIndex=device_index, + NetworkInterfaceId=eni_id, + ) + get_waiter(connection, 'network_interface_attached').wait(NetworkInterfaceIds=[eni_id]) changed = True elif attached is False: @@ -637,6 +658,8 @@ def modify_eni(connection, module, eni): module.fail_json_aws(e, "Failed to modify eni {0}".format(eni_id)) eni = describe_eni(connection, module, eni_id) + if module.check_mode and changed: + module.exit_json(changed=changed, msg="Would have modified ENI: {0} if not in check mode".format(eni['NetworkInterfaceId'])) module.exit_json(changed=changed, interface=get_eni_info(eni)) @@ -656,6 +679,9 @@ def delete_eni(connection, module): if not eni: module.exit_json(changed=False) + if module.check_mode: + module.exit_json(changed=True, msg="Would have deleted ENI if not in check mode.") + eni_id = eni["NetworkInterfaceId"] force_detach = module.params.get("force_detach") @@ -683,6 +709,9 @@ def delete_eni(connection, module): def detach_eni(connection, eni, module): + if module.check_mode: + module.exit_json(changed=True, msg="Would have detached ENI if not in check mode.") + attached = module.params.get("attached") eni_id = eni["NetworkInterfaceId"] @@ -836,7 +865,8 @@ def main(): required_if=([ ('attached', True, ['instance_id']), ('purge_secondary_private_ip_addresses', True, ['secondary_private_ip_addresses']) - ]) + ]), + supports_check_mode=True, ) retry_decorator = AWSRetry.jittered_backoff( diff --git a/tests/integration/targets/ec2_eni/tasks/test_attachment.yaml b/tests/integration/targets/ec2_eni/tasks/test_attachment.yaml index 333b9f538a8..3ce0e9353a3 100644 --- a/tests/integration/targets/ec2_eni/tasks/test_attachment.yaml +++ b/tests/integration/targets/ec2_eni/tasks/test_attachment.yaml @@ -8,6 +8,21 @@ - "{{ instance_id_2 }}" wait: True +- name: attach the network interface to instance 1 (check mode) + ec2_eni: + instance_id: "{{ instance_id_1 }}" + device_index: 1 + private_ip_address: "{{ ip_1 }}" + subnet_id: "{{ vpc_subnet_result.subnet.id }}" + state: present + attached: True + check_mode: true + register: result_check_mode + +- assert: + that: + - result_check_mode.changed + - name: attach the network interface to instance 1 ec2_eni: instance_id: "{{ instance_id_1 }}" @@ -84,6 +99,21 @@ _interface_0: '{{ eni_info.network_interfaces[0] }}' # ============================================================ +- name: test attaching the network interface to a different instance (check mode) + ec2_eni: + instance_id: "{{ instance_id_2 }}" + device_index: 1 + private_ip_address: "{{ ip_1 }}" + subnet_id: "{{ vpc_subnet_result.subnet.id }}" + state: present + attached: True + check_mode: true + register: result_check_mode + +- assert: + that: + - result_check_mode.changed + - name: test attaching the network interface to a different instance ec2_eni: instance_id: "{{ instance_id_2 }}" @@ -109,6 +139,21 @@ _interface_0: '{{ eni_info.network_interfaces[0] }}' # ============================================================ +- name: detach the network interface (check mode) + ec2_eni: + instance_id: "{{ instance_id_2 }}" + device_index: 1 + private_ip_address: "{{ ip_1 }}" + subnet_id: "{{ vpc_subnet_result.subnet.id }}" + state: present + attached: False + check_mode: true + register: result_check_mode + +- assert: + that: + - result_check_mode.changed + - name: detach the network interface ec2_eni: instance_id: "{{ instance_id_2 }}" @@ -182,6 +227,19 @@ - "{{ instance_id_2 }}" wait: True +- name: delete an attached network interface with force_detach (check mode) + ec2_eni: + force_detach: True + eni_id: "{{ eni_id_1 }}" + state: absent + check_mode: true + register: result_check_mode + ignore_errors: True + +- assert: + that: + - result_check_mode.changed + - name: delete an attached network interface with force_detach ec2_eni: force_detach: True diff --git a/tests/integration/targets/ec2_eni/tasks/test_deletion.yaml b/tests/integration/targets/ec2_eni/tasks/test_deletion.yaml index b6dffc3481e..a0144aabab8 100644 --- a/tests/integration/targets/ec2_eni/tasks/test_deletion.yaml +++ b/tests/integration/targets/ec2_eni/tasks/test_deletion.yaml @@ -1,5 +1,18 @@ --- # ============================================================ +- name: test deleting the unattached network interface by using the ID (check mode) + ec2_eni: + eni_id: "{{ eni_id_1 }}" + name: "{{ resource_prefix }}" + subnet_id: "{{ vpc_subnet_id }}" + state: absent + check_mode: True + register: result_check_mode + +- assert: + that: + - result_check_mode.changed + - name: test deleting the unattached network interface by using the ID ec2_eni: eni_id: "{{ eni_id_1 }}" @@ -18,6 +31,19 @@ - '"network_interfaces" in eni_info' - eni_id_1 not in ( eni_info.network_interfaces | selectattr('id') | map(attribute='id') | list ) +- name: test removing the network interface by ID is idempotent (check mode) + ec2_eni: + eni_id: "{{ eni_id_1 }}" + name: "{{ resource_prefix }}" + subnet_id: "{{ vpc_subnet_id }}" + state: absent + check_mode: True + register: result_check_mode + +- assert: + that: + - not result_check_mode.changed + - name: test removing the network interface by ID is idempotent ec2_eni: eni_id: "{{ eni_id_1 }}" diff --git a/tests/integration/targets/ec2_eni/tasks/test_eni_basic_creation.yaml b/tests/integration/targets/ec2_eni/tasks/test_eni_basic_creation.yaml index 66f3c3070f2..42735a9a831 100644 --- a/tests/integration/targets/ec2_eni/tasks/test_eni_basic_creation.yaml +++ b/tests/integration/targets/ec2_eni/tasks/test_eni_basic_creation.yaml @@ -1,5 +1,18 @@ --- # ============================================================ +- name: create a network interface (check mode) + ec2_eni: + device_index: 1 + private_ip_address: "{{ ip_1 }}" + subnet_id: "{{ vpc_subnet_id }}" + state: present + check_mode: true + register: result_check_mode + +- assert: + that: + - result_check_mode.changed + - name: create a network interface ec2_eni: device_index: 1 @@ -77,6 +90,19 @@ - '"vpc_id" in _interface_0' - _interface_0.vpc_id == vpc_id +- name: test idempotence by using the same private_ip_address (check mode) + ec2_eni: + device_index: 1 + private_ip_address: "{{ ip_1 }}" + subnet_id: "{{ vpc_subnet_id }}" + state: present + check_mode: true + register: result_check_mode + +- assert: + that: + - not result_check_mode.changed + - name: test idempotence by using the same private_ip_address ec2_eni: device_index: 1 diff --git a/tests/integration/targets/ec2_eni/tasks/test_ipaddress_assign.yaml b/tests/integration/targets/ec2_eni/tasks/test_ipaddress_assign.yaml index 1e67227cb4f..3f6d85b81ac 100644 --- a/tests/integration/targets/ec2_eni/tasks/test_ipaddress_assign.yaml +++ b/tests/integration/targets/ec2_eni/tasks/test_ipaddress_assign.yaml @@ -1,5 +1,19 @@ --- # ============================================================ +- name: add two implicit secondary IPs (check mode) + ec2_eni: + device_index: 1 + private_ip_address: "{{ ip_1 }}" + subnet_id: "{{ vpc_subnet_id }}" + state: present + secondary_private_ip_address_count: 2 + check_mode: true + register: result_check_mode + +- assert: + that: + - result_check_mode.changed + - name: add two implicit secondary IPs ec2_eni: device_index: 1 @@ -22,6 +36,20 @@ vars: _interface_0: '{{ eni_info.network_interfaces[0] }}' +- name: test idempotence with two implicit secondary IPs (check mode) + ec2_eni: + device_index: 1 + private_ip_address: "{{ ip_1 }}" + subnet_id: "{{ vpc_subnet_id }}" + state: present + secondary_private_ip_address_count: 2 + check_mode: true + register: result_check_mode + +- assert: + that: + - not result_check_mode.changed + - name: test idempotence with two implicit secondary IPs ec2_eni: device_index: 1 @@ -109,6 +137,21 @@ _private_ips: "{{ eni_info.network_interfaces | map(attribute='private_ip_addresses') | flatten | map(attribute='private_ip_address') | list }}" # ============================================================ +- name: remove secondary address (check mode) + ec2_eni: + purge_secondary_private_ip_addresses: true + device_index: 1 + private_ip_address: "{{ ip_1 }}" + subnet_id: "{{ vpc_subnet_id }}" + state: present + secondary_private_ip_addresses: [] + check_mode: true + register: result_check_mode + +- assert: + that: + - result_check_mode.changed + - name: remove secondary address ec2_eni: purge_secondary_private_ip_addresses: true @@ -132,6 +175,21 @@ vars: _interface_0: '{{ eni_info.network_interfaces[0] }}' +- name: test idempotent behavior purging secondary addresses (check mode) + ec2_eni: + purge_secondary_private_ip_addresses: true + device_index: 1 + private_ip_address: "{{ ip_1 }}" + subnet_id: "{{ vpc_subnet_id }}" + state: present + secondary_private_ip_addresses: [] + check_mode: true + register: result_check_mode + +- assert: + that: + - not result_check_mode.changed + - name: test idempotent behavior purging secondary addresses ec2_eni: purge_secondary_private_ip_addresses: true diff --git a/tests/integration/targets/ec2_eni/tasks/test_modifying_delete_on_termination.yaml b/tests/integration/targets/ec2_eni/tasks/test_modifying_delete_on_termination.yaml index 54240b4d2a2..f8c6e23b1b2 100644 --- a/tests/integration/targets/ec2_eni/tasks/test_modifying_delete_on_termination.yaml +++ b/tests/integration/targets/ec2_eni/tasks/test_modifying_delete_on_termination.yaml @@ -23,6 +23,22 @@ # ============================================================ +- name: enable delete_on_termination (check mode) + ec2_eni: + instance_id: "{{ instance_id_2 }}" + device_index: 1 + private_ip_address: "{{ ip_1 }}" + subnet_id: "{{ vpc_subnet_result.subnet.id }}" + state: present + attached: True + delete_on_termination: True + check_mode: true + register: result_check_mode + +- assert: + that: + - result_check_mode.changed + - name: enable delete_on_termination ec2_eni: instance_id: "{{ instance_id_2 }}" @@ -45,6 +61,22 @@ vars: _interface_0: '{{ eni_info.network_interfaces[0] }}' +- name: test idempotent behavior enabling delete_on_termination (check mode) + ec2_eni: + instance_id: "{{ instance_id_2 }}" + device_index: 1 + private_ip_address: "{{ ip_1 }}" + subnet_id: "{{ vpc_subnet_result.subnet.id }}" + state: present + attached: True + delete_on_termination: True + check_mode: true + register: result_check_mode + +- assert: + that: + - not result_check_mode.changed + - name: test idempotent behavior enabling delete_on_termination ec2_eni: instance_id: "{{ instance_id_2 }}" @@ -63,6 +95,22 @@ # ============================================================ +- name: disable delete_on_termination (check mode) + ec2_eni: + instance_id: "{{ instance_id_2 }}" + device_index: 1 + private_ip_address: "{{ ip_1 }}" + subnet_id: "{{ vpc_subnet_result.subnet.id }}" + state: present + attached: True + delete_on_termination: False + check_mode: true + register: result_check_mode + +- assert: + that: + - result_check_mode.changed + - name: disable delete_on_termination ec2_eni: instance_id: "{{ instance_id_2 }}" diff --git a/tests/integration/targets/ec2_eni/tasks/test_modifying_source_dest_check.yaml b/tests/integration/targets/ec2_eni/tasks/test_modifying_source_dest_check.yaml index 3ba6c2574f1..4259d3a81a3 100644 --- a/tests/integration/targets/ec2_eni/tasks/test_modifying_source_dest_check.yaml +++ b/tests/integration/targets/ec2_eni/tasks/test_modifying_source_dest_check.yaml @@ -1,4 +1,16 @@ # ============================================================ +- name: test source_dest_check defaults to true (check mode) + ec2_eni: + eni_id: "{{ eni_id_1 }}" + source_dest_check: true + state: present + check_mode: true + register: result_check_mode + +- assert: + that: + - not result_check_mode.changed + - name: test source_dest_check defaults to true ec2_eni: eni_id: "{{ eni_id_1 }}" @@ -36,6 +48,18 @@ vars: _interface_0: '{{ eni_info.network_interfaces[0] }}' +- name: test idempotence disabling source_dest_check (check mode) + ec2_eni: + eni_id: "{{ eni_id_1 }}" + source_dest_check: false + state: present + check_mode: true + register: result_check_mode + +- assert: + that: + - not result_check_mode.changed + - name: test idempotence disabling source_dest_check ec2_eni: eni_id: "{{ eni_id_1 }}" diff --git a/tests/integration/targets/ec2_eni/tasks/test_modifying_tags.yaml b/tests/integration/targets/ec2_eni/tasks/test_modifying_tags.yaml index 8164f869f52..d26d96b5b0b 100644 --- a/tests/integration/targets/ec2_eni/tasks/test_modifying_tags.yaml +++ b/tests/integration/targets/ec2_eni/tasks/test_modifying_tags.yaml @@ -13,6 +13,20 @@ - result.interface.name is undefined # ============================================================ +- name: add tags to the network interface (check mode) + ec2_eni: + eni_id: "{{ eni_id_1 }}" + state: present + name: "{{ resource_prefix }}" + tags: + CreatedBy: "{{ resource_prefix }}" + check_mode: true + register: result_check_mode + +- assert: + that: + - result_check_mode.changed + - name: add tags to the network interface ec2_eni: eni_id: "{{ eni_id_1 }}" @@ -44,6 +58,18 @@ _interface_0: '{{ eni_info.network_interfaces[0] }}' # ============================================================ +- name: test idempotence by using the Name tag and the subnet (check mode) + ec2_eni: + name: "{{ resource_prefix }}" + state: present + subnet_id: "{{ vpc_subnet_result.subnet.id }}" + check_mode: true + register: result_check_mode + +- assert: + that: + - not result_check_mode.changed + - name: test idempotence by using the Name tag and the subnet ec2_eni: name: "{{ resource_prefix }}" @@ -57,6 +83,18 @@ - result.interface.id == eni_id_1 # ============================================================ +- name: test tags are not purged if tags are null even if name is provided (check mode) + ec2_eni: + name: "{{ resource_prefix }}" + state: present + subnet_id: "{{ vpc_subnet_result.subnet.id }}" + check_mode: true + register: result_check_mode + +- assert: + that: + - not result_check_mode.changed + - name: test tags are not purged if tags are null even if name is provided ec2_eni: name: "{{ resource_prefix }}"