Repository: ansible-collections/community.aws

Issue:
UnboundLocalError in sqs_queue
<!--- Verify first that your issue is not already reported on GitHub -->
<!--- Also test if the latest release and devel branch are affected too -->
<!--- Complete *all* sections as described, this form is processed automatically -->

##### SUMMARY
Copied the "Create FIFO queue" example from documentation, and it fails to run with an UnboundLocalError.

##### ISSUE TYPE
- Bug Report

##### COMPONENT NAME
sqs_queue

##### ANSIBLE VERSION
<!--- Paste verbatim output from "ansible --version" between quotes -->
```
ansible 2.9.10
  config file = /home/mstudd/.ansible.cfg
  configured module search path = ['/home/mstudd/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3.8/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 3.8.3 (default, May 29 2020, 00:00:00) [GCC 10.1.1 20200507 (Red Hat 10.1.1-1)]
```

##### CONFIGURATION
<!--- Paste verbatim output from "ansible-config dump --only-changed" between quotes -->
```
DEFAULT_VAULT_IDENTITY_LIST(env: ANSIBLE_VAULT_IDENTITY_LIST) = ['ops@~/.vault/ops', 'dev@~/.vault/dev']
```

##### OS / ENVIRONMENT
Fedora 32 x86_64


##### STEPS TO REPRODUCE
<!--- Describe exactly how to reproduce the problem, using a minimal test-case -->

<!--- Paste example playbooks or commands between quotes below -->
```
---

- hosts: localhost
  tasks:
    - community.aws.sqs_queue:
        name: fifo-queue
        region: us-east-1
        queue_type: fifo
        content_based_deduplication: yes
```

<!--- HINT: You can paste gist.github.com links for larger files -->

##### EXPECTED RESULTS
ansible-playbook creates the SQS queue as described (or reports relevant auth error if AWS creds aren't correct).


##### ACTUAL RESULTS
<!--- Describe what actually happened. If possible run with extra verbosity (-vvvv) -->

<!--- Paste verbatim command output between quotes -->
```
  config file = /home/mstudd/dev/git/ansible/ansible.cfg
  configured module search path = ['/home/mstudd/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3.8/site-packages/ansible
  executable location = /usr/bin/ansible-playbook
  python version = 3.8.3 (default, May 29 2020, 00:00:00) [GCC 10.1.1 20200507 (Red Hat 10.1.1-1)]
Using /home/mstudd/dev/git/ansible/ansible.cfg as config file
setting up inventory plugins
host_list declined parsing /home/mstudd/dev/git/ansible/inventories/dev/hosts as it did not pass its verify_file() method
script declined parsing /home/mstudd/dev/git/ansible/inventories/dev/hosts as it did not pass its verify_file() method
auto declined parsing /home/mstudd/dev/git/ansible/inventories/dev/hosts as it did not pass its verify_file() method
Set default localhost to localhost
Parsed /home/mstudd/dev/git/ansible/inventories/dev/hosts inventory source with ini plugin
[WARNING]: Found both group and host with same name: api-charts
Loading callback plugin default of type stdout, v2.0 from /usr/lib/python3.8/site-packages/ansible/plugins/callback/default.py

PLAYBOOK: test.yml **********************************************************************************************************************************************************************************************************************************************************************************************************
Positional arguments: test.yml
verbosity: 4
connection: smart
timeout: 10
become_method: sudo
tags: ('all',)
inventory: ('/home/mstudd/dev/git/ansible/inventories/dev/hosts',)
forks: 5
1 plays in test.yml

PLAY [localhost] ************************************************************************************************************************************************************************************************************************************************************************************************************
Trying secret FileVaultSecret(filename='/home/mstudd/.vault/ops') for vault_id=ops
Tried to use the vault secret (ops) to decrypt (/home/mstudd/dev/git/ansible/inventories/dev/group_vars/all/secrets.yml) but it failed. Error: HMAC verification failed: Signature did not match digest.
Trying secret FileVaultSecret(filename='/home/mstudd/.vault/dev') for vault_id=dev

TASK [Gathering Facts] ******************************************************************************************************************************************************************************************************************************************************************************************************
task path: /home/mstudd/dev/git/ansible/test.yml:3
<localhost.dev> ESTABLISH LOCAL CONNECTION FOR USER: mstudd
<localhost.dev> EXEC /bin/sh -c 'echo ~mstudd && sleep 0'
<localhost.dev> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /home/mstudd/.ansible/tmp `"&& mkdir /home/mstudd/.ansible/tmp/ansible-tmp-1596227662.5343304-234250-22361424934479 && echo ansible-tmp-1596227662.5343304-234250-22361424934479="` echo /home/mstudd/.ansible/tmp/ansible-tmp-1596227662.5343304-234250-22361424934479 `" ) && sleep 0'
<localhost> Attempting python interpreter discovery
<localhost.dev> EXEC /bin/sh -c 'echo PLATFORM; uname; echo FOUND; command -v '"'"'/usr/bin/python'"'"'; command -v '"'"'python3.7'"'"'; command -v '"'"'python3.6'"'"'; command -v '"'"'python3.5'"'"'; command -v '"'"'python2.7'"'"'; command -v '"'"'python2.6'"'"'; command -v '"'"'/usr/libexec/platform-python'"'"'; command -v '"'"'/usr/bin/python3'"'"'; command -v '"'"'python'"'"'; echo ENDFOUND && sleep 0'
<localhost.dev> EXEC /bin/sh -c '/usr/bin/python && sleep 0'
Using module file /usr/lib/python3.8/site-packages/ansible/modules/system/setup.py
<localhost.dev> PUT /home/mstudd/.ansible/tmp/ansible-local-234246mzlywzby/tmphl8okmrr TO /home/mstudd/.ansible/tmp/ansible-tmp-1596227662.5343304-234250-22361424934479/AnsiballZ_setup.py
<localhost.dev> EXEC /bin/sh -c 'chmod u+x /home/mstudd/.ansible/tmp/ansible-tmp-1596227662.5343304-234250-22361424934479/ /home/mstudd/.ansible/tmp/ansible-tmp-1596227662.5343304-234250-22361424934479/AnsiballZ_setup.py && sleep 0'
<localhost.dev> EXEC /bin/sh -c '/usr/bin/python3 /home/mstudd/.ansible/tmp/ansible-tmp-1596227662.5343304-234250-22361424934479/AnsiballZ_setup.py && sleep 0'
<localhost.dev> EXEC /bin/sh -c 'rm -f -r /home/mstudd/.ansible/tmp/ansible-tmp-1596227662.5343304-234250-22361424934479/ > /dev/null 2>&1 && sleep 0'
ok: [localhost]
META: ran handlers

TASK [community.aws.sqs_queue] **********************************************************************************************************************************************************************************************************************************************************************************************
task path: /home/mstudd/dev/git/ansible/test.yml:5
<localhost.dev> ESTABLISH LOCAL CONNECTION FOR USER: mstudd
<localhost.dev> EXEC /bin/sh -c 'echo ~mstudd && sleep 0'
<localhost.dev> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /home/mstudd/.ansible/tmp `"&& mkdir /home/mstudd/.ansible/tmp/ansible-tmp-1596227663.4545841-234299-215745550363761 && echo ansible-tmp-1596227663.4545841-234299-215745550363761="` echo /home/mstudd/.ansible/tmp/ansible-tmp-1596227663.4545841-234299-215745550363761 `" ) && sleep 0'
Using module file /home/mstudd/dev/git/ansible/galaxy-roles/ansible_collections/community/aws/plugins/modules/sqs_queue.py
<localhost.dev> PUT /home/mstudd/.ansible/tmp/ansible-local-234246mzlywzby/tmpifp2ngt5 TO /home/mstudd/.ansible/tmp/ansible-tmp-1596227663.4545841-234299-215745550363761/AnsiballZ_sqs_queue.py
<localhost.dev> EXEC /bin/sh -c 'chmod u+x /home/mstudd/.ansible/tmp/ansible-tmp-1596227663.4545841-234299-215745550363761/ /home/mstudd/.ansible/tmp/ansible-tmp-1596227663.4545841-234299-215745550363761/AnsiballZ_sqs_queue.py && sleep 0'
<localhost.dev> EXEC /bin/sh -c '/usr/bin/python3 /home/mstudd/.ansible/tmp/ansible-tmp-1596227663.4545841-234299-215745550363761/AnsiballZ_sqs_queue.py && sleep 0'
<localhost.dev> EXEC /bin/sh -c 'rm -f -r /home/mstudd/.ansible/tmp/ansible-tmp-1596227663.4545841-234299-215745550363761/ > /dev/null 2>&1 && sleep 0'
The full traceback is:
Traceback (most recent call last):
  File "/home/mstudd/.ansible/tmp/ansible-tmp-1596227663.4545841-234299-215745550363761/AnsiballZ_sqs_queue.py", line 102, in <module>
    _ansiballz_main()
  File "/home/mstudd/.ansible/tmp/ansible-tmp-1596227663.4545841-234299-215745550363761/AnsiballZ_sqs_queue.py", line 94, in _ansiballz_main
    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)
  File "/home/mstudd/.ansible/tmp/ansible-tmp-1596227663.4545841-234299-215745550363761/AnsiballZ_sqs_queue.py", line 40, in invoke_module
    runpy.run_module(mod_name='ansible_collections.community.aws.plugins.modules.sqs_queue', init_globals=None, run_name='__main__', alter_sys=True)
  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_community.aws.sqs_queue_payload_vm5yiveu/ansible_community.aws.sqs_queue_payload.zip/ansible_collections/community/aws/plugins/modules/sqs_queue.py", line 474, in <module>
  File "/tmp/ansible_community.aws.sqs_queue_payload_vm5yiveu/ansible_community.aws.sqs_queue_payload.zip/ansible_collections/community/aws/plugins/modules/sqs_queue.py", line 464, in main
  File "/tmp/ansible_community.aws.sqs_queue_payload_vm5yiveu/ansible_community.aws.sqs_queue_payload.zip/ansible_collections/community/aws/plugins/modules/sqs_queue.py", line 311, in create_or_update_sqs_queue
  File "/tmp/ansible_community.aws.sqs_queue_payload_vm5yiveu/ansible_community.aws.sqs_queue_payload.zip/ansible_collections/community/aws/plugins/modules/sqs_queue.py", line 377, in update_sqs_queue
UnboundLocalError: local variable 'existing_value' referenced before assignment
fatal: [localhost]: FAILED! => {
    "changed": false,
    "module_stderr": "Traceback (most recent call last):\n  File \"/home/mstudd/.ansible/tmp/ansible-tmp-1596227663.4545841-234299-215745550363761/AnsiballZ_sqs_queue.py\", line 102, in <module>\n    _ansiballz_main()\n  File \"/home/mstudd/.ansible/tmp/ansible-tmp-1596227663.4545841-234299-215745550363761/AnsiballZ_sqs_queue.py\", line 94, in _ansiballz_main\n    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)\n  File \"/home/mstudd/.ansible/tmp/ansible-tmp-1596227663.4545841-234299-215745550363761/AnsiballZ_sqs_queue.py\", line 40, in invoke_module\n    runpy.run_module(mod_name='ansible_collections.community.aws.plugins.modules.sqs_queue', init_globals=None, run_name='__main__', alter_sys=True)\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_community.aws.sqs_queue_payload_vm5yiveu/ansible_community.aws.sqs_queue_payload.zip/ansible_collections/community/aws/plugins/modules/sqs_queue.py\", line 474, in <module>\n  File \"/tmp/ansible_community.aws.sqs_queue_payload_vm5yiveu/ansible_community.aws.sqs_queue_payload.zip/ansible_collections/community/aws/plugins/modules/sqs_queue.py\", line 464, in main\n  File \"/tmp/ansible_community.aws.sqs_queue_payload_vm5yiveu/ansible_community.aws.sqs_queue_payload.zip/ansible_collections/community/aws/plugins/modules/sqs_queue.py\", line 311, in create_or_update_sqs_queue\n  File \"/tmp/ansible_community.aws.sqs_queue_payload_vm5yiveu/ansible_community.aws.sqs_queue_payload.zip/ansible_collections/community/aws/plugins/modules/sqs_queue.py\", line 377, in update_sqs_queue\nUnboundLocalError: local variable 'existing_value' referenced before assignment\n",
    "module_stdout": "",
    "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error",
    "rc": 1
}

PLAY RECAP ******************************************************************************************************************************************************************************************************************************************************************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0   
```



Discussion:
Looks like changing `existing_value` to `value` in line 377 of sqs_queue.py fixes it.
cc @jillr @loia @nand0p @s-hertel @sbj-ss @tremble @wimnat
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: notify --->
we are encountering this issue as well.

@mestuddtc do you have a Pull Request that can be merged in to fix this?

Resolving patch:
diff --git a/plugins/modules/sqs_queue.py b/plugins/modules/sqs_queue.py
--- a/plugins/modules/sqs_queue.py
+++ b/plugins/modules/sqs_queue.py
@@ -375,7 +375,7 @@ def update_sqs_queue(module, client, queue_url):
 
         if isinstance(new_value, bool):
             new_value = str(new_value).lower()
-            existing_value = str(existing_value).lower()
+            value = str(value).lower()
 
         if new_value == value:
             continue


Test patch:
diff --git a/tests/integration/targets/sqs_queue/tasks/main.yml b/tests/integration/targets/sqs_queue/tasks/main.yml
--- a/tests/integration/targets/sqs_queue/tasks/main.yml
+++ b/tests/integration/targets/sqs_queue/tasks/main.yml
@@ -104,3 +104,25 @@
         with_items:
           - { name: "{{ create_result.name }}" }
           - { name: "{{ dead_letter_queue.name }}" }
+  - name: Test FIFO queue
+    block:
+      - name: Creating FIFO queue
+        sqs_queue:
+          name: "{{ resource_prefix }}{{ 1000 | random }}"
+          queue_type: fifo
+          content_based_deduplication: yes
+        register: create_result
+      - name: Assert queue created with configuration
+        assert:
+          that:
+            - create_result.changed
+    always:
+      - name: Cleaning up queue
+        sqs_queue:
+          name: "{{ item.name }}"
+          state: absent
+        register: delete_result
+        retries: 3
+        delay: 3
+        with_items:
+          - { name: "{{ create_result.name }}" }