Search code examples
amazon-web-servicesamazon-cloudwatchamazon-cloudtrailamazon-waf

Input Transformation in CloudWatch EventBridge Rule


I have a simple requirement to send notification on update of WAF rules. For this I created a cloud trail event for management events. In ClouWatch eventbridge I added a new rule with Event Pattern as :

    {
  "source": ["aws.waf", "aws.wafv2"],
  "detail-type": ["AWS API Call via CloudTrail"],
  "detail": {
    "eventSource": ["waf.amazonaws.com", "wafv2.amazonaws.com"],
    "eventName": ["UpdateWebACL", "CreateWebACL", "DeleteWebACL", "UpdateRule", "CreateRule", "DeleteRule", "UpdateRuleGroup", "CreateRuleGroup", "DeleteRuleGroup"]
  }
}

In Target I gave my SNS topic and as Input Transformation I gave :

{
    "eventName": "$.details.eventName",
    "timestamp": "$.time",
    "user": "$.details.userIdentity.userName",
    "webACLName": "$.details.requestParameters.name"
}

And a simple template :

"EventName: <eventName>"
"WebACL: <webACLName>"
"Time: \"<timestamp>\""
"User: <user>"

When a webACL is updated it is sending me the notification but other than time the other information are empty.

I could not find API Trail under event "AWS events" as shown [![Input Configuration][1]][1]

If instead of "Input Transformation" I choose "Part of matched event" and then give $.details in "Specify the part of the matched event", I can see the below details

{
    "eventVersion": "1.08",
    "userIdentity": {
        "type": "IAMUser",
        "principalId": "xxxxxx",
        "arn": "arn:aws:iam::xxx:user/test",
        "accountId": "xxxx",
        "accessKeyId": "xxxx",
        "userName": "test",
        "sessionContext": {
            "sessionIssuer": {},
            "webIdFederationData": {},
            "attributes": {
                "creationDate": "2024-09-03T17:45:01Z",
                "mfaAuthenticated": "false"
            }
        }
    },
    "eventTime": "2024-09-04T05:44:42Z",
    "eventSource": "wafv2.amazonaws.com",
    "eventName": "CreateWebACL",
    "awsRegion": "us-east-1",
    "sourceIPAddress": "xx.xx.xx.xx",
    "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36",
    "requestParameters": {
        "name": "testwaf",
        "scope": "REGIONAL",
        "defaultAction": {
            "allow": {}
        },
        "rules": [
            {
                "name": "AWS-AWSManagedRulesCommonRuleSet",
                "priority": 0,
                "statement": {
                    "managedRuleGroupStatement": {
                        "vendorName": "AWS",
                        "name": "AWSManagedRulesCommonRuleSet",
                        "excludedRules": [],
                        "ruleActionOverrides": [
                            {
                                "name": "CrossSiteScripting_BODY",
                                "actionToUse": {
                                    "count": {}
                                }
                            },
  :
                            {
                                "name": "UserAgent_BadBots_HEADER",
                                "actionToUse": {
                                    "count": {}
                                }
                            }
                        ]
                    }
                },
                "overrideAction": {
                    "none": {}
                },
                "visibilityConfig": {
                    "sampledRequestsEnabled": true,
                    "cloudWatchMetricsEnabled": true,
                    "metricName": "AWS-AWSManagedRulesCommonRuleSet"
                }
            }
        ],
        "visibilityConfig": {
            "sampledRequestsEnabled": true,
            "cloudWatchMetricsEnabled": true,
            "metricName": "testwaf"
        },
        "associationConfig": {}
    },
    "responseElements": {
        "summary": {
            "name": "testwaf",
            "id": "xxxe",
            "description": "",
            "lockToken": "xxxx",
            "aRN": "arn:aws:wafv2:us-east-1:xxxx:regional/webacl/testwaf/xxx"
        }
    },
    "requestID": "xxx",
    "eventID": "xxx",
    "readOnly": false,
    "eventType": "AwsApiCall",
    "apiVersion": "2019-04-23",
    "managementEvent": true,
    "recipientAccountId": "xxx",
    "eventCategory": "Management",
    "tlsDetails": {
        "tlsVersion": "TLSv1.3",
        "cipherSuite": "TLS_AES_128_GCM_SHA256",
        "clientProvidedHostHeader": "wafv2.us-east-1.amazonaws.com"
    },
    "sessionCredentialFromConsole": "true"
}

Is there any straightforward transformation to get the values from the event or should I use lambda and custom logic to extract the details.

Thanks [1]: https://i.sstatic.net/AoICKp8J.png


Solution

  • can you change your input transformation from $.details to $.detail and try:

    old:

    {
        "eventName": "$.details.eventName",
        "timestamp": "$.time",
        "user": "$.details.userIdentity.userName",
        "webACLName": "$.details.requestParameters.name"
    }
    
    

    corrected:

    {
        "eventName": "$.detail.eventName",
        "timestamp": "$.time",
        "user": "$.detail.userIdentity.userName",
        "webACLName": "$.detail.requestParameters.name"
    }
    
    

    documentation for refernace: https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-transform-target-input.html