Repository: cloud-custodian/cloud-custodian

Issue:
Lambda is failing for app elb config rule evaluation
File "/var/task/c7n/resources/appelb.py", line 98, in load_resource
 for t in json.loads(item['Tags'])]
I have seen recent fix in rds.py for  the same issue . We must need same fix here as well.

**File appelb.py: Line#105:** json.loads(items['Tags']) would be replaced with **item['supplementaryConfiguration']['Tags']**


Discussion:

Resolving patch:
diff --git a/c7n/resources/appelb.py b/c7n/resources/appelb.py
--- a/c7n/resources/appelb.py
+++ b/c7n/resources/appelb.py
@@ -102,7 +102,7 @@ class ConfigAppElb(ConfigSource):
     def load_resource(self, item):
         resource = super(ConfigAppElb, self).load_resource(item)
         resource['Tags'] = [{u'Key': t['key'], u'Value': t['value']}
-          for t in json.loads(item['Tags'])]
+          for t in json.loads(item['supplementaryConfiguration']['Tags'])]
         return resource
 
 


Test patch:
diff --git a/tests/data/config/app-elb.json b/tests/data/config/app-elb.json
new file mode 100644
--- /dev/null
+++ b/tests/data/config/app-elb.json
@@ -0,0 +1,38 @@
+{
+    "version": "1.2",
+    "accountId": "644160558196",
+    "configurationItemCaptureTime": "2017-11-09T12:35:43.639000-05:00",
+    "configurationItemStatus": "ResourceDiscovered",
+    "configurationStateId": "1510248943639",
+    "configurationItemMD5Hash": "983bfae2b42b2835c96a322ff7d88b56",
+    "arn": "arn:aws:elasticloadbalancing:us-east-1:644160558196:loadbalancer/app/Migration-QAEAST-ELB/6b0fe08b851e2aa",
+    "resourceType": "AWS::ElasticLoadBalancingV2::LoadBalancer",
+    "resourceId": "arn:aws:elasticloadbalancing:us-east-1:644160558196:loadbalancer/app/Migration-QAEAST-ELB/6b0fe08b851e2aa",
+    "resourceName": "Migration-QAEAST-ELB",
+    "awsRegion": "us-east-1",
+    "availabilityZone": "Multiple Availability Zones",
+    "resourceCreationTime": "2017-11-09T12:32:40.200000-05:00",
+    "tags": {
+	"App": "ARTIFACTPLATFORM",
+	"Env": "QA",
+	"Name": "Artifactory ELB",
+	"OwnerContact": "me@example.com",
+	"TeamName": "Frogger"
+    },
+    "relatedEvents": [{
+      "resourceType": "AWS::EC2::Subnet",
+      "resourceId": "subnet-ac333ccc",
+      "relationshipName": "Is attached to Subnet"
+    },
+    {
+      "resourceType": "AWS::EC2::VPC",
+      "resourceId": "vpc-bbaaeb9",
+      "relationshipName": "Is contained in Vpc"
+    }
+  ],
+  "configuration": "{\"loadBalancerArn\":\"arn:aws:elasticloadbalancing:us-east-1:644160558196:loadbalancer/app/Migration-QAEAST-ELB/6b0fe08b851e2aa\",\"dNSName\":\"internal-Migration-QAEAST-ELB-91111.us-east-1.elb.amazonaws.com\",\"canonicalHostedZoneId\":\"Z11SXDOTRQ7ABC\",\"createdTime\":\"2017-11-09T17:32:40.200Z\",\"loadBalancerName\":\"Migration-QAEAST-ELB\",\"scheme\":\"internal\",\"vpcId\":\"vpc-bbaaeb9\",\"state\":{\"code\":\"active\",\"reason\":null},\"type\":\"application\",\"availabilityZones\":[{\"zoneName\":\"us-east-1b\",\"subnetId\":\"subnet-93111aaa\",\"loadBalancerAddresses\":[]},{\"zoneName\":\"us-east-1d\",\"subnetId\":\"subnet-95222bbb\",\"loadBalancerAddresses\":[]},{\"zoneName\":\"us-east-1a\",\"subnetId\":\"subnet-ac333ccc\",\"loadBalancerAddresses\":[]}],\"securityGroups\":[\"sg-111222333\",\"sg-333444555\",\"sg-666777888\",\"sg-aaacccddd\"],\"ipAddressType\":\"ipv4\"}",
+  "supplementaryConfiguration": {
+    "LoadBalancerAttributes": "[{\"key\":\"access_logs.s3.enabled\",\"value\":\"true\"},{\"key\":\"access_logs.s3.prefix\",\"value\":\"ARTIFACTPLATFORM\"},{\"key\":\"idle_timeout.timeout_seconds\",\"value\":\"300\"},{\"key\":\"access_logs.s3.bucket\",\"value\":\"elb-access-logs-us-east-1\"},{\"key\":\"deletion_protection.enabled\",\"value\":\"false\"}]",
+    "Tags": "[{\"key\":\"App\",\"value\":\"ARTIFACTPLATFORM\"},{\"key\":\"OwnerContact\",\"value\":\"me@example.com\"},{\"key\":\"TeamName\",\"value\":\"Frogger\"},{\"key\":\"Env\",\"value\":\"QA\"},{\"key\":\"Name\",\"value\":\"Artifact ELB\"}]"
+  }
+}
diff --git a/tests/test_appelb.py b/tests/test_appelb.py
--- a/tests/test_appelb.py
+++ b/tests/test_appelb.py
@@ -15,7 +15,7 @@
 
 import six
 
-from .common import BaseTest
+from .common import BaseTest, event_data
 from c7n.filters import FilterValidationError
 from c7n.executor import MainThreadExecutor
 from c7n.resources.appelb import AppELB, AppELBTargetGroup
@@ -23,6 +23,21 @@
 
 class AppELBTest(BaseTest):
 
+    def test_appelb_config_source(self):
+        event = event_data('app-elb.json', 'config')
+        p = self.load_policy({'name': 'appelbcfg', 'resource': 'app-elb'})
+        source = p.resource_manager.get_source('config')
+        resource = source.load_resource(event)
+        self.maxDiff = None
+        self.assertEqual(
+            resource['Tags'],
+            [{'Key': 'App', 'Value': 'ARTIFACTPLATFORM'},
+             {'Key': 'OwnerContact', 'Value': 'me@example.com'},
+             {'Key': 'TeamName', 'Value': 'Frogger'},
+             {'Key': 'Env', 'Value': 'QA'},
+             {'Key': 'Name', 'Value': 'Artifact ELB'}])
+                         
+            
     def test_appelb_simple(self):
         self.patch(AppELB, 'executor_factory', MainThreadExecutor)
         session_factory = self.replay_flight_data('test_appelb_simple')