Repository: cloud-custodian/cloud-custodian

Issue:
AWS Config Rule Deploy Error With S3 Resource
We are testing out the c7n config-rule mode for the first time. We are running into an error with a policy we are testing. Here is the policy:
```
- name: agt-s3-check-encryption-status-tag-disabled
  resource: s3
  description: |
     This is part of a policy chain which checks to see if the bucket
     has encryption enabled and if not it enables AES-256 default key.
  mode:
      packages: [boto3, botocore, urllib3]
      type: config-rule
      role: AGT_Cloud_Custodian_Role
  filters:
    - "tag:c7n_CheckEncryption": present
    - not:
        - type: bucket-encryption
  actions:
    - type: set-bucket-encryption
    - type: unmark
      tags: ['c7n_CheckEncryption']
```
and here is the error:
```
[ERROR] AttributeError: 'NoneType' object has no attribute 'get'
Traceback (most recent call last):
  File "/var/task/custodian_policy.py", line 4, in run
    return handler.dispatch_event(event, context)
  File "/var/task/c7n/handler.py", line 168, in dispatch_event
    p.push(event, context)
  File "/var/task/c7n/policy.py", line 932, in push
    return mode.run(event, lambda_ctx)
  File "/var/task/c7n/policy.py", line 729, in run
    resources = super(ConfigRuleMode, self).run(event, lambda_context)
  File "/var/task/c7n/policy.py", line 484, in run
    results = action.process(resources)
  File "/var/task/c7n/tags.py", line 474, in process
    self.process_resource_set, self.id_key, resources, tags, self.log)
  File "/var/task/c7n/tags.py", line 136, in _common_tag_processer
    raise error
  File "/var/lang/lib/python3.7/concurrent/futures/thread.py", line 57, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/var/task/c7n/resources/s3.py", line 2274, in process_resource_set
    self.manager.session_factory, resource_set, remove_tags=tags)
  File "/var/task/c7n/resources/s3.py", line 505, in modify_bucket_tags
    client = bucket_client(local_session(session_factory), bucket)
  File "/var/task/c7n/resources/s3.py", line 490, in bucket_client
    region = get_region(b)
  File "/var/task/c7n/resources/s3.py", line 558, in get_region
    region = b.get('Location',
{}
).get('LocationConstraint')
```

Config Event:
```
{
"version": "1.0",
"invokingEvent": "{\"configurationItemDiff\":{\"changedProperties\":{},\"changeType\":\"CREATE\"},\"configurationItem\":{\"relatedEvents\":[],\"relationships\":[],\"configuration\":{\"name\":\"another-config-test-2\",\"owner\":{\"displayName\":null,\"id\":\"99e1702adadc340d666f5077c737dd2a27390e79b2ecefa22f0fa9c4cc08edce\"},\"creationDate\":\"2019-09-30T19:48:21.000Z\"},\"supplementaryConfigurat
"resultToken": "eyJlbmNyeXB0ZWREYXRhIjpbMTEzLC00MCwtNjAsLTg3LC0yNCwtNjgsMTA4LC0yNSwtMTAxLC00NSw0NywtNzYsMjUsLTYxLC0xMTksMjMsNTcsLTcwLDU2LDExNSwyNCwxNiwtNjAsLTExNCwtMzQsLTcxLDIxLDIxLCFSDFSDFSDFSDFSDFSEFSEFSDFSDFOCwxMjQsLTYwLC01NiwzNiwxNSwxMjIsMyw0NSwxMDAsLTUwLDYxLDc2LDc0LDYzLDk3LDMsLTkzLC0yMSwxMSw0NSwtMTYsLTk0LDEyNiwtNjgsMTA1LDExLC04LDEwNiwxMTksODUsLTc1LC01LDAsLTgsMTI3LC00NCwtNTEsLTUwLC04OC
"eventLeftScope": false,
"executionRoleArn": "arn:aws:iam::1234567890:role/aws-service-role/config.amazonaws.com/AWSServiceRoleForConfig",
"configRuleArn": "arn:aws:config:us-east-1:1234567890:config-rule/config-rule-xgr9y2",
"configRuleName": "custodian-agt-s3-check-encryption-status-tag-disabled",
"configRuleId": "config-rule-xgr9y2",
"accountId": "1234567890",
"debug": true
}
```


Discussion:

Resolving patch:
diff --git a/c7n/resources/s3.py b/c7n/resources/s3.py
--- a/c7n/resources/s3.py
+++ b/c7n/resources/s3.py
@@ -151,6 +151,8 @@ def load_resource(self, item):
         # aka standard
         if 'awsRegion' in item and item['awsRegion'] != 'us-east-1':
             resource['Location'] = {'LocationConstraint': item['awsRegion']}
+        else:
+            resource['Location'] = {}
 
         # owner is under acl per describe
         resource.pop('Owner', None)
@@ -402,7 +404,7 @@ def handle_BucketWebsiteConfiguration(self, resource, item_value):
 }
 
 S3_AUGMENT_TABLE = (
-    ('get_bucket_location', 'Location', None, None),
+    ('get_bucket_location', 'Location', {}, None),
     ('get_bucket_tagging', 'Tags', [], 'TagSet'),
     ('get_bucket_policy', 'Policy', None, 'Policy'),
     ('get_bucket_acl', 'Acl', None, None),


Test patch:
diff --git a/tests/test_s3.py b/tests/test_s3.py
--- a/tests/test_s3.py
+++ b/tests/test_s3.py
@@ -749,7 +749,7 @@ class S3ConfigSource(ConfigTest):
     def test_normalize(self):
         self.patch(s3.S3, "executor_factory", MainThreadExecutor)
         augments = list(s3.S3_AUGMENT_TABLE)
-        augments.remove(("get_bucket_location", "Location", None, None))
+        augments.remove(("get_bucket_location", "Location", {}, None))
         self.patch(s3, "S3_AUGMENT_TABLE", augments)
 
         bname = "custodian-test-data-23"
@@ -889,7 +889,7 @@ def test_normalize(self):
         results = self.wait_for_config(session, queue_url, bname)
         resource_b = s3.ConfigS3(manager).load_resource(results[0])
         self.maxDiff = None
-
+        self.assertEqual(s3.get_region(resource_b), 'us-east-1')
         for k in ("Logging", "Policy", "Versioning", "Name", "Website"):
             self.assertEqual(resource_a[k], resource_b[k])
 
@@ -903,6 +903,7 @@ def test_config_normalize_notification(self):
         p = self.load_policy({"name": "s3cfg", "resource": "s3"})
         source = p.resource_manager.get_source("config")
         resource = source.load_resource(event)
+        self.assertEqual(s3.get_region(resource), 'us-east-1')
         self.assertEqual(
             resource["Notification"],
             {
@@ -1084,6 +1085,7 @@ def test_load_item_resource(self):
             {"Planet": "Earth", "Verbose": "Game"},
             {t["Key"]: t["Value"] for t in resource.pop("Tags")},
         )
+        self.assertEqual(s3.get_region(resource), 'us-east-2')
         self.assertEqual(
             resource,
             {
@@ -1149,7 +1151,7 @@ def test_load_item_resource_config_event(self):
                     2017, 9, 15, 2, 5, 40, tzinfo=tzutc()
                 ),
                 u"Lifecycle": None,
-                u"Location": None,
+                u"Location": {},
                 u"Logging": None,
                 u"Name": u"c7n-fire-logs",
                 u"Notification": {},