Repository: ansible/ansible

Issue:
Dynamic Inventory Script - ec2.py - Elasticache - Forbidden Error/NoAuthHandlerFound
**Issue Type:**

Bug Report

**Ansible Version**
ansible 2.0.0 (detached HEAD de54f26376) last updated 2015/11/13 13:35:35 (GMT +1000)
  lib/ansible/modules/core: (detached HEAD 6e37f1dcef) last updated 2015/11/13 13:31:27 (GMT +1000)
  lib/ansible/modules/extras: (detached HEAD e52e015791) last updated 2015/11/13 13:31:27 (GMT +1000)

Running Ansible from source - v2.0.0-0.4.beta2

**Environment:**
OSX 10.11.1
Running Ansible from source - v2.0.0-0.4.beta2
Running boto (2.38.0) and boto3 (1.1.4)
Python 2.7.10

**Summary:**

When utilising the ec2.py dynamic inventory with AWS profiles and not setting elasticache = false, boto.exception.NoAuthHandlerFound is returned when no default profile is set, or Forbidden when default profile is set to incorrect keys. It does not utilise the boto_profile set in the ec2.ini file for elasticache calls - like it does with ec2 calls.

**Steps To Reproduce:**

Setup $HOME/.aws/credentials with no default profile set and a profile name of something else set to what you require, and setup the ec2.ini to call that specific profile and elasticache = true or no elasticache declaration.

```
less $HOME/.aws/credentials
[default]
aws_access_key_id=''
aws_secret_access_key=''
[personal]
aws_access_key_id=<PERSONAL_ACCESS_KEY>
aws_secret_access_key=<PERSONAL_SECRET_KEY>

less $HOME/inventory/ec2.ini
boto_profile = personal
elasticache = true
```

**Expected Results:**

```
Inventory returned from personal AWS account.
```

**Actual Results:**

```
python inventory/ec2.py --refresh-cache
boto.exception.NoAuthHandlerFound: No handler was ready to authenticate. 1 handlers were checked. ['HmacAuthV4Handler'] Check your credentials
```

 or the below when default profile has keys not set.

```
 ERROR: "Forbidden", while: getting ElastiCache clusters
```

**Proposed fix:**

Update contrib/inventory/ec2.py with the following:

```
def get_elasticache_clusters_by_region(self, region):
    ''' Makes an AWS API call to the list of ElastiCache clusters (with
    nodes' info) in a particular region.'''

    # ElastiCache boto module doesn't provide a get_all_intances method,
    # that's why we need to call describe directly (it would be called by
    # the shorthand method anyway...)
    try:
        conn = self.connect_to_aws(elasticache, region)

def get_elasticache_replication_groups_by_region(self, region):
    ''' Makes an AWS API call to the list of ElastiCache replication groups
    in a particular region.'''

    # ElastiCache boto module doesn't provide a get_all_intances method,
    # that's why we need to call describe directly (it would be called by
    # the shorthand method anyway...)
    try:
        conn = self.connect_to_aws(elasticache, region)
```



Discussion:

Resolving patch:
diff --git a/contrib/inventory/ec2.py b/contrib/inventory/ec2.py
--- a/contrib/inventory/ec2.py
+++ b/contrib/inventory/ec2.py
@@ -505,7 +505,7 @@ def get_elasticache_clusters_by_region(self, region):
         # that's why we need to call describe directly (it would be called by
         # the shorthand method anyway...)
         try:
-            conn = elasticache.connect_to_region(region)
+            conn = self.connect_to_aws(elasticache, region)
             if conn:
                 # show_cache_node_info = True
                 # because we also want nodes' information
@@ -541,7 +541,7 @@ def get_elasticache_replication_groups_by_region(self, region):
         # that's why we need to call describe directly (it would be called by
         # the shorthand method anyway...)
         try:
-            conn = elasticache.connect_to_region(region)
+            conn = self.connect_to_aws(elasticache, region)
             if conn:
                 response = conn.describe_replication_groups()
 


Test patch: