I have an EventBridge rule that captures all resource modifications from Cloudtrail:
{
"source": ["aws.*"],
"detail-type": ["AWS API Call via CloudTrail"],
"detail": {
"eventSource": ["*.amazonaws.com"],
"eventName": ["Create*", "Delete*", "Update*", "Put*", "Attach*", "Detach*", "Modify*", "Set*"]
}
}
Its target is a lambda that was tested with a cloudtrail event, and it works (sends the response to Teams channel webhook).
This is the CF YAML of the rule, so you can have a clearer insight into it:
AWSTemplateFormatVersion: '2010-09-09'
Description: CloudFormation template for EventBridge rule 'infrastructure-drift'
Resources:
EventRule0:
Type: AWS::Events::Rule
Properties:
EventBusName: default
EventPattern:
source:
- aws.*
detail-type:
- AWS API Call via CloudTrail
detail:
eventSource:
- '*.amazonaws.com'
eventName:
- Create*
- Delete*
- Update*
- Put*
- Attach*
- Detach*
- Modify*
- Set*
Name: infrastructure-drift
State: ENABLED
Targets:
- Id: xxx
Arn: arn:aws:lambda:eu-west-1:xxx:function:InfrastructureDrift
I made some manual changes to some resources on my account, which are supposed to trigger the Lambda, but they never did. I can get the lambda to work when I test it with any event from Cloudtrail personally, meaning its formatted well and it does its job. I feel like the issue is with the rule, but I don’t see how, as this looks right to me. I should note that the lambda has right Resource-based policy. Any help appreciated, thank you. Just in case, this is the lambda:
import json
import http.client
def format_json(json_data):
""" Helper function to format JSON data into a pretty-printed string """
return json.dumps(json_data, indent=4)
def lambda_handler(event, context):
try:
# Extract basic information about the event
user_identity = event.get('userIdentity', {}).get('arn', 'Unknown user')
event_name = event.get('eventName', 'Unknown event')
event_time = event.get('eventTime', 'Unknown time')
# Detailed description of the change from requestParameters and responseElements
request_details = format_json(event.get('requestParameters', {}))
response_details = format_json(event.get('responseElements', {}))
# Construct the message to be sent to Teams
message = (f"**Event Time:**n{event_time}nn"
f"**User:**n{user_identity}nn"
f"**Action:**n{event_name}nn"
f"**Request Details:**n```n{request_details}n```nn"
f"**Response Details:**n```n{response_details}n```")
# Teams webhook URL
webhook_url = 'xxx'
conn = http.client.HTTPSConnection("xxx.webhook.office.com")
headers = {'Content-type': 'application/json'}
payload = json.dumps({
"title": "AWS Resource Change Alert",
"text": message
})
conn.request("POST", webhook_url, payload, headers)
response = conn.getresponse()
data = response.read()
return data.decode("utf-8")
except Exception as e:
# Handle generic exceptions and print error details
print(f"Error processing event: {str(e)}")
return str(e)