From 6dd4c312013f916fedc2aa01addee25728d3b28c Mon Sep 17 00:00:00 2001 From: Joseph Torcasso <87090265+jatorcasso@users.noreply.github.com> Date: Thu, 2 Jun 2022 03:58:28 -0400 Subject: [PATCH] ec2_instance - Fix NoneType error on no input tags (#856) ec2_instance - Fix NoneType error on no input tags SUMMARY Reverts bug introduced in #849 which throws a NoneType exception when tags are not input ISSUE TYPE Bugfix Pull Request COMPONENT NAME ec2_instance ADDITIONAL INFORMATION The error gets thrown when trying to wrap dict(None). See https://ansible.softwarefactory-project.io/zuul/build/5e37b5947f7045c6bf01e88f8ae5271f TASK [elb_classic_lb : Wait for instance a] ************************************ task path: /home/zuul/.ansible/collections/ansible_collections/amazon/aws/tests/integration/targets/elb_classic_lb/tasks/simple_instances.yml:18 Using module file /home/zuul/.ansible/collections/ansible_collections/amazon/aws/plugins/modules/ec2_instance.py Pipelining is enabled. ESTABLISH LOCAL CONNECTION FOR USER: zuul EXEC /bin/sh -c 'ANSIBLE_DEBUG_BOTOCORE_LOGS=True /home/zuul/venv/bin/python && sleep 0' The full traceback is: Traceback (most recent call last): File "", line 121, in File "", line 113, in _ansiballz_main File "", line 61, in invoke_module File "/usr/lib64/python3.8/runpy.py", line 207, in run_module return _run_module_code(code, init_globals, run_name, mod_spec) File "/usr/lib64/python3.8/runpy.py", line 97, in _run_module_code _run_code(code, mod_globals, init_globals, File "/usr/lib64/python3.8/runpy.py", line 87, in _run_code exec(code, run_globals) File "/tmp/ansible_ec2_instance_payload_ofa2yzhm/ansible_ec2_instance_payload.zip/ansible_collections/amazon/aws/plugins/modules/ec2_instance.py", line 2105, in File "/tmp/ansible_ec2_instance_payload_ofa2yzhm/ansible_ec2_instance_payload.zip/ansible_collections/amazon/aws/plugins/modules/ec2_instance.py", line 2097, in main File "/tmp/ansible_ec2_instance_payload_ofa2yzhm/ansible_ec2_instance_payload.zip/ansible_collections/amazon/aws/plugins/modules/ec2_instance.py", line 1783, in handle_existing TypeError: 'NoneType' object is not iterable fatal: [testhost]: FAILED! => { "changed": false, "module_stderr": "Traceback (most recent call last):\n File \"\", line 121, in \n File \"\", line 113, in _ansiballz_main\n File \"\", line 61, in invoke_module\n File \"/usr/lib64/python3.8/runpy.py\", line 207, in run_module\n return _run_module_code(code, init_globals, run_name, mod_spec)\n File \"/usr/lib64/python3.8/runpy.py\", line 97, in _run_module_code\n _run_code(code, mod_globals, init_globals,\n File \"/usr/lib64/python3.8/runpy.py\", line 87, in _run_code\n exec(code, run_globals)\n File \"/tmp/ansible_ec2_instance_payload_ofa2yzhm/ansible_ec2_instance_payload.zip/ansible_collections/amazon/aws/plugins/modules/ec2_instance.py\", line 2105, in \n File \"/tmp/ansible_ec2_instance_payload_ofa2yzhm/ansible_ec2_instance_payload.zip/ansible_collections/amazon/aws/plugins/modules/ec2_instance.py\", line 2097, in main\n File \"/tmp/ansible_ec2_instance_payload_ofa2yzhm/ansible_ec2_instance_payload.zip/ansible_collections/amazon/aws/plugins/modules/ec2_instance.py\", line 1783, in handle_existing\nTypeError: 'NoneType' object is not iterable\n", "module_stdout": "", "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error", "rc": 1 } Reviewed-by: Mark Chappell Reviewed-by: Joseph Torcasso --- plugins/modules/ec2_instance.py | 4 +-- .../tasks/tags_and_vpc_settings.yml | 36 ++++++++++++++++++- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/plugins/modules/ec2_instance.py b/plugins/modules/ec2_instance.py index 2bc65d9a729..efca90e5740 100644 --- a/plugins/modules/ec2_instance.py +++ b/plugins/modules/ec2_instance.py @@ -1780,7 +1780,7 @@ def determine_iam_role(name_or_arn): def handle_existing(existing_matches, state): - tags = dict(module.params.get('tags', None)) + tags = module.params.get('tags') purge_tags = module.params.get('purge_tags') name = module.params.get('name') @@ -1788,7 +1788,7 @@ def handle_existing(existing_matches, state): # into tags, but since tags isn't explicitly passed we'll treat it not being # set as purge_tags == False if name: - if purge_tags and tags is None: + if tags is None: purge_tags = False tags = {} tags.update({'Name': name}) diff --git a/tests/integration/targets/ec2_instance/roles/ec2_instance/tasks/tags_and_vpc_settings.yml b/tests/integration/targets/ec2_instance/roles/ec2_instance/tasks/tags_and_vpc_settings.yml index 04ecd22a241..a81e0040b42 100644 --- a/tests/integration/targets/ec2_instance/roles/ec2_instance/tasks/tags_and_vpc_settings.yml +++ b/tests/integration/targets/ec2_instance/roles/ec2_instance/tasks/tags_and_vpc_settings.yml @@ -138,11 +138,45 @@ - check_tags.instances[0].tags.Name.startswith(resource_prefix) - "'{{ check_tags.instances[0].state.name }}' in ['pending', 'running']" + - name: "Try setting purge_tags to True without specifiying tags (should NOT purge tags)" + ec2_instance: + state: present + name: "{{ resource_prefix }}-test-basic-vpc-create" + image_id: "{{ ec2_ami_id }}" + purge_tags: true + security_groups: "{{ sg.group_id }}" + vpc_subnet_id: "{{ testing_subnet_b.subnet.id }}" + instance_type: "{{ ec2_instance_type }}" + register: _purge_tags_without_tags + + - name: Assert tags were not purged + assert: + that: + - _purge_tags_without_tags.instances[0].tags | length > 1 + + - name: "Purge all tags (aside from Name)" + ec2_instance: + state: present + name: "{{ resource_prefix }}-test-basic-vpc-create" + image_id: "{{ ec2_ami_id }}" + purge_tags: true + tags: {} + security_groups: "{{ sg.group_id }}" + vpc_subnet_id: "{{ testing_subnet_b.subnet.id }}" + instance_type: "{{ ec2_instance_type }}" + register: _purge_tags + + - name: Assert tags were purged + assert: + that: + - _purge_tags.instances[0].tags | length == 1 + - _purge_tags.instances[0].tags.Name.startswith(resource_prefix) + - name: "Terminate instance" ec2_instance: state: absent filters: - "tag:TestId": "{{ ec2_instance_tag_TestId }}" + "tag:Name": "{{ resource_prefix }}-test-basic-vpc-create" wait: false register: result - assert: