Repository: ansible/ansible

Issue:
Elasticcache creation always is shown as changed (playbook is not idempotent)
##### ISSUE TYPE
 - Bug Report

##### COMPONENT NAME
elasticache

##### ANSIBLE VERSION
<!--- Paste, BELOW THIS COMMENT, verbatim output from "ansible --version" between quotes below -->
```
ansible 2.5.2
  config file = REDACTD/ansible.cfg
  configured module search path = ['REDACTD/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = REDACTD/.pyenv/versions/3.6.5/lib/python3.6/site-packages/ansible
  executable location = REDACTD/.pyenv/versions/3.6.5/bin/ansible
  python version = 3.6.5 (default, Apr 12 2018, 13:43:59) [GCC 4.2.1 Compatible Apple LLVM 9.1.0 (clang-902.0.39.1)]
```

##### CONFIGURATION
```
ANSIBLE_SSH_ARGS(REDACTED/ansible.cfg) = -o ControlMaster=auto -o ControlPersist=60s -o ControlPath=/tmp/ansible-ssh-%h-%p-%r -o ForwardAgent=
HOST_KEY_CHECKING(REDACTED/ansible.cfg) = False
```

##### OS / ENVIRONMENT
N/A

##### SUMMARY
Ansible marks elasticcache creation as "changed" even though nothing has been changed.

##### STEPS TO REPRODUCE
A simple playbook to create a Redis server using elasticcahe would reproduce the issue:

```yaml
- name: Create a Redis server
  elasticache:
    name: '{{ project.name }}-redis-{{ env }}'
    region: '{{ aws.region }}'
    state: present
    engine: redis
    node_type: '{{ redis.instance_size }}'
    num_nodes: '{{ redis.num_nodes }}'
    wait: yes
  register: elasticache
```

##### EXPECTED RESULTS
When running the playbook for the 2nd time, I expect to see the task marked as "ok" not "changed":

```
TASK [1-launch-aws-services : Create an Redis server] 
ok: [localhost]
```

##### ACTUAL RESULTS
Every time that I run the playbook, the elasticcache marked as changed, even thought nothing has really changed:

```
TASK [1-launch-aws-services : Create an Redis server] 
changed: [localhost]
```

Here is the output with -vvvv verbose mode:

```
Using module file DEDACTED/.pyenv/versions/3.6.5/lib/python3.6/site-packages/ansible/modules/cloud/amazon/elasticache.py
<127.0.0.1> ESTABLISH LOCAL CONNECTION FOR USER: DEDACTED
<127.0.0.1> EXEC /bin/sh -c 'echo ~ && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo DEDACTED/.ansible/tmp/ansible-tmp-1526273649.425235-127783658341067 `" && echo ansible-tmp-1526273649.425235-127783658341067="` echo DEDACTED/.ansible/tmp/ansible-tmp-1526273649.425235-127783658341067 `" ) && sleep 0'
<127.0.0.1> PUT DEDACTED/.ansible/tmp/ansible-local-91834uxrimcd6/tmpkaqbqu2p TO DEDACTED/.ansible/tmp/ansible-tmp-1526273649.425235-127783658341067/elasticache.py
<127.0.0.1> EXEC /bin/sh -c 'chmod u+x DEDACTED/.ansible/tmp/ansible-tmp-1526273649.425235-127783658341067/ DEDACTED/.ansible/tmp/ansible-tmp-1526273649.425235-127783658341067/elasticache.py && sleep 0'
<127.0.0.1> EXEC /bin/sh -c 'DEDACTED/.pyenv/versions/3.6.5/bin/python3.6 DEDACTED/.ansible/tmp/ansible-tmp-1526273649.425235-127783658341067/elasticache.py && sleep 0'
<127.0.0.1> EXEC /bin/sh -c 'rm -f -r DEDACTED/.ansible/tmp/ansible-tmp-1526273649.425235-127783658341067/ > /dev/null 2>&1 && sleep 0'
changed: [localhost] => {
    "changed": true,
    "elasticache": {
        "data": {
            "AtRestEncryptionEnabled": false,
            "AuthTokenEnabled": false,
            "AutoMinorVersionUpgrade": true,
            "CacheClusterCreateTime": "2018-05-14T04:07:08.069000+00:00",
            "CacheClusterId": "presen-redis-dev",
            "CacheClusterStatus": "available",
            "CacheNodeType": "cache.m1.small",
            "CacheNodes": [
                {
                    "CacheNodeCreateTime": "2018-05-14T04:07:08.069000+00:00",
                    "CacheNodeId": "0001",
                    "CacheNodeStatus": "available",
                    "CustomerAvailabilityZone": "ap-southeast-2a",
                    "Endpoint": {
                        "Address": "presen-redis-dev.k5wi4k.0001.apse2.cache.amazonaws.com",
                        "Port": 6379
                    },
                    "ParameterGroupStatus": "in-sync"
                }
            ],
            "CacheParameterGroup": {
                "CacheNodeIdsToReboot": [],
                "CacheParameterGroupName": "default.redis3.2",
                "ParameterApplyStatus": "in-sync"
            },
            "CacheSecurityGroups": [],
            "CacheSubnetGroupName": "default",
            "ClientDownloadLandingPage": "https://console.aws.amazon.com/elasticache/home#client-download:",
            "Engine": "redis",
            "EngineVersion": "3.2.10",
            "NumCacheNodes": 1,
            "PendingModifiedValues": {},
            "PreferredAvailabilityZone": "ap-southeast-2a",
            "PreferredMaintenanceWindow": "thu:12:30-thu:13:30",
            "SnapshotRetentionLimit": 0,
            "SnapshotWindow": "16:30-17:30",
            "TransitEncryptionEnabled": false
        },
        "name": "presen-redis-dev",
        "status": "available"
    },
    "invocation": {
        "module_args": {
            "aws_access_key": null,
            "aws_secret_key": null,
            "cache_engine_version": "",
            "cache_parameter_group": "",
            "cache_port": null,
            "cache_security_groups": [],
            "cache_subnet_group": "",
            "ec2_url": null,
            "engine": "redis",
            "hard_modify": null,
            "name": "presen-redis-dev",
            "node_type": "cache.m1.small",
            "num_nodes": 1,
            "profile": null,
            "region": "ap-southeast-2",
            "security_group_ids": [],
            "security_token": null,
            "state": "present",
            "validate_certs": true,
            "wait": true,
            "zone": "ap-southeast-2a"
        }
    }
}
```

When I diff the output of the two consecutive execution, I see no difference. When running the following commands, I see no difference except changes in temporary pahts:

```
diff $(ansible-playbook -i ../lib/ec2.py main.yml --extra-vars="env=dev" -vvvv) $(ansible-playbook -i ../lib/ec2.py main.yml --extra-vars="env=dev" -vvvv)
```


Discussion:
Files identified in the description:
* [lib/ansible/modules/cloud/amazon/elasticache.py](https://github.com/ansible/ansible/blob/devel/lib/ansible/modules/cloud/amazon/elasticache.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 @alachaum @jsdalton
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: notify --->
-label needs_triage

Resolving patch:
diff --git a/lib/ansible/modules/cloud/amazon/elasticache.py b/lib/ansible/modules/cloud/amazon/elasticache.py
--- a/lib/ansible/modules/cloud/amazon/elasticache.py
+++ b/lib/ansible/modules/cloud/amazon/elasticache.py
@@ -369,7 +369,7 @@ def _requires_modification(self):
             'EngineVersion': self.cache_engine_version
         }
         for key, value in modifiable_data.items():
-            if value is not None and self.data[key] != value:
+            if value is not None and value and self.data[key] != value:
                 return True
 
         # Check cache security groups


Test patch: