Monday, March 23, 2020

AWS Config Custom Rule

How to AWS Custom Config 

Lambda - Python

Want to know how to setup your lambda Python function for AWS Custom Config? Here's what you need to know to get started. 

Here's a really simplified version of the Python code that you need to get started. You should add some try and catch errors and parse whatever input you are looking for.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
def lambda_handler(event, context):
    # you can check what invoked it
    invoking_event = json.loads(event["invokingEvent"])
    # you only need this for resource change trigger
    configuration_item = invoking_event["configurationItem"]
    # you can check what rule parameters were passed in
    rule_parameters = json.loads(event["ruleParameters"])
 
    compliant, annotation = evaluate_compliance(some_argument)

    config = boto3.client("config")
    # this example assumes resource trigger, for time trigger, you can have the above function spit out a list of resources
    config.put_evaluations(
    Evaluations=[
            {
                "ComplianceResourceType": configuration_item["resourceType"],
                "ComplianceResourceId": configuration_item["resourceId"],
                "ComplianceType": compliant, 
                "Annotation": annotation,
                "OrderingTimestamp": configuration_item["configurationItemCaptureTime"]
            },
        ],
        ResultToken=result_token,
    )    
 
 
def evaluate_compliance(argument):
    compliant = "COMPLIANT"
    annotations = []
 if blah: 
  compliant = "COMPLIANT"
  annotations.append("blah")
 else:
  compliant = "NON_COMPLIANT"
  annotations.append("different blah")
 return compliant, " ".join(annotations)

To understand how to fill in the logic of your code, you can look at what you get in the event payload.

Inputs


Sample scheduled trigger:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
{
   "version":"1.0",
   "invokingEvent":"{\"awsAccountId\":\"999999999\",\"notificationCreationTime\":\"2020-03-23T02:42:51.511Z\",\"messageType\":\"ScheduledNotification\",\"recordVersion\":\"1.0\"}",
   "ruleParameters":"{\"executionRole\":\"arn:aws:iam::9999:role/blah\"}",
   "resultToken":"XYZ",
   "eventLeftScope":false,
   "executionRoleArn":"arn:aws:iam::9999999:role/aws-service-role/config.amazonaws.com/AWSServiceRoleForConfig",
   "configRuleArn":"arn:aws:config:us-east-2:999999999:config-rule/config-rule-kfabou",
   "configRuleName":"my-test-rule1",
   "configRuleId":"config-rule-kfabou",
   "accountId":"9999999999"
}
Above's invoking event:
1
2
3
4
5
6
{
   "awsAccountId":"999999999",
   "notificationCreationTime":"2020-03-23T02:42:51.511Z",
   "messageType":"ScheduledNotification",
   "recordVersion":"1.0"
}
Rule parameter is the values you provide in Key:Value pair under your Config rule setup



Sample resource change trigger:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
{
   "version":"1.0",
   "invokingEvent":"{\"configurationItemDiff\":null,\"configurationItem\":{\"relatedEvents\":[],\"relationships\":[{\"resourceId\":\"ANPASP666ZVAXGDCE5SDN\",\"resourceName\":\"Read_Only_EC2\",\"resourceType\":\"AWS::IAM::Policy\",\"name\":\"Is attached to CustomerManagedPolicy\"}],\"configuration\":{\"path\":\"/\",\"userName\":\"FoxySugar\",\"userId\":\"AIDASP666ZVA36XQGO6DD\",\"arn\":\"arn:aws:iam::9999999999:user/FoxySugar\",\"createDate\":\"2020-01-07T14:06:13.000Z\",\"userPolicyList\":[],\"groupList\":[],\"attachedManagedPolicies\":[{\"policyName\":\"Read_Only_EC2\",\"policyArn\":\"arn:aws:iam::9999999:policy/Read_Only_EC2\"}],\"permissionsBoundary\":null,\"tags\":[]},\"supplementaryConfiguration\":{},\"tags\":{},\"configurationItemVersion\":\"1.3\",\"configurationItemCaptureTime\":\"2020-03-23T02:02:28.440Z\",\"configurationStateId\":1584928948999,\"awsAccountId\":\"999999999\",\"configurationItemStatus\":\"ResourceDiscovered\",\"resourceType\":\"AWS::IAM::User\",\"resourceId\":\"AIDASP666ZVA36XQGO6DD\",\"resourceName\":\"FoxySugar\",\"ARN\":\"arn:aws:iam::9999999:user/FoxySugar\",\"awsRegion\":\"global\",\"availabilityZone\":\"Not Applicable\",\"configurationStateMd5Hash\":\"\",\"resourceCreationTime\":\"2020-01-07T14:06:13.000Z\"},\"notificationCreationTime\":\"2020-03-23T02:40:01.999Z\",\"messageType\":\"ConfigurationItemChangeNotification\",\"recordVersion\":\"1.3\"}",
   "ruleParameters":"{}",
   "resultToken":"XYZ==",
   "eventLeftScope":false,
   "executionRoleArn":"arn:aws:iam::99999999:role/aws-service-role/config.amazonaws.com/AWSServiceRoleForConfig",
   "configRuleArn":"arn:aws:config:us-east-2:999999999:config-rule/config-rule-kfabou",
   "configRuleName":"my-config-rule1",
   "configRuleId":"config-rule-kfabou",
   "accountId":"99999999999999"
}
Above's invoking event:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
{
   "configurationItemDiff":null,
   "configurationItem":{
      "relatedEvents":[

      
      ],
      "relationships":[
         {
            "resourceId":"ANPASP666ZVAXGDCE5SDN",
            "resourceName":"Read_Only_EC2",
            "resourceType":"AWS::IAM::Policy",
            "name":"Is attached to CustomerManagedPolicy"
        
         }
      
      ],
      "configuration":{
         "path":"/",
         "userName":"FoxySugar",
         "userId":"AIDASP666ZVA36XQGO6DD",
         "arn":"arn:aws:iam::9999999999:user/FoxySugar",
         "createDate":"2020-01-07T14:06:13.000Z",
         "userPolicyList":[

         
         ],
         "groupList":[

         
         ],
         "attachedManagedPolicies":[
            {
               "policyName":"Read_Only_EC2",
               "policyArn":"arn:aws:iam::9999999:policy/Read_Only_EC2"
            
            }
         
         ],
         "permissionsBoundary":null,
         "tags":[

         
         ]
      
      },
      "supplementaryConfiguration":{

      
      },
      "tags":{

      
      },
      "configurationItemVersion":"1.3",
      "configurationItemCaptureTime":"2020-03-23T02:02:28.440Z",
      "configurationStateId":1584928948999,
      "awsAccountId":"999999999",
      "configurationItemStatus":"ResourceDiscovered",
      "resourceType":"AWS::IAM::User",
      "resourceId":"AIDASP666ZVA36XQGO6DD",
      "resourceName":"FoxySugar",
      "ARN":"arn:aws:iam::9999999:user/FoxySugar",
      "awsRegion":"global",
      "availabilityZone":"Not Applicable",
      "configurationStateMd5Hash":"",
      "resourceCreationTime":"2020-01-07T14:06:13.000Z"
   
   },
   "notificationCreationTime":"2020-03-23T02:40:01.999Z",
   "messageType":"ConfigurationItemChangeNotification",
   "recordVersion":"1.3"
}



Output:


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
{
   "Evaluations": [ 
      { 
         "Annotation": "string",
         "ComplianceResourceId": "string",
         "ComplianceResourceType": "string",
         "ComplianceType": "string",
         "OrderingTimestamp": number
      }
   ],
   "ResultToken": "string",
   "TestMode": boolean
}
This is from this documentation.

Explanation (Lines):
2: This is array of compliance report. You can include as many as you like.
4. This is optional description
5. This is the ID of the resource
6. This is the resource type, this must be one supported by Config. Click here.
7. This must be one of following:  
  • COMPLIANT
  • NON_COMPLIANT
  • NOT_APPLICABLE
  • INSUFFICIENT_DATA
8. This is timestamp
11. This must be the same ResultToken that function received from Config.
12. If this is set to true, then nothing is actually reported back to Config.  


With this in mind, you should be able to make sense of these sample AWS Config Lambda codes such as one found here.

No comments:

Post a Comment

AWS WAF log4j query

How to query AWS WAF log for log4j attacks 1. Setup your Athena table using this instruction https://docs.aws.amazon.com/athena/latest/ug/wa...