Setting up AWS EventBridge Rules with Terraform
Learn how to create and manage AWS EventBridge rules using Terraform, including event patterns, schedules, and targets
Setting up AWS EventBridge Rules with Terraform
AWS EventBridge (formerly CloudWatch Events) is a serverless event bus service. This guide demonstrates how to set up and manage EventBridge rules using Terraform.
Video Tutorial
Learn more about managing AWS EventBridge with Terraform in this comprehensive video tutorial:
Prerequisites
- AWS CLI configured with appropriate permissions
- Terraform installed (version 1.0.0 or later)
- Basic understanding of event-driven architectures
- Familiarity with JSON/YAML
Project Structure
terraform-eventbridge/
├── main.tf
├── variables.tf
├── outputs.tf
├── modules/
│ └── eventbridge/
│ ├── main.tf
│ ├── variables.tf
│ └── outputs.tf
└── patterns/
└── events.json
EventBridge Configuration
Create modules/eventbridge/main.tf
:
# Event Bus
resource "aws_cloudwatch_event_bus" "main" {
name = "${var.project_name}-bus"
tags = merge(
var.tags,
{
Name = "${var.project_name}-bus"
}
)
}
# Event Bus Policy
resource "aws_cloudwatch_event_bus_policy" "main" {
event_bus_name = aws_cloudwatch_event_bus.main.name
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Sid = "AllowOtherAccountsPutEvents"
Effect = "Allow"
Principal = {
AWS = var.allowed_account_ids
}
Action = "events:PutEvents"
Resource = aws_cloudwatch_event_bus.main.arn
}
]
})
}
# Schedule Rule
resource "aws_cloudwatch_event_rule" "schedule" {
name = "${var.project_name}-schedule"
description = "Schedule-based rule"
event_bus_name = aws_cloudwatch_event_bus.main.name
schedule_expression = "rate(5 minutes)"
tags = merge(
var.tags,
{
Name = "${var.project_name}-schedule"
}
)
}
# Pattern-based Rule
resource "aws_cloudwatch_event_rule" "pattern" {
name = "${var.project_name}-pattern"
description = "Pattern-based rule"
event_bus_name = aws_cloudwatch_event_bus.main.name
event_pattern = jsonencode({
source = ["aws.ec2"]
detail-type = ["EC2 Instance State-change Notification"]
detail = {
state = ["running", "stopped"]
}
})
tags = merge(
var.tags,
{
Name = "${var.project_name}-pattern"
}
)
}
# Lambda Target
resource "aws_cloudwatch_event_target" "lambda" {
rule = aws_cloudwatch_event_rule.pattern.name
event_bus_name = aws_cloudwatch_event_bus.main.name
target_id = "SendToLambda"
arn = aws_lambda_function.handler.arn
retry_policy {
maximum_event_age_in_seconds = 3600
maximum_retry_attempts = 3
}
dead_letter_config {
arn = aws_sqs_queue.dlq.arn
}
}
# SQS Target
resource "aws_cloudwatch_event_target" "sqs" {
rule = aws_cloudwatch_event_rule.schedule.name
event_bus_name = aws_cloudwatch_event_bus.main.name
target_id = "SendToSQS"
arn = aws_sqs_queue.main.arn
input_transformer {
input_paths = {
time = "$.time"
id = "$.id"
}
input_template = "{\\"timestamp\\": <time>, \\"event_id\\": <id>}"
}
}
# SNS Target
resource "aws_cloudwatch_event_target" "sns" {
rule = aws_cloudwatch_event_rule.pattern.name
event_bus_name = aws_cloudwatch_event_bus.main.name
target_id = "SendToSNS"
arn = aws_sns_topic.notifications.arn
input_path = "$.detail"
}
# Step Functions Target
resource "aws_cloudwatch_event_target" "step_functions" {
rule = aws_cloudwatch_event_rule.pattern.name
event_bus_name = aws_cloudwatch_event_bus.main.name
target_id = "SendToStepFunctions"
arn = aws_sfn_state_machine.main.arn
role_arn = aws_iam_role.events.arn
}
# Kinesis Target
resource "aws_cloudwatch_event_target" "kinesis" {
rule = aws_cloudwatch_event_rule.pattern.name
event_bus_name = aws_cloudwatch_event_bus.main.name
target_id = "SendToKinesis"
arn = aws_kinesis_stream.main.arn
role_arn = aws_iam_role.events.arn
kinesis_target {
partition_key_path = "$.id"
}
}
# API Destination Target
resource "aws_cloudwatch_event_api_destination" "webhook" {
name = "${var.project_name}-webhook"
description = "Webhook destination"
invocation_endpoint = "https://api.example.com/webhook"
http_method = "POST"
invocation_rate_limit_per_second = 10
connection_arn = aws_cloudwatch_event_connection.webhook.arn
}
resource "aws_cloudwatch_event_connection" "webhook" {
name = "${var.project_name}-webhook-connection"
description = "Webhook connection"
authorization_type = "API_KEY"
auth_parameters {
api_key {
key = "Authorization"
value = var.webhook_api_key
}
}
}
resource "aws_cloudwatch_event_target" "api_destination" {
rule = aws_cloudwatch_event_rule.pattern.name
event_bus_name = aws_cloudwatch_event_bus.main.name
target_id = "SendToWebhook"
arn = aws_cloudwatch_event_api_destination.webhook.arn
role_arn = aws_iam_role.events.arn
}
Event Patterns
- EC2 State Changes
resource "aws_cloudwatch_event_rule" "ec2_state" {
name = "${var.project_name}-ec2-state"
description = "Track EC2 state changes"
event_bus_name = aws_cloudwatch_event_bus.main.name
event_pattern = jsonencode({
source = ["aws.ec2"]
detail-type = ["EC2 Instance State-change Notification"]
detail = {
state = ["running", "stopped", "terminated"]
}
})
}
- S3 Events
resource "aws_cloudwatch_event_rule" "s3_events" {
name = "${var.project_name}-s3-events"
description = "Track S3 object events"
event_bus_name = aws_cloudwatch_event_bus.main.name
event_pattern = jsonencode({
source = ["aws.s3"]
detail-type = ["AWS API Call via CloudTrail"]
detail = {
eventSource = ["s3.amazonaws.com"]
eventName = ["PutObject", "DeleteObject"]
}
})
}
- Custom Events
resource "aws_cloudwatch_event_rule" "custom" {
name = "${var.project_name}-custom"
description = "Handle custom application events"
event_bus_name = aws_cloudwatch_event_bus.main.name
event_pattern = jsonencode({
source = ["custom.myapp"]
detail-type = ["UserSignup", "OrderPlaced"]
detail = {
status = ["success", "failure"]
}
})
}
Schedule Patterns
- Cron Expression
resource "aws_cloudwatch_event_rule" "cron" {
name = "${var.project_name}-cron"
description = "Run on specific schedule"
event_bus_name = aws_cloudwatch_event_bus.main.name
schedule_expression = "cron(0 12 * * ? *)"
}
- Rate Expression
resource "aws_cloudwatch_event_rule" "rate" {
name = "${var.project_name}-rate"
description = "Run at regular intervals"
event_bus_name = aws_cloudwatch_event_bus.main.name
schedule_expression = "rate(5 minutes)"
}
Input Transformation
- JSON Path
resource "aws_cloudwatch_event_target" "transform" {
rule = aws_cloudwatch_event_rule.pattern.name
event_bus_name = aws_cloudwatch_event_bus.main.name
target_id = "TransformInput"
arn = aws_lambda_function.handler.arn
input_transformer {
input_paths = {
instance = "$.detail.instance-id"
state = "$.detail.state"
time = "$.time"
}
input_template = <<EOF
{
"instanceId": <instance>,
"currentState": <state>,
"timestamp": <time>
}
EOF
}
}
Monitoring and Alerts
- CloudWatch Metrics
resource "aws_cloudwatch_metric_alarm" "failed_invocations" {
alarm_name = "${var.project_name}-failed-invocations"
comparison_operator = "GreaterThanThreshold"
evaluation_periods = "1"
metric_name = "FailedInvocations"
namespace = "AWS/Events"
period = "300"
statistic = "Sum"
threshold = "0"
alarm_description = "EventBridge rule invocation failed"
alarm_actions = [aws_sns_topic.alerts.arn]
dimensions = {
RuleName = aws_cloudwatch_event_rule.pattern.name
}
}
- Dead Letter Queue
resource "aws_sqs_queue" "dlq" {
name = "${var.project_name}-dlq"
tags = merge(
var.tags,
{
Name = "${var.project_name}-dlq"
}
)
}
resource "aws_cloudwatch_event_target" "with_dlq" {
rule = aws_cloudwatch_event_rule.pattern.name
event_bus_name = aws_cloudwatch_event_bus.main.name
target_id = "WithDLQ"
arn = aws_lambda_function.handler.arn
dead_letter_config {
arn = aws_sqs_queue.dlq.arn
}
}
Best Practices
-
Event Bus Design
- Use custom event buses
- Implement proper permissions
- Define clear event patterns
- Use meaningful names
-
Target Configuration
- Implement retries
- Configure DLQ
- Transform inputs
- Monitor failures
-
Security
- Use IAM roles
- Implement encryption
- Control access
- Monitor usage
-
Performance
- Optimize event patterns
- Configure batch size
- Monitor latency
- Handle failures
Conclusion
You’ve learned how to set up and manage AWS EventBridge using Terraform. This setup provides:
- Event routing
- Schedule-based execution
- Target integration
- Monitoring capabilities
Remember to:
- Design clear event patterns
- Implement proper error handling
- Monitor rule execution
- Optimize performance