Repository: ansible-collections/amazon.aws

Issue:
Create instance ignoring specified availability_zone
### Summary

I'm trying to create a new instance in a specified availability zone; however, for some reason it is always being created in zone a instead of whatever I specify. 

### Issue Type

Bug Report

### Component Name

ec2_instance

### Ansible Version

```console (paste below)
$ ansible --version
ansible [core 2.13.3]
  config file = /Users/josh/Code/server/ansible.cfg
  configured module search path = ['/Users/josh/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /opt/homebrew/lib/python3.10/site-packages/ansible
  ansible collection location = /Users/josh/.ansible/collections:/usr/share/ansible/collections
  executable location = /opt/homebrew/bin/ansible
  python version = 3.10.6 (main, Aug 30 2022, 04:58:14) [Clang 13.1.6 (clang-1316.0.21.2.5)]
  jinja version = 3.1.2
  libyaml = True
```


### Collection Versions

```console (paste below)
$ ansible-galaxy collection list
Collection                    Version
----------------------------- -------
amazon.aws                    3.4.0  
ansible.netcommon             3.1.0  
ansible.posix                 1.4.0  
ansible.utils                 2.6.1  
ansible.windows               1.11.0 
arista.eos                    5.0.1  
awx.awx                       21.4.0 
azure.azcollection            1.13.0 
check_point.mgmt              2.3.0  
chocolatey.chocolatey         1.3.0  
cisco.aci                     2.2.0  
cisco.asa                     3.1.0  
cisco.dnac                    6.5.3  
cisco.intersight              1.0.19 
cisco.ios                     3.3.0  
cisco.iosxr                   3.3.0  
cisco.ise                     2.5.0  
cisco.meraki                  2.10.1 
cisco.mso                     2.0.0  
cisco.nso                     1.0.3  
cisco.nxos                    3.1.0  
cisco.ucs                     1.8.0  
cloud.common                  2.1.2  
cloudscale_ch.cloud           2.2.2  
community.aws                 3.5.0  
community.azure               1.1.0  
community.ciscosmb            1.0.5  
community.crypto              2.5.0  
community.digitalocean        1.21.0 
community.dns                 2.3.1  
community.docker              2.7.1  
community.fortios             1.0.0  
community.general             5.5.0  
community.google              1.0.0  
community.grafana             1.5.2  
community.hashi_vault         3.2.0  
community.hrobot              1.5.2  
community.libvirt             1.2.0  
community.mongodb             1.4.2  
community.mysql               3.4.0  
community.network             4.0.1  
community.okd                 2.2.0  
community.postgresql          2.2.0  
community.proxysql            1.4.0  
community.rabbitmq            1.2.2  
community.routeros            2.2.1  
community.sap                 1.0.0  
community.sap_libs            1.2.0  
community.skydive             1.0.0  
community.sops                1.3.0  
community.vmware              2.8.0  
community.windows             1.11.0 
community.zabbix              1.8.0  
containers.podman             1.9.4  
cyberark.conjur               1.1.0  
cyberark.pas                  1.0.14 
dellemc.enterprise_sonic      1.1.1  
dellemc.openmanage            5.5.0  
dellemc.os10                  1.1.1  
dellemc.os6                   1.0.7  
dellemc.os9                   1.0.4  
f5networks.f5_modules         1.19.0 
fortinet.fortimanager         2.1.5  
fortinet.fortios              2.1.7  
frr.frr                       2.0.0  
gluster.gluster               1.0.2  
google.cloud                  1.0.2  
hetzner.hcloud                1.8.1  
hpe.nimble                    1.1.4  
ibm.qradar                    2.0.0  
ibm.spectrum_virtualize       1.9.0  
infinidat.infinibox           1.3.3  
infoblox.nios_modules         1.3.0  
inspur.sm                     2.0.0  
junipernetworks.junos         3.1.0  
kubernetes.core               2.3.2  
mellanox.onyx                 1.0.0  
netapp.aws                    21.7.0 
netapp.azure                  21.10.0
netapp.cloudmanager           21.19.0
netapp.elementsw              21.7.0 
netapp.ontap                  21.22.0
netapp.storagegrid            21.10.0
netapp.um_info                21.8.0 
netapp_eseries.santricity     1.3.1  
netbox.netbox                 3.7.1  
ngine_io.cloudstack           2.2.4  
ngine_io.exoscale             1.0.0  
ngine_io.vultr                1.1.2  
openstack.cloud               1.8.0  
openvswitch.openvswitch       2.1.0  
ovirt.ovirt                   2.2.3  
purestorage.flasharray        1.13.0 
purestorage.flashblade        1.9.0  
purestorage.fusion            1.0.2  
sensu.sensu_go                1.13.1 
servicenow.servicenow         1.0.6  
splunk.es                     2.0.0  
t_systems_mms.icinga_director 1.31.0 
theforeman.foreman            3.4.0  
vmware.vmware_rest            2.2.0  
vyos.vyos                     3.0.1  
wti.remote                    1.0.4  
```


### AWS SDK versions

```console (paste below)
$ pip show boto boto3 botocore
WARNING: Package(s) not found: boto
Name: boto3
Version: 1.24.70
Summary: The AWS SDK for Python
Home-page: https://github.com/boto/boto3
Author: Amazon Web Services
Author-email: 
License: Apache License 2.0
Location: /opt/homebrew/lib/python3.10/site-packages
Requires: botocore, jmespath, s3transfer
Required-by: 
---
Name: botocore
Version: 1.27.70
Summary: Low-level, data-driven core of boto 3.
Home-page: https://github.com/boto/botocore
Author: Amazon Web Services
Author-email: 
License: Apache License 2.0
Location: /opt/homebrew/lib/python3.10/site-packages
Requires: jmespath, python-dateutil, urllib3
```


### Configuration

```console (paste below)
$ ansible-config dump --only-changed
DEFAULT_HOST_LIST(/Users/josh/Code/server/ansible.cfg) = ['/Users/josh/Code/server/ansible/inventory_aws_ec2.yml']
DISPLAY_SKIPPED_HOSTS(/Users/josh/Code/server/ansible.cfg) = False
HOST_KEY_CHECKING(/Users/josh/Code/server/ansible.cfg) = False
INTERPRETER_PYTHON(/Users/josh/Code/server/ansible.cfg) = python
```


### OS / Environment

macOS 12.5

### Steps to Reproduce

<!--- Paste example playbooks or commands between quotes below -->
```yaml (paste below)
- name: Create new instance
  register: create_instance_result
  amazon.aws.ec2_instance:
    key_name: install
    launch_template:
      name: mytemplate
    instance_role: "{{ ('test' in NAME) | ternary('test-perms', 'prod-perms') }}"
    security_group: my-sg
    region: "{{ REGION }}"
    availability_zone: "{{ ZONE }}"
    tags:
      Name: "{{ NAME }}"
      type: new
    network:
      assign_public_ip: yes
  failed_when:
    - not create_instance_result.changed

------------------------------------------------------------------------------------------------
$ ansible-playbook ansible/create_new_instance.yml -vvv -e 'NAME=ansible-zone-test-7 REGION=us-west-2 ZONE=us-west-2b'
```


### Expected Results

I expect a new instance to be created (it is) with the specified availability zone (it is not).

### Actual Results

```console (paste below)
ansible-playbook [core 2.13.3]
  config file = /Users/josh/Code/server/ansible.cfg
  configured module search path = ['/Users/josh/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /opt/homebrew/lib/python3.10/site-packages/ansible
  ansible collection location = /Users/josh/.ansible/collections:/usr/share/ansible/collections
  executable location = /opt/homebrew/bin/ansible-playbook
  python version = 3.10.6 (main, Aug 30 2022, 04:58:14) [Clang 13.1.6 (clang-1316.0.21.2.5)]
  jinja version = 3.1.2
  libyaml = True
Using /Users/josh/Code/server/ansible.cfg as config file
host_list declined parsing /Users/josh/Code/server/ansible/inventory_aws_ec2.yml as it did not pass its verify_file() method
script declined parsing /Users/josh/Code/server/ansible/inventory_aws_ec2.yml as it did not pass its verify_file() method
Using inventory plugin 'ansible_collections.amazon.aws.plugins.inventory.aws_ec2' to process inventory source '/Users/josh/Code/server/ansible/inventory_aws_ec2.yml'
Parsed /Users/josh/Code/server/ansible/inventory_aws_ec2.yml inventory source with auto plugin
redirecting (type: modules) ansible.builtin.authorized_key to ansible.posix.authorized_key
redirecting (type: modules) ansible.builtin.git_config to community.general.git_config
redirecting (type: modules) community.general.git_config to community.general.source_control.git_config
redirecting (type: modules) ansible.builtin.make to community.general.make
redirecting (type: modules) community.general.make to community.general.system.make
redirecting (type: modules) ansible.builtin.make to community.general.make
redirecting (type: modules) community.general.make to community.general.system.make
Skipping callback 'default', as we already have a stdout callback.
Skipping callback 'minimal', as we already have a stdout callback.
Skipping callback 'oneline', as we already have a stdout callback.

PLAYBOOK: create_new_instance.yml ******************************************************************************************************************************************************************************
4 plays in ansible/create_new_instance.yml

PLAY [localhost] ***********************************************************************************************************************************************************************************************
META: ran handlers
<127.0.0.1> ESTABLISH LOCAL CONNECTION FOR USER: josh
<127.0.0.1> EXEC /bin/sh -c 'echo ~josh && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /Users/josh/.ansible/tmp `"&& mkdir "` echo /Users/josh/.ansible/tmp/ansible-tmp-1664993396.826973-4005-260448881352299 `" && echo ansible-tmp-1664993396.826973-4005-260448881352299="` echo /Users/josh/.ansible/tmp/ansible-tmp-1664993396.826973-4005-260448881352299 `" ) && sleep 0'
Using module file /opt/homebrew/lib/python3.10/site-packages/ansible_collections/amazon/aws/plugins/modules/ec2_instance.py
<127.0.0.1> PUT /Users/josh/.ansible/tmp/ansible-local-4000mo_9bxcp/tmptflegebu TO /Users/josh/.ansible/tmp/ansible-tmp-1664993396.826973-4005-260448881352299/AnsiballZ_ec2_instance.py
<127.0.0.1> EXEC /bin/sh -c 'chmod u+x /Users/josh/.ansible/tmp/ansible-tmp-1664993396.826973-4005-260448881352299/ /Users/josh/.ansible/tmp/ansible-tmp-1664993396.826973-4005-260448881352299/AnsiballZ_ec2_instance.py && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '/opt/homebrew/opt/python@3.10/bin/python3.10 /Users/josh/.ansible/tmp/ansible-tmp-1664993396.826973-4005-260448881352299/AnsiballZ_ec2_instance.py && sleep 0'
<127.0.0.1> EXEC /bin/sh -c 'rm -f -r /Users/josh/.ansible/tmp/ansible-tmp-1664993396.826973-4005-260448881352299/ > /dev/null 2>&1 && sleep 0'

TASK [create_new_instance : Create new instance] **********************************************************************************************************************************************************
task path: /Users/josh/Code/server/ansible/roles/create_new_instance/tasks/main.yml:1
changed: [localhost] => {
    "changed": true,
    "failed_when_result": false,
    "instance_ids": [
        "i-0914a7023bf71da1a"
    ],
    "instances": [
        {
            "ami_launch_index": 0,
            "architecture": "x86_64",
            "block_device_mappings": [
                {
                    "device_name": "/dev/xvda",
                    "ebs": {
                        "attach_time": "2022-10-05T18:10:00+00:00",
                        "delete_on_termination": true,
                        "status": "attaching",
                        "volume_id": "vol-0914621599da17bce"
                    }
                }
            ],
            "capacity_reservation_specification": {
                "capacity_reservation_preference": "open"
            },
            "client_token": "76256d2410e945519962839503147607",
            "cpu_options": {
                "core_count": 2,
                "threads_per_core": 1
            },
            "ebs_optimized": false,
            "ena_support": true,
            "enclave_options": {
                "enabled": false
            },
            "hibernation_options": {
                "configured": false
            },
            "hypervisor": "xen",
            "iam_instance_profile": {
                "arn": "arn:aws:iam::356247613230:instance-profile/prod-perms",
                "id": "AIPAVF4QDF4XOCVFXNHHM"
            },
            "image_id": "ami-0f38a8f9158f42fef",
            "instance_id": "i-0914a7023bf71da1a",
            "instance_type": "t2.medium",
            "key_name": "install",
            "launch_time": "2022-10-05T18:09:59+00:00",
            "maintenance_options": {
                "auto_recovery": "default"
            },
            "metadata_options": {
                "http_endpoint": "enabled",
                "http_protocol_ipv6": "disabled",
                "http_put_response_hop_limit": 1,
                "http_tokens": "optional",
                "instance_metadata_tags": "disabled",
                "state": "pending"
            },
            "monitoring": {
                "state": "disabled"
            },
            "network_interfaces": [
                {
                    "attachment": {
                        "attach_time": "2022-10-05T18:09:59+00:00",
                        "attachment_id": "eni-attach-09bcb69e84b51494b",
                        "delete_on_termination": true,
                        "device_index": 0,
                        "network_card_index": 0,
                        "status": "attaching"
                    },
                    "description": "",
                    "groups": [
                        {
                            "group_id": "sg-040a7b0bb9115482e",
                            "group_name": "my-sg"
                        }
                    ],
                    "interface_type": "interface",
                    "ipv6_addresses": [],
                    "mac_address": "02:9d:6c:46:47:ab",
                    "network_interface_id": "eni-0855a013919dcbb43",
                    "owner_id": "356247613230",
                    "private_dns_name": "ip-172-31-20-79.us-west-2.compute.internal",
                    "private_ip_address": "172.31.20.79",
                    "private_ip_addresses": [
                        {
                            "primary": true,
                            "private_dns_name": "ip-172-31-20-79.us-west-2.compute.internal",
                            "private_ip_address": "172.31.20.79"
                        }
                    ],
                    "source_dest_check": true,
                    "status": "in-use",
                    "subnet_id": "subnet-2ec4dd57",
                    "vpc_id": "vpc-bc21adc4"
                }
            ],
            "placement": {
                "availability_zone": "us-west-2a",
                "group_name": "",
                "tenancy": "default"
            },
            "platform_details": "Linux/UNIX",
            "private_dns_name": "ip-172-31-20-79.us-west-2.compute.internal",
            "private_dns_name_options": {
                "enable_resource_name_dns_a_record": true,
                "enable_resource_name_dns_aaaa_record": false,
                "hostname_type": "ip-name"
            },
            "private_ip_address": "172.31.20.79",
            "product_codes": [],
            "public_dns_name": "",
            "root_device_name": "/dev/xvda",
            "root_device_type": "ebs",
            "security_groups": [
                {
                    "group_id": "sg-040a7b0bb9115482e",
                    "group_name": "my-sg"
                }
            ],
            "source_dest_check": true,
            "state": {
                "code": 0,
                "name": "pending"
            },
            "state_transition_reason": "",
            "subnet_id": "subnet-2ec4dd57",
            "tags": {
                "Name": "ansible-zone-test-7",
                "aws:ec2launchtemplate:id": "lt-09f2247bbae9501c3",
                "aws:ec2launchtemplate:version": "6",
                "type": "new"
            },
            "usage_operation": "RunInstances",
            "usage_operation_update_time": "2022-10-05T18:09:59+00:00",
            "virtualization_type": "hvm",
            "vpc_id": "vpc-bc21adc4"
        }
    ],
    "invocation": {
        "module_args": {
            "availability_zone": "us-west-2b",
            "aws_access_key": null,
            "aws_ca_bundle": null,
            "aws_config": null,
            "aws_secret_key": null,
            "count": null,
            "cpu_credit_specification": null,
            "cpu_options": null,
            "debug_botocore_endpoint_logs": false,
            "detailed_monitoring": null,
            "ebs_optimized": null,
            "ec2_url": null,
            "exact_count": null,
            "filters": {
                "instance-state-name": [
                    "pending",
                    "running",
                    "stopping",
                    "stopped"
                ],
                "tag:Name": [
                    "ansible-zone-test-7"
                ]
            },
            "image": null,
            "image_id": null,
            "instance_ids": [],
            "instance_initiated_shutdown_behavior": null,
            "instance_role": "prod-perms",
            "instance_type": null,
            "key_name": "install",
            "launch_template": {
                "name": "mytemplate"
            },
            "metadata_options": null,
            "name": null,
            "network": {
                "assign_public_ip": true
            },
            "placement_group": null,
            "profile": null,
            "purge_tags": false,
            "region": "us-west-2",
            "security_group": "my-sg",
            "security_groups": [],
            "security_token": null,
            "state": "present",
            "tags": {
                "Name": "ansible-zone-test-7",
                "type": "new"
            },
            "tenancy": null,
            "termination_protection": null,
            "tower_callback": null,
            "user_data": null,
            "validate_certs": true,
            "volumes": null,
            "vpc_subnet_id": null,
            "wait": true,
            "wait_timeout": 600
        }
    },
    "spec": {
        "BlockDeviceMappings": [],
        "ClientToken": "76256d2410e945519962839503147607",
        "IamInstanceProfile": {
            "Arn": "arn:aws:iam::356247613230:instance-profile/prod-perms"
        },
        "KeyName": "install",
        "LaunchTemplate": {
            "LaunchTemplateName": "mytemplate"
        },
        "MaxCount": 1,
        "MinCount": 1,
        "NetworkInterfaces": [
            {
                "AssociatePublicIpAddress": true,
                "DeviceIndex": 0,
                "Groups": [
                    "sg-040a7b0bb9115482e"
                ],
                "SubnetId": "subnet-2ec4dd57"
            }
        ],
        "TagSpecifications": [
            {
                "ResourceType": "volume",
                "Tags": [
                    {
                        "Key": "Name",
                        "Value": "ansible-zone-test-7"
                    },
                    {
                        "Key": "type",
                        "Value": "new"
                    }
                ]
            },
            {
                "ResourceType": "instance",
                "Tags": [
                    {
                        "Key": "Name",
                        "Value": "ansible-zone-test-7"
                    },
                    {
                        "Key": "type",
                        "Value": "new"
                    }
                ]
            }
        ]
    }
}
```


### Code of Conduct

- [X] I agree to follow the Ansible Code of Conduct


Discussion:
Files identified in the description:
* [`plugins/modules/ec2_instance.py`](https://github.com/['ansible-collections/amazon.aws', 'ansible-collections/community.aws', 'ansible-collections/community.vmware']/blob/main/plugins/modules/ec2_instance.py)

If these files are inaccurate, please update the `component name` section of the description or use the `!component` bot command.

[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: components_banner --->
cc @jillr @ryansb @s-hertel @tremble
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: notify --->
The following aws cli command, which I believe is equivalent to what I'm trying to achieve here, works as expected:
```
$ aws ec2 run-instances --key-name install --launch-template '{"LaunchTemplateName": "mytemplate"}' --iam-instance-profile '{"Name": "prod-perms"}' --region us-west-2 --placement '{"AvailabilityZone": "us-west-2c"}' --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=cli-test}, {Key=type,Value=new}]' --associate-public-ip-address
```

So this makes me think this is an issue with ansible, not something with aws
Hi @kennedyjosh, @mandar242's PR https://github.com/ansible-collections/amazon.aws/pull/1150 should resolve the problem. Can you give it a try?

Resolving patch:
diff --git a/plugins/modules/ec2_instance.py b/plugins/modules/ec2_instance.py
--- a/plugins/modules/ec2_instance.py
+++ b/plugins/modules/ec2_instance.py
@@ -1126,7 +1126,7 @@ def build_network_spec(params):
                 module.fail_json(
                     msg="No default subnet could be found - you must include a VPC subnet ID (vpc_subnet_id parameter) to create an instance")
             else:
-                sub = get_default_subnet(default_vpc)
+                sub = get_default_subnet(default_vpc, availability_zone=module.params.get('availability_zone'))
                 spec['SubnetId'] = sub['SubnetId']
 
         if network.get('private_ip_address'):


Test patch:
diff --git a/tests/integration/targets/ec2_instance_instance_minimal/tasks/main.yml b/tests/integration/targets/ec2_instance_instance_minimal/tasks/main.yml
--- a/tests/integration/targets/ec2_instance_instance_minimal/tasks/main.yml
+++ b/tests/integration/targets/ec2_instance_instance_minimal/tasks/main.yml
@@ -264,6 +264,74 @@
       - create_instance_tag.instance_ids | length == 1
       - create_instance_tag.instance_ids[0] == create_instance_id_tag
 
+###############################################################
+
+  - name: "Create a new instance in AZ {{ aws_region }}a"
+    ec2_instance:
+      state: present
+      name: "{{ resource_prefix }}-test-basic-{{ aws_region }}a"
+      instance_type: "{{ ec2_instance_type }}"
+      image_id: "{{ ec2_ami_id }}"
+      region: "{{ aws_region }}"
+      availability_zone: "{{ aws_region }}a"
+      tags:
+        TestId: "{{ ec2_instance_tag_TestId }}"
+      wait: true
+    register: create_instance
+
+  - name: "Save instance ID"
+    set_fact:
+      create_instance_id_3: "{{ create_instance.instance_ids[0] }}"
+
+  - name: Get instance info
+    ec2_instance_info:
+      instance_ids:
+        - "{{ create_instance_id_3 }}"
+    register: info_result
+
+  - assert:
+      that:
+      - create_instance is not failed
+      - create_instance is changed
+      - '"ec2:RunInstances" in create_instance.resource_actions'
+      - '"instance_ids" in create_instance'
+      - create_instance.instance_ids | length == 1
+      - create_instance.instance_ids[0].startswith("i-")
+      - info_result.instances[0].placement.availability_zone == '{{ aws_region }}a'
+
+  - name: "Create a new instance in AZ {{ aws_region }}b"
+    ec2_instance:
+      state: present
+      name: "{{ resource_prefix }}-test-basic-{{ aws_region }}b"
+      instance_type: "{{ ec2_instance_type }}"
+      image_id: "{{ ec2_ami_id }}"
+      region: "{{ aws_region }}"
+      availability_zone: "{{ aws_region }}b"
+      tags:
+        TestId: "{{ ec2_instance_tag_TestId }}"
+      wait: true
+    register: create_instance
+
+  - name: "Save instance ID"
+    set_fact:
+      create_instance_id_4: "{{ create_instance.instance_ids[0] }}"
+
+  - name: Get instance info
+    ec2_instance_info:
+      instance_ids:
+        - "{{ create_instance_id_4 }}"
+    register: info_result
+
+  - assert:
+      that:
+      - create_instance is not failed
+      - create_instance is changed
+      - '"ec2:RunInstances" in create_instance.resource_actions'
+      - '"instance_ids" in create_instance'
+      - create_instance.instance_ids | length == 1
+      - create_instance.instance_ids[0].startswith("i-")
+      - info_result.instances[0].placement.availability_zone == '{{ aws_region }}b'
+
 ################################################################
 
   - name: "Terminate instance based on name parameter (check_mode)"
@@ -481,3 +549,151 @@
       - '"ec2:TerminateInstances" not in terminate_id.resource_actions'
       - '"terminate_failed" not in terminate_id'
       - '"terminate_success" not in terminate_id'
+
+################################################################
+
+  - name: "Terminate instance based on id (check_mode)"
+    ec2_instance:
+      state: absent
+      instance_ids:
+      - "{{ create_instance_id_3 }}"
+      wait: true
+    register: terminate_id
+    check_mode: true
+
+  - assert:
+      that:
+      - terminate_id is not failed
+      - terminate_id is changed
+      - '"ec2:TerminateInstances" not in terminate_id.resource_actions'
+      - '"terminate_failed" in terminate_id'
+      - '"terminate_success" in terminate_id'
+      - terminate_id.terminate_failed | length == 0
+      - terminate_id.terminate_success | length == 1
+      - terminate_id.terminate_success[0] == create_instance_id_3
+
+  - name: "Terminate instance based on id"
+    ec2_instance:
+      state: absent
+      instance_ids:
+      - "{{ create_instance_id_3 }}"
+      wait: true
+    register: terminate_id
+
+  - assert:
+      that:
+      - terminate_id is not failed
+      - terminate_id is changed
+      - '"ec2:TerminateInstances" in terminate_id.resource_actions'
+      - '"terminate_failed" in terminate_id'
+      - '"terminate_success" in terminate_id'
+      - terminate_id.terminate_failed | length == 0
+      - terminate_id.terminate_success | length == 1
+      - terminate_id.terminate_success[0] == create_instance_id_3
+
+  - name: "Terminate instance based on id - idempotency (check_mode)"
+    ec2_instance:
+      state: absent
+      instance_ids:
+      - "{{ create_instance_id_3 }}"
+      wait: true
+    register: terminate_id
+    check_mode: true
+
+  - assert:
+      that:
+      - terminate_id is not failed
+      - terminate_id is not changed
+      - '"ec2:TerminateInstances" not in terminate_id.resource_actions'
+      - '"terminate_failed" not in terminate_id'
+      - '"terminate_success" not in terminate_id'
+
+  - name: "Terminate instance based on id - idempotency"
+    ec2_instance:
+      state: absent
+      instance_ids:
+      - "{{ create_instance_id_3 }}"
+      wait: true
+    register: terminate_id
+
+  - assert:
+      that:
+      - terminate_id is not failed
+      - terminate_id is not changed
+      - '"ec2:TerminateInstances" not in terminate_id.resource_actions'
+      - '"terminate_failed" not in terminate_id'
+      - '"terminate_success" not in terminate_id'
+
+################################################################
+
+  - name: "Terminate instance based on id (check_mode)"
+    ec2_instance:
+      state: absent
+      instance_ids:
+      - "{{ create_instance_id_4 }}"
+      wait: true
+    register: terminate_id
+    check_mode: true
+
+  - assert:
+      that:
+      - terminate_id is not failed
+      - terminate_id is changed
+      - '"ec2:TerminateInstances" not in terminate_id.resource_actions'
+      - '"terminate_failed" in terminate_id'
+      - '"terminate_success" in terminate_id'
+      - terminate_id.terminate_failed | length == 0
+      - terminate_id.terminate_success | length == 1
+      - terminate_id.terminate_success[0] == create_instance_id_4
+
+  - name: "Terminate instance based on id"
+    ec2_instance:
+      state: absent
+      instance_ids:
+      - "{{ create_instance_id_4 }}"
+      wait: true
+    register: terminate_id
+
+  - assert:
+      that:
+      - terminate_id is not failed
+      - terminate_id is changed
+      - '"ec2:TerminateInstances" in terminate_id.resource_actions'
+      - '"terminate_failed" in terminate_id'
+      - '"terminate_success" in terminate_id'
+      - terminate_id.terminate_failed | length == 0
+      - terminate_id.terminate_success | length == 1
+      - terminate_id.terminate_success[0] == create_instance_id_4
+
+  - name: "Terminate instance based on id - idempotency (check_mode)"
+    ec2_instance:
+      state: absent
+      instance_ids:
+      - "{{ create_instance_id_4 }}"
+      wait: true
+    register: terminate_id
+    check_mode: true
+
+  - assert:
+      that:
+      - terminate_id is not failed
+      - terminate_id is not changed
+      - '"ec2:TerminateInstances" not in terminate_id.resource_actions'
+      - '"terminate_failed" not in terminate_id'
+      - '"terminate_success" not in terminate_id'
+
+  - name: "Terminate instance based on id - idempotency"
+    ec2_instance:
+      state: absent
+      instance_ids:
+      - "{{ create_instance_id_4 }}"
+      wait: true
+    register: terminate_id
+
+  - assert:
+      that:
+      - terminate_id is not failed
+      - terminate_id is not changed
+      - '"ec2:TerminateInstances" not in terminate_id.resource_actions'
+      - '"terminate_failed" not in terminate_id'
+      - '"terminate_success" not in terminate_id'