AWS EventBridge is a serverless event bus service formerly known as CloudWatch Events. It allows applications, AWS services, and supported SaaS partners to publish and react to events in near real-time. Terraform provides declarative management of EventBridge components including event buses, rules with event patterns and schedules, targets such as Lambda, SQS, CloudWatch Logs and API Destination, and related permissions, archives and schedules.
Introduction
Building event-driven architectures with EventBridge requires consistent provisioning of buses, rules, targets and permissions across environments. Using Terraform removes manual console work, enforces version control, and enables repeatable deployments of event patterns, scheduled rules and target wiring. This article covers the core concepts, Terraform resources, module usage, and operational patterns for AWS EventBridge with Terraform.
What AWS EventBridge Is
AWS EventBridge is a serverless event bus service that allows you to listen to events from your applications, supported third-party applications, and AWS services. It simplifies building event-driven architectures by serving as the central event hub and enabling applications to publish, subscribe to, and react to events in near real-time.
AWS EventBridge also provides built-in support for creating schedulers that emit events at scheduled times. Amazon EventBridge is the event bus that ties AWS services together. When an EC2 instance changes state, when a CodePipeline deployment fails, when an S3 object is created, EventBridge can catch those events and route them to targets like Lambda functions, SQS queues, or Step Functions.
EventBridge scheduled rules can also run cron-style scheduled tasks in AWS, although EventBridge Scheduler is the recommended service for new standalone schedules.
Core Concepts
EventBridge has three main concepts:
- Event Bus - Where events arrive. The default bus receives events from AWS services in your account; some services, such as S3 object events, require event delivery to EventBridge to be enabled first
- Rule - Matches events using an event pattern or schedule expression and routes to targets
- Target - The resource invoked when a rule matches, such as Lambda, SQS, CloudWatch Logs, API Destination
The default event bus is automatically configured to receive events from AWS services, like S3:PutObject, which is the event emitted from S3 when an object is created.
A sample S3 event on the default bus:
{
"version": "0",
"id": "17793124-05d4-b198-2fde-7ededc63b103",
"detail-type": "Object Created",
"source": "aws.s3",
"account": "123456789012",
"time": "2021-11-12T00:00:00Z",
"region": "ca-central-1",
"resources": ["arn:aws:s3:::example-bucket"],
"detail": {
"version": "0",
"bucket": {
"name": "example-bucket"
},
"object": {
"key": "example-key",
"size": 5,
"etag": "b1946ac92492d2347c6235b4d2611184",
"version-id": "IYV3p45BT0ac8hjHg1houSdS1a.Mro8e",
"sequencer": "00617F08299329D189"
},
"request-id": "N4N7GDK58NMKJ12R",
"requester": "123456789012",
"source-ip-address": "1.2.3.4",
"reason": "PutObject"
}
}
By default, every event bus can have up to 300 configured rules.
Prerequisites for Terraform Workflows
Setting up Terraform for AWS requires:
- 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 commonly used:
terraform-eventbridge/
├── main.tf
├── variables.tf
├── outputs.tf
├── modules/
│ └── eventbridge/
│ ├── main.tf
│ ├── variables.tf
│ └── outputs.tf
└── patterns/
└── events.json
Managing Event Buses with Terraform
AWS EventBridge already includes a default event bus for every account. This event bus is automatically configured to receive events from AWS services.
To use the default bus with Terraform, declare a data block pointing to the event bus name:
data "aws_cloudwatch_event_bus" "default" {
name = "default"
}
Creating a custom bus:
resource "aws_cloudwatch_event_bus" "main" {
name = "${var.project_name}-bus"
tags = merge(
var.tags,
{
Name = "${var.project_name}-bus"
}
)
}
Event bus policy controls who can put events. Example policy allowing other accounts:
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
}
]
})
}
Configuring EventBridge Rules in Terraform
Rules can be schedule-based or pattern-based.
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 matches incoming events. The event_pattern is a JSON-encoded filter on source, detail-type, resources, and detail fields.
Using Schedulers with Terraform
EventBridge Scheduler is the dedicated service for new standalone schedules. The guide covers using schedulers with Terraform alongside traditional awscloudwatchevent_rule resources.
If you need more than five, create additional rules with the same pattern or fan out through SNS or Step Functions.
Event Targets in EventBridge Using Terraform
Targets are wired with awscloudwatchevent_target. Common targets include Lambda, SQS, CloudWatch Logs, and API Destination.
How do I create a Lambda target for EventBridge in Terraform:
- Define awscloudwatchevent_rule with a pattern or schedule
- Attach awscloudwatchevent_target pointing to the Lambda ARN
- Grant awslambdapermission so EventBridge can invoke the function
Example target wiring with input transformation and dead-letter queue:
module "eventbridge" {
source = "terraform-aws-modules/eventbridge/aws"
bus_name = "my-bus"
log_config = {
include_detail = "FULL"
level = "INFO"
}
log_delivery = {
cloudwatch_logs = {
destination_arn = "arn:aws:logs:us-east-1:123456789012:log-group:my-log-group"
}
s3 = {
destination_arn = "arn:aws:s3:::my-log-bucket"
}
}
rules = {
orders = {
description = "Capture all order data"
event_pattern = jsonencode({ "source" : ["myapp.orders"] })
enabled = true
}
}
targets = {
orders = [
{
name = "send-orders-to-sqs"
arn = aws_sqs_queue.queue.arn
dead_letter_arn = aws_sqs_queue.dlq.arn
},
{
name = "send-orders-to-kinesis"
arn = aws_kinesis_stream.this.arn
dead_letter_arn = aws_sqs_queue.dlq.arn
input_transformer = local.kinesis_input_transformer
},
{
name = "log-orders-to-cloudwatch"
arn = aws_cloudwatch_log_group.this.arn
}
]
}
tags = {
Name = "my-bus"
}
}
Targets can be transformed, retried, and sent to dead-letter queues, and archives can be created for replays.
Monitoring EventBridge with Terraform
Monitoring covers log delivery to CloudWatch Logs and S3, rule invocation metrics, and archive configuration. The module supports:
- AWS EventBridge Archives and Replays
- Conditional creation for many types of resources
- Support IAM policy attachments and various ways to create and attach additional policies
Terraform Module for EventBridge
The terraform-aws-modules/terraform-aws-eventbridge module creates AWS EventBridge Resources (bus, rules, targets, permissions, connections, destinations, pipes, schedules and schedule groups).
Capabilities:
- Creates AWS EventBridge Resources (bus, rules, targets, permissions, connections, destinations, pipes, schedules and schedule groups)
- Attach resources to an existing EventBridge bus
- Support AWS EventBridge Archives and Replays
- Conditional creation for many types of resources
- Support IAM policy attachments and various ways to create and attach additional policies
Most common use-case which creates custom bus, logging, rules and targets.
Minimal module usage:
module "eventbridge" {
source = "terraform-aws-modules/eventbridge/aws"
bus_name = "my-bus"
tags = {
Name = "my-bus"
}
}
Resource Mapping Table
| Terraform Resource | EventBridge Concept | Typical Use |
|---|---|---|
| awscloudwatchevent_bus | Event Bus | Custom bus for app events |
| awscloudwatcheventbuspolicy | Bus Policy | Control PutEvents permissions |
| awscloudwatchevent_rule | Rule | Pattern or schedule matching |
| awscloudwatchevent_target | Target | Wire rule to Lambda, SQS, etc |
| awscloudwatchevent_archive | Archive | Store events for replay |
| awscloudwatcheventapidestination | API Destination | HTTP target delivery |
Limits and Best Practices Table
| Area | Recommendation |
|---|---|
| Rules per bus | Up to 300 configured rules per bus |
| Schedule preference | Use EventBridge Scheduler for new standalone schedules |
| Default bus | Use data source to reference default bus |
| Permissions | Grant minimal PutEvents via bus policy |
| Dead-letter queues | Configure for SQS and Kinesis targets |
| Input transformation | Use input_transformer to reshape payloads |
| Logging | Enable log delivery to CloudWatch Logs and S3 |
| Module usage | Prefer module for bus, logging, rules and targets together |
Best Practices for Terraform and EventBridge Integration
- Use Terraform modules to create event buses, define rules with event patterns, build scheduled rules with both awscloudwatchevent_rule and the dedicated EventBridge Scheduler, wire up Lambda, SQS, CloudWatch Logs, and API Destination targets, transform event payloads, and set up retries, dead-letter queues, and archives
- Keep event patterns in separate JSON files under patterns/ for review
- Tag resources consistently with project name and bus name
- Separate custom buses from default bus to isolate third-party events
- Version Terraform 1.0.0 or later and pin module versions
Conclusion
Terraform provides full lifecycle control over AWS EventBridge components. Event buses can be created and secured with policies, rules can be defined for schedules and event patterns, and targets can be wired to Lambda, SQS, CloudWatch Logs, API Destinations, Kinesis and more with transformations, dead-letter queues and retries. The dedicated EventBridge Scheduler complements classic rules for scheduled workloads. Using the community module streamlines creation of buses, logging, rules and targets with conditional resources and archive support, enabling repeatable, auditable event-driven architectures.