Real-time AWS security monitoring solution that sends instant Slack notifications for critical security events across all regions. Deploy with just 2 commands!
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β us-east-1 (Primary) β
β ββββββββββββββ βββββββββββββββ βββββββββββββββββββββββββββ β
β β CloudTrail βββ S3 + KMS β β Lambda Functions β β
β βMulti-Regionβ β Secure Logs β β βββββββββββββββββββββββ β β
β ββββββββββββββ βββββββββββββββ β β IAM βConsoleβEC2 β β β
β β βSecretsβRDS Handler β β β
β βββββββββββββββββββββββββββββββ β βββββββββββββββββββββββ β β
β β Security EventBus β βββββββββββββββββββββββββββ β
β βββββββββββββββββββββββββββββββ β β
βββββββββββββββββββββββββββββββββββββββββββββββββββΌββββββββββββββ
β
ββββββΌβββββ
β Slack β
βWebhook β
βββββββββββ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β ap-northeast-2 (Regional) β
β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β EventBridge Rules β β
β β βββββββββββ ββββββββββββββββββββ βββββββββββββββ β β
β β β EC2 β β Secrets Manager β β RDS β β β
β β β Rule β β Rule β β Rule β β β
β β βββββββββββ ββββββββββββββββββββ βββββββββββββββ β β
β βββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββ β
β β Cross-Region Forward β
ββββββββββββββββββββββΌββββββββββββββββββββββββββββββββββββββββ
β
β²
- AWS CLI configured with appropriate permissions
- Slack webhook URL (Setup Guide)
# 1. Deploy Primary Region (us-east-1)
aws cloudformation deploy \
--template-file multi-region-security-monitoring.yaml \
--stack-name aws-security-monitoring \
--parameter-overrides \
SlackWebhookUrl="https://hooks.slack.com/services/YOUR/SLACK/WEBHOOK" \
AllowedIpAddresses="192.168.1.1" \
DeploymentType="Primary" \
--capabilities CAPABILITY_NAMED_IAM \
--region us-east-1
# 2. Deploy Regional (any additional region)
aws cloudformation deploy \
--template-file multi-region-security-monitoring.yaml \
--stack-name aws-security-monitoring-regional \
--parameter-overrides \
SlackWebhookUrl="https://hooks.slack.com/services/YOUR/SLACK/WEBHOOK" \
AllowedIpAddresses="192.168.1.1" \
DeploymentType="Regional" \
PrimaryRegion="us-east-1" \
--capabilities CAPABILITY_NAMED_IAM \
--region ap-northeast-2| Service | Events | Risk Level | Trigger Conditions |
|---|---|---|---|
| π IAM | User/Policy changes, Access Keys | π΄ High | Unauthorized IP, Privilege escalation |
| π₯οΈ Console | Login attempts (success/failure) | π‘ Medium | Root login, No MFA, Unknown IP |
| π Secrets Manager | Secret access/modification | π΄ Critical | Policy changes, Value retrieval |
| π₯οΈ EC2 | Security Group changes, SSH access | π High | 0.0.0.0/0 rules, Instance Connect |
| πΎ RDS | HTTP Endpoint exposure | π΄ Critical | Data API enablement |
| Parameter | Description | Default | Example |
|---|---|---|---|
SlackWebhookUrl |
Slack webhook for notifications | Required | https://hooks.slack.com/services/... |
AllowedIpAddresses |
Trusted IPs (no channel alerts) | 127.0.0.1 |
192.168.1.1,10.0.0.1,203.0.113.1 |
DeploymentType |
Primary or Regional deployment | Primary |
Primary / Regional |
PrimaryRegion |
Central processing region | us-east-1 |
us-east-1 |
S3BucketSuffix |
CloudTrail S3 bucket suffix | security |
security-prod |
TrailName |
CloudTrail name | security-cloudtrail |
security-trail-prod |
π S3 Bucket Settings
CloudTrailS3Bucket:
Properties:
BucketName: !Sub cloudtrail-${AWS::AccountId}-${S3BucketSuffix}
# π Security Settings
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: AES256 # Change to aws:kms for KMS encryption
KMSMasterKeyID: !Ref KMSKey # Uncomment for KMS
# π« Access Control
PublicAccessBlockConfiguration:
BlockPublicAcls: true # Prevent public ACLs
IgnorePublicAcls: true # Ignore existing public ACLs
BlockPublicPolicy: true # Block public bucket policies
RestrictPublicBuckets: true # Restrict public bucket access
# π Versioning
VersioningConfiguration:
Status: Enabled # Change to Suspended to disable
# ποΈ Lifecycle Management (Add if needed)
# LifecycleConfiguration:
# Rules:
# - Id: DeleteOldLogs
# Status: Enabled
# ExpirationInDays: 365 # Delete logs after 1 year
# Transitions:
# - TransitionInDays: 30
# StorageClass: STANDARD_IA
# - TransitionInDays: 90
# StorageClass: GLACIERCustomization Options:
- π Encryption: Switch from AES256 to KMS for advanced key management
- π Retention: Add lifecycle rules for automatic log cleanup
- π° Cost Optimization: Configure storage class transitions
- π Naming: Modify bucket naming pattern for your organization
π CloudTrail Advanced Settings
CloudTrail:
Properties:
TrailName: !Sub ${TrailName}-${AWS::StackName}
S3BucketName: !Ref CloudTrailS3Bucket
# π Logging Configuration
IsLogging: true # Enable/disable logging
IsMultiRegionTrail: true # Capture all regions
IncludeGlobalServiceEvents: true # Include IAM, CloudFront, Route53
EnableLogFileValidation: true # Integrity checking
# π Encryption
KMSKeyId: !Ref CloudTrailKMSKey # Remove for S3-managed encryption
# π― Event Filtering
AdvancedEventSelectors:
- Name: Management events selector
FieldSelectors:
- Field: eventCategory
Equals: [Management]
# Add additional selectors:
# - Field: eventName
# NotEquals: ["DescribeInstances", "ListObjects"]
# - Field: eventSource
# Equals: ["ec2.amazonaws.com", "iam.amazonaws.com"]
# π SNS Integration (Optional)
# SNSTopicName: !Ref CloudTrailTopic
# π CloudWatch Integration (Optional)
# CloudWatchLogsLogGroupArn: !GetAtt LogGroup.Arn
# CloudWatchLogsRoleArn: !GetAtt CloudWatchRole.ArnCustomization Options:
- π Event Filtering: Fine-tune which events to capture
- π CloudWatch: Enable CloudWatch Logs integration
- π§ SNS: Add SNS notifications for trail delivery
- π Regional: Switch to single-region trail for cost savings
π οΈ Runtime & Performance Settings
# Global Lambda Configuration
Runtime: python3.10 # python3.11, python3.12 available
Timeout: 30 # Seconds (max 900)
MemorySize: 128 # MB (128-10240, 64MB increments)
# Environment Variables
Environment:
Variables:
HOOK_URL: !Ref SlackWebhookUrl
ALLOWED_IP: !Ref AllowedIpAddresses
# Add custom variables:
# LOG_LEVEL: INFO
# RETRY_COUNT: 3
# TIMEOUT_SECONDS: 10
# Function-Specific Overrides (example)
IAMEventHandlerFunction:
Properties:
Timeout: 60 # Longer timeout for complex IAM events
MemorySize: 256 # More memory for large IAM policies
EC2EventHandlerFunction:
Properties:
ReservedConcurrencyConfiguration:
ReservedConcurrency: 5 # Limit concurrent executionsPerformance Tuning:
- β‘ Memory: Increase for faster execution
- β±οΈ Timeout: Adjust based on Slack response times
- π Concurrency: Set reserved concurrency for cost control
- π Monitoring: Add X-Ray tracing for debugging
π IAM Permissions & Security
LambdaExecutionRole:
Properties:
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
# Custom Policies (if needed)
Policies:
- PolicyName: CustomLoggingPolicy
PolicyDocument:
Statement:
- Effect: Allow
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
# - secretsmanager:GetSecretValue # For webhook secrets
# - kms:Decrypt # For encrypted parameters
Resource: "*"
# VPC Configuration (if required)
# VpcConfig:
# SecurityGroupIds:
# - !Ref LambdaSecurityGroup
# SubnetIds:
# - !Ref PrivateSubnet1
# - !Ref PrivateSubnet2Security Enhancements:
- π Secrets: Store webhook URL in AWS Secrets Manager
- π VPC: Deploy in VPC for network isolation
- π‘οΈ Security Groups: Restrict outbound traffic
- π Least Privilege: Minimize IAM permissions
π― Event Pattern Customization
# Example: Customize IAM Events
IAMEventRule:
Properties:
EventPattern:
source: ["aws.iam"]
detail-type: ["AWS API Call via CloudTrail"]
detail:
eventSource: ["iam.amazonaws.com"]
eventName: [
"CreateUser", "DeleteUser",
"AttachUserPolicy", "DetachUserPolicy",
# Add/remove events as needed:
# "CreateRole", "DeleteRole",
# "PutUserPolicy", "DeleteUserPolicy"
]
# Additional filters:
# userIdentity:
# type: ["IAMUser", "Root"]
# requestParameters:
# userName: [{"exists": true}]Advanced Filtering:
- π€ User Types: Filter by Root, IAMUser, AssumedRole
- π Regions: Limit to specific regions
- π Parameters: Filter by request parameters
- β° Time Windows: Add time-based conditions
π Cross-Region Event Routing
# Regional Event Rules (Forward to Primary)
EC2EventRule:
Condition: IsRegionalOnly
Properties:
EventBusName: default
Targets:
- Id: EC2CrossRegionTarget
Arn: !Sub arn:aws:events:${PrimaryRegion}:${AWS::AccountId}:event-bus/security-event-bus
RoleArn: !GetAtt CrossRegionEventRole.Arn
# Transformation (Optional)
# HttpParameters:
# HeaderParameters:
# X-Source-Region: ap-northeast-2
# InputTransformer:
# InputPathsMap:
# region: "$.detail.awsRegion"
# InputTemplate: |
# {
# "source-region": "<region>",
# "event": <aws.events.event>
# }Routing Options:
- π Event Transformation: Modify events during routing
- π Dead Letter Queues: Handle failed deliveries
- β‘ Retry Logic: Configure retry attempts
- π Metrics: Add custom CloudWatch metrics
β Stack Creation Failed
Error: The resource CloudTrailS3Bucket is in a CREATE_FAILED state
Solutions:
- Bucket name conflict: Change
S3BucketSuffixparameter - Permission issues: Ensure AWS CLI has sufficient permissions
- Region availability: Some services not available in all regions
# Check bucket availability
aws s3api head-bucket --bucket cloudtrail-123456789012-security 2>/dev/null || echo "Bucket available"
# Validate template
aws cloudformation validate-template --template-body file://multi-region-security-monitoring.yamlπ No Slack Notifications
Troubleshooting Steps:
- Test Webhook URL:
curl -X POST -H 'Content-type: application/json' \
--data '{"text":"Test from AWS Security Monitoring"}' \
YOUR_SLACK_WEBHOOK_URL- Check Lambda Logs:
aws logs filter-log-events \
--log-group-name "/aws/lambda/IAMEventHandler" \
--start-time $(date -d "1 hour ago" +%s)000 \
--region us-east-1- Verify EventBridge Rules:
aws events list-rules --region us-east-1
aws events list-targets-by-rule --rule IAMEventRule --region us-east-1- Test Lambda Function:
aws lambda invoke \
--function-name IAMEventHandler \
--payload '{"Records":[{"eventSource":"aws:iam","eventName":"CreateUser"}]}' \
response.jsonπ Cross-Region Issues
Common Problems:
- Regional stack deployed before Primary
- Cross-region IAM role permissions
- EventBus not accessible
Solutions:
# Verify EventBus exists
aws events describe-event-bus --name security-event-bus --region us-east-1
# Check cross-region role
aws iam get-role --role-name aws-security-monitoring-regional-cross-region-role
# Test cross-region permissions
aws events put-events \
--entries Source=test,DetailType=test,Detail='{}' \
--endpoint-url https://events.us-east-1.amazonaws.com \
--region ap-northeast-2| Service | Usage | Cost |
|---|---|---|
| CloudTrail | 1 trail | $2.00 |
| S3 Storage | 1GB logs/month | $0.02 |
| Lambda | 1000 invocations | $0.20 |
| EventBridge | 1M events | $1.00 |
| Total | ~$3.22/month |
- Log Lifecycle: Implement S3 lifecycle policies
- Event Filtering: Reduce unnecessary Lambda invocations
- Reserved Concurrency: Prevent cost spikes
- Regional Selection: Deploy only in required regions
- Scalability: Make easy to scale more event with lambda functions
- Enhanced Filtering: Custom event filtering rules
- Response Automation: Auto-remediation for common issues
- Free to use and modify for your AWS environments
- Community contributions welcome via GitHub issues/PRs
- Fork this repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Create a Pull Request
Q: Can I add custom event sources?
A: Yes! Add new EventBridge rules and Lambda functions:
- Copy existing handler (e.g.,
EC2EventHandler) - Modify event pattern in the template
- Update Lambda code for new service
- Redeploy stack
Q: How do I modify alert messages?
A: Edit the Lambda function code in the YAML template. Look for the create_base_slack_message and add_fields_to_message methods.
Q: Can I use Microsoft Teams instead of Slack?
A: Yes! Change the webhook URL format and modify the message payload structure in the Lambda code.
Q: How do I exclude certain events?
A: Modify the EventPattern in the EventBridge rules to exclude specific events or add filters in the Lambda code.
Q: Is this production-ready?
A: Yes, with additional considerations:
- Store webhook URLs in Secrets Manager
- Add comprehensive error handling
- Implement proper monitoring and alerting
- Regular security reviews and updates

