From a74d629b085a1962b483f13fc2e84d80a4e14a57 Mon Sep 17 00:00:00 2001 From: abikouo Date: Thu, 17 Oct 2024 18:17:24 +0200 Subject: [PATCH] Code review updates --- .../20240110-ec2_launch_template-refactor.yml | 7 +- plugins/modules/ec2_launch_template.py | 367 +++++++----------- .../ec2_launch_template/tasks/limits.yml | 52 --- .../ec2_launch_template/tasks/main.yml | 1 - .../ec2_launch_template/tasks/tagging.yml | 83 +++- 5 files changed, 226 insertions(+), 284 deletions(-) delete mode 100644 tests/integration/targets/ec2_launch_template/tasks/limits.yml diff --git a/changelogs/fragments/20240110-ec2_launch_template-refactor.yml b/changelogs/fragments/20240110-ec2_launch_template-refactor.yml index f1f145f8226..d2e7293fa9a 100644 --- a/changelogs/fragments/20240110-ec2_launch_template-refactor.yml +++ b/changelogs/fragments/20240110-ec2_launch_template-refactor.yml @@ -1,6 +1,9 @@ --- +breaking_changes: + - ec2_launch_template - Tags defined using option ``tags`` are now applied to the launch template resources not the resource created using this launch template (https://github.com/ansible-collections/community.aws/issues/176). minor_changes: - ec2_launch_template - Refactor module to use shared code from ``amazon.aws.plugins.module_utils.ec2`` and update ``RETURN`` block (https://github.com/ansible-collections/community.aws/pull/2164). - ec2_launch_template - Add the possibility to delete specific versions of a launch template using ``versions_to_delete`` (https://github.com/ansible-collections/community.aws/pull/2164). - - ec2_launch_template - Add support for template tags via ``template_tags`` and ``purge_template_tags`` options (https://github.com/ansible-collections/community.aws/issues/176). - - ec2_launch_template - Add suboption ``throughput`` to ``block_device_mappings`` argument (https://github.com/ansible-collections/community.aws/issues/1944). + - ec2_launch_template - Add suboption ``throughput`` to ``block_device_mappings`` argument (https://github.com/ansible-collections/community.aws/issues/1944). + - ec2_launch_template - Add option ``tag_specifications`` to define tags to be applied to the resources created with the launch template (https://github.com/ansible-collections/community.aws/issues/176). + - ec2_launch_template - Add support ``purge_tags`` parameter (https://github.com/ansible-collections/community.aws/issues/176). diff --git a/plugins/modules/ec2_launch_template.py b/plugins/modules/ec2_launch_template.py index e9ee53ea5cf..a33b011bf8f 100644 --- a/plugins/modules/ec2_launch_template.py +++ b/plugins/modules/ec2_launch_template.py @@ -74,7 +74,7 @@ elements: dict suboptions: device_name: - description: The device name (for example, /dev/sdh or xvdh). + description: The device name (for example, V(/dev/sdh) or V(xvdh)). type: str no_device: description: Suppresses the specified device included in the block device mapping of the AMI. @@ -133,7 +133,7 @@ throughput: description: > The throughput to provision for a gp3 volume, with a maximum of 1,000 MiB/s. - Valid Range - Minimum value of 125. Maximum value of 1000. + Valid Range - Minimum value of V(125). Maximum value of V(1000). type: int version_added: 9.0.0 cpu_options: @@ -148,24 +148,21 @@ threads_per_core: description: > The number of threads per CPU core. To disable Intel Hyper-Threading - Technology for the instance, specify a value of 1. Otherwise, specify - the default value of 2. + Technology for the instance, specify a value of V(1). Otherwise, specify + the default value of V(2). type: int credit_specification: description: The credit option for CPU usage of the instance. Valid for T2 or T3 instances only. type: dict suboptions: cpu_credits: - description: > - The credit option for CPU usage of a T2 or T3 instance. Valid values - are C(standard) and C(unlimited). + description: + - The credit option for CPU usage of a T2 or T3 instance. Valid values are C(standard) and C(unlimited). type: str disable_api_termination: - description: > - This helps protect instances from accidental termination. If set to true, - you can't terminate the instance using the Amazon EC2 console, CLI, or - API. To change this attribute to false after launch, use - I(ModifyInstanceAttribute). + description: + - This helps protect instances from accidental termination. + - If set to V(true), you can't terminate the instance using the Amazon EC2 console, CLI, or API. type: bool ebs_optimized: description: > @@ -204,20 +201,19 @@ type: dict suboptions: market_type: - description: The market type. This should always be 'spot'. + description: The market type. This should always be V(spot). type: str spot_options: description: Spot-market specific settings. type: dict suboptions: block_duration_minutes: - description: > - The required duration for the Spot Instances (also known as Spot - blocks), in minutes. This value must be a multiple of 60 (60, - 120, 180, 240, 300, or 360). + description: + - The required duration for the Spot Instances (also known as Spot blocks), in minutes. + - This value must be a multiple of V(60) (V(60), V(120), V(180), V(240), V(300), or V(360)). type: int instance_interruption_behavior: - description: The behavior when a Spot Instance is interrupted. The default is C(terminate). + description: The behavior when a Spot Instance is interrupted. The default is V(terminate). choices: [hibernate, stop, terminate] type: str max_price: @@ -228,22 +224,21 @@ choices: [one-time, persistent] type: str instance_type: - description: > - The instance type, such as C(c5.2xlarge). For a full list of instance types, see - U(http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-types.html). + description: + - The instance type, such as V(c5.2xlarge). For a full list of instance types, see + U(http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-types.html). type: str kernel_id: - description: > - The ID of the kernel. We recommend that you use PV-GRUB instead of - kernels and RAM disks. For more information, see - U(http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/UserProvidedkernels.html) + description: + - The ID of the kernel. + - We recommend that you use PV-GRUB instead of kernels and RAM disks. For more information, see + U(http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/UserProvidedkernels.html) type: str key_name: description: - The name of the key pair. You can create a key pair using M(amazon.aws.ec2_key). - If you do not specify a key pair, you can't connect to the instance - unless you choose an AMI that is configured to allow users another way to - log in. + unless you choose an AMI that is configured to allow users another way to log in. type: str monitoring: description: Settings for instance monitoring. @@ -274,16 +269,15 @@ type: list elements: str ipv6_address_count: - description: > - The number of IPv6 addresses to assign to a network interface. Amazon - EC2 automatically selects the IPv6 addresses from the subnet range. - You can't use this option if specifying the I(ipv6_addresses) option. + description: + - The number of IPv6 addresses to assign to a network interface. + - Amazon EC2 automatically selects the IPv6 addresses from the subnet range. + - You can't use this option if specifying the O(network_interfaces.ipv6_addresses) option. type: int ipv6_addresses: - description: > - A list of one or more specific IPv6 addresses from the IPv6 CIDR - block range of your subnet. You can't use this option if you're - specifying the I(ipv6_address_count) option. + description: + - A list of one or more specific IPv6 addresses from the IPv6 CIDR block range of your subnet. + - You can't use this option if you're specifying the O(network_interfaces.ipv6_address_count) option. type: list elements: str network_interface_id: @@ -329,25 +323,17 @@ security_groups: description: > A list of security group names (Default VPC or EC2-Classic) that the new instances will be added to. - For any VPC other than Default, you must use I(security_group_ids). + For any VPC other than Default, you must use O(security_group_ids). type: list elements: str source_version: - description: > - The version number of the launch template version on which to base the new version. - The new version inherits the same launch parameters as the source version, except for parameters that you explicity specify. - Snapshots applied to the block device mapping are ignored when creating a new version unless they are explicitly included. + description: + - The version number of the launch template version on which to base the new version. + - The new version inherits the same launch parameters as the source version, except for parameters that you explicity specify. + - Snapshots applied to the O(block_device_mappings) are ignored when creating a new version unless they are explicitly included. type: str default: latest version_added: 4.1.0 - tags: - type: dict - description: - - A set of key-value pairs to be applied to resources when this Launch Template is used. - - "Tag key constraints: Tag keys are case-sensitive and accept a maximum of 127 Unicode characters. May not begin with I(aws:)" - - "Tag value constraints: Tag values are case-sensitive and accept a maximum of 255 Unicode characters." - - This field is deprecated and will be removed in a release after 2026-12-01, use O(tag_specifications) instead. - aliases: ['resource_tags'] tag_specifications: description: - The tags to apply to the resources when this Launch template is used. @@ -389,27 +375,25 @@ suboptions: http_endpoint: type: str - description: > - This parameter enables or disables the HTTP metadata endpoint on your instances. + description: This parameter enables or disables the HTTP metadata endpoint on your instances. choices: [enabled, disabled] default: 'enabled' http_put_response_hop_limit: type: int - description: > - The desired HTTP PUT response hop limit for instance metadata requests. - The larger the number, the further instance metadata requests can travel. + description: + - The desired HTTP PUT response hop limit for instance metadata requests. + - The larger the number, the further instance metadata requests can travel. default: 1 http_tokens: type: str - description: > - The state of token usage for your instance metadata requests. + description: The state of token usage for your instance metadata requests. choices: [optional, required] default: 'optional' http_protocol_ipv6: version_added: 3.1.0 type: str - description: > - - Wether the instance metadata endpoint is available via IPv6 (V(enabled)) or not (V(disabled)). + description: + - Wether the instance metadata endpoint is available via IPv6. choices: [enabled, disabled] default: 'disabled' instance_metadata_tags: @@ -419,31 +403,15 @@ - Wether the instance tags are availble (V(enabled)) via metadata endpoint or not (V(disabled)). choices: [enabled, disabled] default: 'disabled' - template_tags: - description: - - A dictionary representing the tags to be applied to the launch template. - - If the O(template_tags) parameter is not set then tags will not be modified. - type: dict - required: false - version_added: 9.0.0 - purge_template_tags: - description: - - If O(purge_template_tags=true) and O(template_tags) is set, existing tags will be purged - from the resource to match exactly what is defined by O(template_tags) parameter. - - If the O(template_tags) parameter is not set then tags will not be modified, even - if O(purge_template_tags=True). - - Tag keys beginning with V(aws:) are reserved by Amazon and can not be - modified. As such they will be ignored for the purposes of the - O(purge_template_tags) parameter. See the Amazon documentation for more information - U(https://docs.aws.amazon.com/general/latest/gr/aws_tagging.html#tag-conventions). - type: bool - default: true - required: false - version_added: 9.0.0 +notes: + - The O(tags) option used has been in release 9.0.0 to be applied to the launch template resource instead of launch template resource. + - Use O(tag_specifications) to define tags to be applied to resources when this Launch Template is used. + - Support for O(purge_tags) was added in release 9.0.0. extends_documentation_fragment: - amazon.aws.common.modules - amazon.aws.region.modules - amazon.aws.boto3 +- amazon.aws.tags """ EXAMPLES = r""" @@ -490,7 +458,7 @@ image_id: "ami-04b762b4289fba92b" instance_type: t2.micro disable_api_termination: true - template_tags: + tags: Some: tag Another: tag @@ -1180,10 +1148,8 @@ from ansible_collections.amazon.aws.plugins.module_utils.ec2 import determine_iam_arn_from_name from ansible_collections.amazon.aws.plugins.module_utils.ec2 import ensure_ec2_tags from ansible_collections.amazon.aws.plugins.module_utils.ec2 import modify_launch_template -from ansible_collections.amazon.aws.plugins.module_utils.exceptions import AnsibleAWSError -from ansible_collections.amazon.aws.plugins.module_utils.exceptions import is_ansible_aws_error_code -from ansible_collections.amazon.aws.plugins.module_utils.tagging import ansible_dict_to_boto3_tag_list from ansible_collections.amazon.aws.plugins.module_utils.tagging import boto3_tag_list_to_ansible_dict +from ansible_collections.amazon.aws.plugins.module_utils.tagging import boto3_tag_specifications from ansible_collections.amazon.aws.plugins.module_utils.transformation import scrub_none_parameters from ansible_collections.community.aws.plugins.module_utils.modules import AnsibleCommunityAWSModule as AnsibleAWSModule @@ -1192,53 +1158,25 @@ def find_existing(client, module: AnsibleAWSModule) -> Tuple[Optional[Dict[str, Any]], Optional[List[Dict[str, Any]]]]: launch_template = None launch_template_versions = [] - try: - params = {} - template_id = module.params.get("template_id") - template_name = module.params.get("template_name") - if template_id: - params["launch_template_ids"] = [template_id] - else: - params["launch_template_names"] = [template_name] - launch_templates = describe_launch_templates(client, **params) - if launch_templates: - launch_template = launch_templates[0] - launch_template_versions = describe_launch_template_versions( - client, LaunchTemplateId=launch_template["LaunchTemplateId"] - ) - return normalize_boto3_result(launch_template), normalize_boto3_result(launch_template_versions) - except is_ansible_aws_error_code("InvalidLaunchTemplateId.Malformed") as e: # pylint: disable=duplicate-except - module.fail_json_aws( - e, - msg=( - f"Launch template with ID {module.params.get('launch_template_id')} is not a valid ID. It should start" - " with `lt-....`" - ), + params = {} + template_id = module.params.get("template_id") + template_name = module.params.get("template_name") + if template_id: + params["launch_template_ids"] = [template_id] + else: + params["launch_template_names"] = [template_name] + launch_templates = describe_launch_templates(client, **params) + if launch_templates: + launch_template = launch_templates[0] + launch_template_versions = describe_launch_template_versions( + client, LaunchTemplateId=launch_template["LaunchTemplateId"] ) - except AnsibleAWSError as e: # pylint: disable=duplicate-except - module.fail_json_aws_error(e) + return normalize_boto3_result(launch_template), normalize_boto3_result(launch_template_versions) def params_to_launch_data( template_params: Dict[str, Any], iam_instance_profile_arn: Optional[str] = None ) -> Dict[str, Any]: - tag_specifications = [] - if template_params.get("tag_specifications"): - tag_specifications = [ - {"resource_type": ts["resource_type"], "tags": ansible_dict_to_boto3_tag_list(ts["tags"])} - for ts in template_params["tag_specifications"] - ] - if template_params.get("tags"): - tag_list = ansible_dict_to_boto3_tag_list(template_params.get("tags")) - tag_specifications += [ - {"resource_type": r_type, "tags": tag_list} for r_type in ("instance", "volume", "network-interface") - ] - del template_params["tags"] - - # In case some tags were defined, add them to the template parameters - if tag_specifications: - template_params["tag_specifications"] = tag_specifications - if iam_instance_profile_arn: template_params["iam_instance_profile"] = {"arn": iam_instance_profile_arn} for interface in template_params.get("network_interfaces") or []: @@ -1318,43 +1256,41 @@ def ensure_absent( if existing: launch_template_id = existing["LaunchTemplateId"] v_to_delete, v_default = validate_version_deletion(module, launch_template_id, existing_versions) - try: - # Update default version - if v_default: - changed = True - if not module.check_mode: - modify_launch_template( - client, - LaunchTemplateId=launch_template_id, - ClientToken=uuid4().hex, - DefaultVersion=to_text(v_default), - ) - # Delete versions - if v_to_delete: - changed = True - if not module.check_mode: - response = delete_launch_template_versions( - client, launch_template_id=launch_template_id, versions=v_to_delete + + # Update default version + if v_default: + changed = True + if not module.check_mode: + modify_launch_template( + client, + LaunchTemplateId=launch_template_id, + ClientToken=uuid4().hex, + DefaultVersion=to_text(v_default), + ) + # Delete versions + if v_to_delete: + changed = True + if not module.check_mode: + response = delete_launch_template_versions( + client, launch_template_id=launch_template_id, versions=v_to_delete + ) + if response["UnsuccessfullyDeletedLaunchTemplateVersions"]: + module.warn( + f"Failed to delete template versions {response['UnsuccessfullyDeletedLaunchTemplateVersions']} on" + f" launch template {launch_template_id}" ) - if response["UnsuccessfullyDeletedLaunchTemplateVersions"]: - module.warn( - f"Failed to delete template versions {response['UnsuccessfullyDeletedLaunchTemplateVersions']} on" - f" launch template {launch_template_id}" - ) - deleted_versions = [ - camel_dict_to_snake_dict(v) for v in response["SuccessfullyDeletedLaunchTemplateVersions"] - ] + deleted_versions = [ + camel_dict_to_snake_dict(v) for v in response["SuccessfullyDeletedLaunchTemplateVersions"] + ] - # Delete the launch template when a list of versions was not specified - if not module.params.get("versions_to_delete"): - changed = True - if not module.check_mode: - deleted_template = delete_launch_template(client, launch_template_id=launch_template_id) - deleted_template = camel_dict_to_snake_dict(deleted_template, ignore_list=["Tags"]) - if "tags" in deleted_template: - deleted_template["tags"] = boto3_tag_list_to_ansible_dict(deleted_template.get("tags", [])) - except AnsibleEC2Error as e: - module.fail_json_aws_error(e) + # Delete the launch template when a list of versions was not specified + if not module.params.get("versions_to_delete"): + changed = True + if not module.check_mode: + deleted_template = delete_launch_template(client, launch_template_id=launch_template_id) + deleted_template = camel_dict_to_snake_dict(deleted_template, ignore_list=["Tags"]) + if "tags" in deleted_template: + deleted_template["tags"] = boto3_tag_list_to_ansible_dict(deleted_template.get("tags")) module.exit_json(changed=changed, deleted_versions=deleted_versions, deleted_template=deleted_template) @@ -1393,14 +1329,11 @@ def add_launch_template_version( if module.check_mode: module.exit_json(changed=True, msg="Would have created launch template version if not in check mode.") - try: - # Create Launch template version - launch_template_version = create_launch_template_version( - client, launch_template_data=launch_template_data, **params - ) - return launch_template_version["VersionNumber"] - except AnsibleEC2Error as e: - module.fail_json_aws_error(e) + # Create Launch template version + launch_template_version = create_launch_template_version( + client, launch_template_data=launch_template_data, **params + ) + return launch_template_version["VersionNumber"] def ensure_default_version( @@ -1420,16 +1353,13 @@ def ensure_default_version( default_version = to_text(validate_string_as_int(module, default_version, "default_version")) if to_text(current_default_version_number) != default_version: changed = True - try: - if not module.check_mode: - modify_launch_template( - client, - LaunchTemplateId=launch_template_id, - ClientToken=uuid4().hex, - DefaultVersion=default_version, - ) - except AnsibleEC2Error as e: - module.fail_json_aws_error(e) + if not module.check_mode: + modify_launch_template( + client, + LaunchTemplateId=launch_template_id, + ClientToken=uuid4().hex, + DefaultVersion=default_version, + ) return changed @@ -1437,7 +1367,8 @@ def format_module_output(client, module: AnsibleAWSModule) -> Dict[str, Any]: # Describe launch template template, template_versions = find_existing(client, module) template = camel_dict_to_snake_dict(template, ignore_list=["Tags"]) - template["tags"] = boto3_tag_list_to_ansible_dict(template.get("tags", [])) + if "tags" in template: + template["tags"] = boto3_tag_list_to_ansible_dict(template.get("tags")) template_versions = [camel_dict_to_snake_dict(v) for v in template_versions] result = { "template": template, @@ -1464,15 +1395,23 @@ def ensure_present( existing_versions: List[Dict[str, Any]], ) -> None: template_name = module.params["template_name"] - template_tags = module.params["template_tags"] - purge_template_tags = module.params["purge_template_tags"] + tags = module.params["tags"] + tag_specifications = module.params.get("tag_specifications") version_description = module.params.get("version_description") iam_instance_profile = module.params.get("iam_instance_profile") + # IAM instance profile if iam_instance_profile: iam_instance_profile = determine_iam_arn_from_name(module.client("iam"), iam_instance_profile) + # Convert Launch template data launch_template_data = params_to_launch_data( dict((k, v) for k, v in module.params.items() if k in template_options), iam_instance_profile ) + # Tag specifications + if tag_specifications: + boto3_tag_specs = [] + for tag_spec in tag_specifications: + boto3_tag_specs.extend(boto3_tag_specifications(tag_spec["tags"], types=tag_spec["resource_type"])) + launch_template_data["TagSpecifications"] = boto3_tag_specs launch_template_data = scrub_none_parameters(launch_template_data, descend_into_lists=True) changed = False @@ -1480,18 +1419,15 @@ def ensure_present( # Create Launch template if module.check_mode: module.exit_json(changed=True, msg="Would have created launch template if not in check mode.") - try: - create_launch_template( - client, - launch_template_name=template_name, - launch_template_data=launch_template_data, - tags=template_tags, - ClientToken=uuid4().hex, - VersionDescription=version_description, - ) - changed = True - except AnsibleEC2Error as e: - module.fail_json_aws_error(e) + create_launch_template( + client, + launch_template_name=template_name, + launch_template_data=launch_template_data, + tags=tags, + ClientToken=uuid4().hex, + VersionDescription=version_description, + ) + changed = True else: launch_template_id = existing["LaunchTemplateId"] default_version_number = existing["DefaultVersionNumber"] @@ -1521,8 +1457,8 @@ def ensure_present( module, launch_template_id, resource_type="launch-template", - tags=template_tags, - purge_tags=purge_template_tags, + tags=tags, + purge_tags=module.params["purge_tags"], ) module.exit_json(changed=changed, **format_module_output(client, module)) @@ -1635,8 +1571,20 @@ def main(): ram_disk_id=dict(), security_group_ids=dict(type="list", elements="str"), security_groups=dict(type="list", elements="str"), - tags=dict(type="dict", aliases=["resource_tags"]), user_data=dict(), + ) + + argument_spec = dict( + state=dict(choices=["present", "absent"], default="present"), + template_name=dict(aliases=["name"]), + template_id=dict(aliases=["id"]), + default_version=dict(default="latest"), + source_version=dict(default="latest"), + version_description=dict(default=""), + iam_instance_profile=dict(), + tags=dict(type="dict", aliases=["resource_tags"]), + purge_tags=dict(type="bool", default=True), + versions_to_delete=dict(type="list", elements="int"), tag_specifications=dict( type="list", elements="dict", @@ -1651,19 +1599,6 @@ def main(): ), ) - argument_spec = dict( - state=dict(choices=["present", "absent"], default="present"), - template_name=dict(aliases=["name"]), - template_id=dict(aliases=["id"]), - default_version=dict(default="latest"), - source_version=dict(default="latest"), - version_description=dict(default=""), - iam_instance_profile=dict(), - template_tags=dict(type="dict"), - purge_template_tags=dict(type="bool", default=True), - versions_to_delete=dict(type="list", elements="int"), - ) - argument_spec.update(template_options) module = AnsibleAWSModule( @@ -1674,21 +1609,17 @@ def main(): supports_check_mode=True, ) - if module.params.get("tags"): - module.deprecate( - "The tags parameter has been deprecated, please use tag_specifications instead.", - date="2026-12-01", - collection_name="community.aws", - ) - state = module.params.get("state") client = module.client("ec2") launch_template, launch_template_versions = find_existing(client, module) - if state == "present": - ensure_present(client, module, template_options, launch_template, launch_template_versions) - else: - ensure_absent(client, module, launch_template, launch_template_versions) + try: + if state == "present": + ensure_present(client, module, template_options, launch_template, launch_template_versions) + else: + ensure_absent(client, module, launch_template, launch_template_versions) + except AnsibleEC2Error as e: + module.fail_json_aws_error(e) if __name__ == "__main__": diff --git a/tests/integration/targets/ec2_launch_template/tasks/limits.yml b/tests/integration/targets/ec2_launch_template/tasks/limits.yml deleted file mode 100644 index c4e0ad4bc91..00000000000 --- a/tests/integration/targets/ec2_launch_template/tasks/limits.yml +++ /dev/null @@ -1,52 +0,0 @@ ---- -# Add integration tests for issue https://github.com/ansible-collections/community.aws/issues/2131 -- name: Test creation/deletion of launch template with more 200 versions - vars: - test_launch_template_name: "{{ resource_prefix }}-limits" - test_total_versions: "{{ range(1, 205) }}" - block: - - name: Create a Launch template with more than 200 versions using - community.aws.ec2_launch_template: - name: "{{ test_launch_template_name }}" - instance_type: t2.micro - version_description: "Version number {{ item }}" - source_version: 1 - default_version: 1 - with_items: "{{ test_total_versions }}" - - - name: Retrieve Launch template information - amazon.aws.ec2_launch_template_info: - filters: - launch-template-name: "{{ test_launch_template_name }}" - register: _templates - - - name: Ensure the Launch template was created as expected - ansible.builtin.assert: - that: - - _templates.launch_templates | length == 1 - - _templates.launch_templates[0].versions | length == test_total_versions | length - - - name: Delete the launch template - community.aws.ec2_launch_template: - name: "{{ test_launch_template_name }}" - state: absent - register: _delete_templ - - - name: Retrieve Launch template information - amazon.aws.ec2_launch_template_info: - filters: - launch-template-name: "{{ test_launch_template_name }}" - register: _templates - - - name: Ensure the Launch template does not exist anymore - ansible.builtin.assert: - that: - - _delete_templ is changed - - _templates.launch_templates | length == 0 - - always: - - name: Delete launch template - community.aws.ec2_launch_template: - state: absent - name: "{{ test_launch_template_name }}" - ignore_errors: true diff --git a/tests/integration/targets/ec2_launch_template/tasks/main.yml b/tests/integration/targets/ec2_launch_template/tasks/main.yml index 2e2e1df4705..c8ea5f055da 100644 --- a/tests/integration/targets/ec2_launch_template/tasks/main.yml +++ b/tests/integration/targets/ec2_launch_template/tasks/main.yml @@ -8,7 +8,6 @@ block: - include_tasks: template_data.yml - include_tasks: tagging.yml - # - include_tasks: limits.yml - include_tasks: iam_instance_role.yml - include_tasks: versions.yml - include_tasks: deletion.yml diff --git a/tests/integration/targets/ec2_launch_template/tasks/tagging.yml b/tests/integration/targets/ec2_launch_template/tasks/tagging.yml index f7de254edcd..b4d38da70c9 100644 --- a/tests/integration/targets/ec2_launch_template/tasks/tagging.yml +++ b/tests/integration/targets/ec2_launch_template/tasks/tagging.yml @@ -2,13 +2,35 @@ - name: Test tagging vars: test_launch_template_name: "{{ resource_prefix }}-tagging" + launch_template_instance_tags: + - key: foo + value: bar + - key: environment + value: test + launch_template_network_tags: + - key: owner + value: ansible + ansible_instance_tags: + foo: bar + environment: test + ansible_network_tags: + owner: ansible block: # Create launch template with tags - name: Create Launch template with tags community.aws.ec2_launch_template: name: "{{ test_launch_template_name }}" instance_type: t2.micro - template_tags: + network_interfaces: + - associate_public_ip_address: false + delete_on_termination: true + device_index: 0 + tag_specifications: + - resource_type: instance + tags: "{{ ansible_instance_tags }}" + - resource_type: network-interface + tags: "{{ ansible_network_tags }}" + tags: ResourcePrefix: "{{ resource_prefix }}" InstanceType: "t2.micro" register: _create_with_tags @@ -18,7 +40,7 @@ filters: launch-template-name: "{{ test_launch_template_name }}" register: _templates - + - name: Ensure the launch template was created with tags ansible.builtin.assert: that: @@ -29,13 +51,28 @@ - _templates.launch_templates[0].tags.InstanceType == "t2.micro" - _templates.launch_templates[0].tags.ResourcePrefix == resource_prefix - _templates.launch_templates[0].versions | length == 1 + - _templates.launch_templates[0].versions[0].launch_template_data.tag_specifications | length == 2 + - instance_tags.tags == launch_template_instance_tags + - network_interface_tags.tags == launch_template_network_tags + vars: + instance_tags: "{{ _templates.launch_templates[0].versions[0].launch_template_data.tag_specifications | selectattr('resource_type', 'equalto', 'instance') | list | first }}" + network_interface_tags: "{{ _templates.launch_templates[0].versions[0].launch_template_data.tag_specifications | selectattr('resource_type', 'equalto', 'network-interface') | list | first }}" # Create launch template once again with same tags (expected no change) - name: Create launch template once again with same tags (expected no change) community.aws.ec2_launch_template: name: "{{ test_launch_template_name }}" instance_type: t2.micro - template_tags: + network_interfaces: + - associate_public_ip_address: false + delete_on_termination: true + device_index: 0 + tag_specifications: + - resource_type: instance + tags: "{{ ansible_instance_tags }}" + - resource_type: network-interface + tags: "{{ ansible_network_tags }}" + tags: ResourcePrefix: "{{ resource_prefix }}" InstanceType: "t2.micro" register: _create_with_tags_idempotency @@ -56,15 +93,30 @@ - _templates.launch_templates[0].tags.InstanceType == "t2.micro" - _templates.launch_templates[0].tags.ResourcePrefix == resource_prefix - _templates.launch_templates[0].versions | length == 1 + - _templates.launch_templates[0].versions[0].launch_template_data.tag_specifications | length == 2 + - instance_tags.tags == launch_template_instance_tags + - network_interface_tags.tags == launch_template_network_tags + vars: + instance_tags: "{{ _templates.launch_templates[0].versions[0].launch_template_data.tag_specifications | selectattr('resource_type', 'equalto', 'instance') | list | first }}" + network_interface_tags: "{{ _templates.launch_templates[0].versions[0].launch_template_data.tag_specifications | selectattr('resource_type', 'equalto', 'network-interface') | list | first }}" # Add new tag - name: Add new tag with purge_tags=false community.aws.ec2_launch_template: name: "{{ test_launch_template_name }}" instance_type: t2.micro - template_tags: + network_interfaces: + - associate_public_ip_address: false + delete_on_termination: true + device_index: 0 + tag_specifications: + - resource_type: instance + tags: "{{ ansible_instance_tags }}" + - resource_type: network-interface + tags: "{{ ansible_network_tags }}" + tags: Phase: integration - purge_template_tags: false + purge_tags: false register: _add_tag - name: Retrieve Launch template information @@ -85,15 +137,22 @@ - _templates.launch_templates[0].tags.ResourcePrefix == resource_prefix - _templates.launch_templates[0].tags.Phase == "integration" - _templates.launch_templates[0].versions | length == 1 + - _templates.launch_templates[0].versions[0].launch_template_data.tag_specifications | length == 2 + - instance_tags.tags == launch_template_instance_tags + - network_interface_tags.tags == launch_template_network_tags + vars: + instance_tags: "{{ _templates.launch_templates[0].versions[0].launch_template_data.tag_specifications | selectattr('resource_type', 'equalto', 'instance') | list | first }}" + network_interface_tags: "{{ _templates.launch_templates[0].versions[0].launch_template_data.tag_specifications | selectattr('resource_type', 'equalto', 'network-interface') | list | first }}" # Add new launch template version and update tags - name: Add new launch template version and update tags community.aws.ec2_launch_template: name: "{{ test_launch_template_name }}" instance_type: t3.micro - template_tags: + tags: Team: Ansible - purge_template_tags: true + purge_tags: true + source_version: "" register: _add_tag_and_version - name: Retrieve Launch template information @@ -116,14 +175,17 @@ - '"Phase" not in _templates.launch_templates[0].tags' - _templates.launch_templates[0].tags.Team == "Ansible" - _templates.launch_templates[0].versions | length == 2 + - '"tag_specifications" not in latest_version_template_data.launch_template_data' + vars: + latest_version_template_data: '{{ _templates.launch_templates[0].versions | selectattr("version_number", "equalto", 2) | list | first }}' # Purge tags - name: Purge all tags from launch template community.aws.ec2_launch_template: name: "{{ test_launch_template_name }}" instance_type: t3.micro - template_tags: {} - purge_template_tags: true + tags: {} + purge_tags: true register: _purge_tags - name: Retrieve Launch template information @@ -136,8 +198,7 @@ ansible.builtin.assert: that: - _purge_tags is changed - - '"tags" in _purge_tags.template' - - _purge_tags.template.tags == {} + - '"tags" not in _purge_tags.template' - _templates.launch_templates[0].tags == {} - _templates.launch_templates[0].versions | length == 2