# Buggy code
def handle_BucketLifecycleConfiguration(self, resource, item_value):
    rules = []
    for r in item_value.get("rules"):
        rr = {}
        rules.append(rr)
        expiry = {}
        for ek, ck in (
            ("Date", "expirationDate"),
            ("ExpiredObjectDeleteMarker", "expiredObjectDeleteMarker"),
            ("Days", "expirationInDays"),
        ):
            if r[ck] and r[ck] != -1:
                expiry[ek] = r[ck]
        if expiry:
            rr["Expiration"] = expiry

        transitions = []
        for t in r.get("transitions") or ():
            tr = {}
            for k in ("date", "days", "storageClass"):
                if t[k]:
                    tr["%s%s" % (k[0].upper(), k[1:])] = t[k]
            transitions.append(tr)
        if transitions:
            rr["Transitions"] = transitions

        if r.get("abortIncompleteMultipartUpload"):
            rr["AbortIncompleteMultipartUpload"] = {
                "DaysAfterInitiation": r["abortIncompleteMultipartUpload"][
                    "daysAfterInitiation"
                ]
            }
        if r.get("noncurrentVersionExpirationInDays"):
            rr["NoncurrentVersionExpiration"] = {
                "NoncurrentDays": r["noncurrentVersionExpirationInDays"]
            }

        nonc_transitions = []
        for t in r.get("noncurrentVersionTransitions") or ():
            nonc_transitions.append(
                {"NoncurrentDays": t["days"], "StorageClass": t["storageClass"]}
            )
        if nonc_transitions:
            rr["NoncurrentVersionTransitions"] = nonc_transitions

        rr["Status"] = r["status"]
        rr["ID"] = r["id"]
        if r.get("prefix"):
            rr["Prefix"] = r["prefix"]
        if "filter" not in r or not r["filter"]:
            continue

        rr["Filter"] = self.convertLifePredicate(r["filter"]["predicate"])

    resource["Lifecycle"] = {"Rules": rules}


# Traceback (KeyError)
2017-10-22 11:25:17,078: policyrun:DEBUG Running policy:blahblah account:acct1 region:us-east-1
2017-10-22 11:25:44,412: custodian.resources.s3:ERROR Exception getting resources from config
u'redirectsAllRequestsTo'
2017-10-22 11:25:44,414: custodian.output:ERROR Error while executing policy
Traceback (most recent call last):
File "/usr/local/custodian/site-packages/c7n/policy.py", line 305, in run
resources = self.policy.resource_manager.resources()
File "/usr/local/custodian/site-packages/c7n/query.py", line 395, in resources
resources = self.augment(self.source.resources(query))
File "/usr/local/custodian/site-packages/c7n/query.py", line 305, in resources
results.extend(f.result())
File "/usr/local/custodian/site-packages/concurrent/futures/_base.py", line 422, in result
return self.__get_result()
File "/usr/local/custodian/site-packages/concurrent/futures/thread.py", line 62, in run
result = self.fn(*self.args, **self.kwargs)
File "/usr/local/custodian/site-packages/c7n/query.py", line 271, in get_resources
results.append(self.load_resource(revisions[0]))
File "/usr/local/custodian/site-packages/c7n/resources/s3.py", line 152, in load_resource
method(resource, v)
File "/usr/local/custodian/site-packages/c7n/resources/s3.py", line 343, in handle_BucketWebsiteConfiguration
'HostName': item_value['redirectsAllRequestsTo']['hostName'],
KeyError: u'redirectsAllRequestsTo'

# Fixed code
def handle_BucketLifecycleConfiguration(self, resource, item_value):
    rules = []
    for r in item_value.get("rules"):
        rr = {}
        rules.append(rr)
        expiry = {}
        for ek, ck in (
            ("Date", "expirationDate"),
            ("ExpiredObjectDeleteMarker", "expiredObjectDeleteMarker"),
            ("Days", "expirationInDays"),
        ):
            if r[ck] and r[ck] != -1:
                expiry[ek] = r[ck]
        if expiry:
            rr["Expiration"] = expiry

        transitions = []
        for t in r.get("transitions") or ():
            tr = {}
            for k in ("date", "days", "storageClass"):
                if t[k]:
                    tr["%s%s" % (k[0].upper(), k[1:])] = t[k]
            transitions.append(tr)
        if transitions:
            rr["Transitions"] = transitions

        if r.get("abortIncompleteMultipartUpload"):
            rr["AbortIncompleteMultipartUpload"] = {
                "DaysAfterInitiation": r["abortIncompleteMultipartUpload"][
                    "daysAfterInitiation"
                ]
            }
        if r.get("noncurrentVersionExpirationInDays"):
            rr["NoncurrentVersionExpiration"] = {
                "NoncurrentDays": r["noncurrentVersionExpirationInDays"]
            }

        nonc_transitions = []
        for t in r.get("noncurrentVersionTransitions") or ():
            nonc_transitions.append(
                {"NoncurrentDays": t["days"], "StorageClass": t["storageClass"]}
            )
        if nonc_transitions:
            rr["NoncurrentVersionTransitions"] = nonc_transitions

        rr["Status"] = r["status"]
        rr["ID"] = r["id"]
        if r.get("prefix"):
            rr["Prefix"] = r["prefix"]
        if "filter" not in r or not r["filter"]:
            continue

        if r["filter"]["predicate"]:
            rr["Filter"] = self.convertLifePredicate(r["filter"]["predicate"])

    resource["Lifecycle"] = {"Rules": rules}