Repository: ansible/ansible-modules-extras

Issue:
Cloud Module - cloudtrail - Error on existing trail without S3 prefix
##### ISSUE TYPE

<!--- Pick one below and delete the rest: -->
- Bug Report
##### COMPONENT NAME

AWS - Cloudtrail
##### ANSIBLE VERSION

```
ansible 2.0.2.0
  config file = /etc/ansible/ansible.cfg
  configured module search path = Default w/o overrides
```
##### SUMMARY

Describing (view) existing trails throws a module failure due to a missing key in the returned dictionary.
##### STEPS TO REPRODUCE
- Create a cloudtrail using existing module without a S3 prefix
- Re-run using existing cloudtrail configuration -- again, without s3 prefix
##### EXPECTED RESULTS

Nothing (unless there are changes)
##### ACTUAL RESULTS

Module error occurs due to KeyError as S3KeyPrefix is NOT part of the results when a describe-trail is performed.

```
An exception occurred during task execution. The full traceback is:
Traceback (most recent call last):
  File "/home/<username>/.ansible/tmp/ansible-tmp-1462399000.22-104944138960760/cloudtrail", line 2435, in <module>
    main()
  File "/home/<username>/.ansible/tmp/ansible-tmp-1462399000.22-104944138960760/cloudtrail", line 194, in main
    results['view']['S3KeyPrefix']                != s3_key_prefix  or \
KeyError: 'S3KeyPrefix'
```

You can see the key does not exist if you perform `aws cloudtrail describe-trails`:

```
        {
            "IncludeGlobalServiceEvents": true, 
            "Name": "<trail-name>", 
            "TrailARN": "arn:aws:cloudtrail:ap-southeast-2:account_id:trail/<trail-name>", 
            "LogFileValidationEnabled": true, 
            "IsMultiRegionTrail": true, 
            "S3BucketName": "<s3-bucket-name>", 
            "HomeRegion": "ap-southeast-2"
        }
```

even though the code is expecting it as seen here on line 193 of `ansible-modules-extras/cloud/amazon/cloudtrail.py`:

```
              results['view']['S3KeyPrefix']                != s3_key_prefix  or \
```



Discussion:
<!-- @matthewdaize: Thanks for filing this bug report! -->

@ansible ping, this issue is waiting for your response.
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)

<!--- boilerplate: issue_bug_new --->

@ansible, ping. This issue is still waiting on your response.
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)

<!--- boilerplate: issue_renotify_maintainer --->


Resolving patch:
diff --git a/cloud/amazon/cloudtrail.py b/cloud/amazon/cloudtrail.py
--- a/cloud/amazon/cloudtrail.py
+++ b/cloud/amazon/cloudtrail.py
@@ -152,13 +152,13 @@ def main():
 
     argument_spec = ec2_argument_spec()
     argument_spec.update(dict(
-        state={'required': True, 'choices': ['enabled', 'disabled'] },
-        name={'required': True, 'type': 'str' },
-        s3_bucket_name={'required': False, 'type': 'str' },
-        s3_key_prefix={'default':'', 'required': False, 'type': 'str' },
-        include_global_events={'default':True, 'required': False, 'type': 'bool' },
+        state={'required': True, 'choices': ['enabled', 'disabled']},
+        name={'required': True, 'type': 'str'},
+        s3_bucket_name={'required': False, 'type': 'str'},
+        s3_key_prefix={'default': '', 'required': False, 'type': 'str'},
+        include_global_events={'default': True, 'required': False, 'type': 'bool'},
     ))
-    required_together = ( ['state', 's3_bucket_name'] )
+    required_together = (['state', 's3_bucket_name'])
 
     module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True, required_together=required_together)
 
@@ -176,6 +176,7 @@ def main():
     s3_bucket_name = module.params['s3_bucket_name']
     # remove trailing slash from the key prefix, really messes up the key structure.
     s3_key_prefix = module.params['s3_key_prefix'].rstrip('/')
+
     include_global_events = module.params['include_global_events']
 
     #if module.params['state'] == 'present' and 'ec2_elbs' not in module.params:
@@ -190,7 +191,7 @@ def main():
             results['view'] = cf_man.view(ct_name)
             # only update if the values have changed.
             if results['view']['S3BucketName']              != s3_bucket_name or \
-              results['view']['S3KeyPrefix']                != s3_key_prefix  or \
+              results['view'].get('S3KeyPrefix', '')      != s3_key_prefix  or \
               results['view']['IncludeGlobalServiceEvents'] != include_global_events:
                 if not module.check_mode:
                     results['update'] = cf_man.update(name=ct_name, s3_bucket_name=s3_bucket_name, s3_key_prefix=s3_key_prefix, include_global_service_events=include_global_events)


Test patch: