EventBridge rules are the control plane for event-driven architectures in AWS. The aws_cloudwatch_event_rule resource in Terraform provisions CloudWatch Event Rules, which are now marketed as Amazon EventBridge rules. A rule matches incoming events from the default event bus, a custom event bus, or a schedule expression and invokes one or more targets such as Lambda functions, SQS queues, SNS topics, Step Functions state machines, or other AWS services.
The resource manages a CloudWatch Event Rule resource. A minimal configuration to get started. Refer to the Terraform Registry docs for all available arguments.
hcl
resource "aws_cloudwatch_event_rule" "example" {
# Required arguments
name = "my-cloudwatch-event-rule"
}
That minimal block creates a rule named my-cloudwatch-event-rule. In practice production rules require either a schedule expression or an event pattern, and typically a description and an enabled flag.
Core Concepts of EventBridge Rules
Amazon EventBridge, formerly CloudWatch Events, 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.
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 - The matching logic defined by a schedule expression or an event pattern
- Target - The resource invoked when a rule matches
The aws_cloudwatch_event_rule resource creates the rule. Targets are attached with aws_cloudwatch_event_target. The rule itself does not invoke anything until a target is attached.
Argument Reference and Attribute Exports
The following arguments are supported for aws_cloudwatch_event_rule.
| Argument | Type | Required | Description |
|---|---|---|---|
| name | string | Optional / Required* | The rule's name. By default generated by Terraform. Conflicts with name_prefix |
| name_prefix | string | Optional | The rule's name. Conflicts with name |
| schedule_expression | string | Conditional | The scheduling expression. For example, cron(0 20 * * ? *) or rate(5 minutes) |
| event_pattern | string | Conditional | Event pattern described a JSON object. See full documentation of CloudWatch Events and Event Patterns for details |
| description | string | Optional | The description of the rule |
| role_arn | string | Optional | The Amazon Resource Name (ARN) associated with the role that is used for target invocation |
| is_enabled | bool | Optional | Whether the rule should be enabled. Defaults to true |
*Provider documentation varies between name being optional and required. The Terraform Registry historically documents name as optional with Terraform generating a name by default, while some derived docs list name as required. Use explicit name in production.
In addition to all arguments above, the following attributes are exported:
| Attribute | Description |
|---|---|
| arn | The Amazon Resource Name (ARN) of the rule |
Conditional requirement: scheduleexpression is required if eventpattern isn't specified. eventpattern is required if scheduleexpression isn't specified. At least one of the two must be provided for a functional rule.
Event Pattern vs Schedule Expression
Event patterns match events arriving on an event bus. A pattern is a JSON object that filters on fields such as source, detail-type, account, region, and arbitrary detail fields.
hcl
resource "aws_cloudwatch_event_rule" "console" {
name = "capture-aws-sign-in"
description = "Capture each AWS Console Sign In"
event_pattern = <<PATTERN
{
"detail-type": [
"AWS Console Sign In via CloudTrail"
]
}
PATTERN
}
The example captures each AWS Console Sign In via CloudTrail. The rule name is capture-aws-sign-in and the description is Capture each AWS Console Sign In.
Schedule expressions provide time-based triggers. Two formats are supported:
- cron(0 20 * * ? *) - cron style
- rate(5 minutes) - rate based
A common scheduled rule:
hcl
resource "aws_cloudwatch_event_rule" "every_five_minutes" {
name = "every-five-minutes"
schedule_expression = "rate(5 minutes)"
description = "Run cleanup every five minutes"
is_enabled = true
}
When using a schedule, eventpattern is omitted. When using an event pattern, scheduleexpression is omitted.
Example Usage with Targets and SNS
Rules without targets do not do work. Targets are attached via aws_cloudwatch_event_target.
```hcl
resource "awscloudwatcheventrule" "console" {
name = "capture-aws-sign-in"
description = "Capture each AWS Console Sign In"
eventpattern = <
"detail-type": [
"AWS Console Sign In via CloudTrail"
]
}
PATTERN
}
resource "awscloudwatcheventtarget" "sns" {
rule = "${awscloudwatcheventrule.console.name}"
targetid = "SendToSNS"
arn = "${awssnstopic.awslogins.arn}"
}
resource "awssnstopic" "aws_logins" {
name = "aws-console-logins"
}
```
This configuration creates a rule that matches AWS Console Sign In events and forwards them to an SNS topic named aws-console-logins. The target_id is SendToSNS.
The rule name capture-aws-sign-in is used to reference the rule from the target via the rule argument.
Advanced Target Configuration with Dead Letter Queue and Retry Policy
Production event-driven architectures require failure handling. A dead letter queue catches failures and a retry policy controls re-attempts.
```hcl
resource "awssqsqueue" "eventbridgedlq" {
name = "eventbridge-dlq"
messageretention_seconds = 1209600 # 14 days
}
resource "awscloudwatcheventtarget" "withdlq" {
rule = awscloudwatcheventrule.everyfiveminutes.name
targetid = "lambda-with-dlq"
arn = awslambdafunction.cleanup.arn
deadletterconfig {
arn = awssqsqueue.eventbridge_dlq.arn
}
retrypolicy {
maximumeventageinseconds = 3600 # Retry for up to 1 hour
maximumretry_attempts = 3
}
}
```
The DLQ queue is configured with 14 days retention. The retry policy limits retries to 3 attempts within a 1 hour window.
Permissions for the DLQ require a queue policy allowing EventBridge to send messages:
hcl
resource "aws_sqs_queue_policy" "allow_eventbridge_dlq" {
queue_url = aws_sqs_queue.eventbridge_dlq.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Sid = "AllowEventBridgeDLQ"
Effect = "Allow"
Principal = {
Service = "events.amazonaws.com"
}
Action = "sqs:SendMessage"
Resource = aws_sqs_queue.eventbridge_dlq.arn
Condition = {
ArnEquals = {
"aws:SourceArn" = aws_cloudwatch_event_rule.every_five_minutes.arn
}
}
}]
})
}
For monitoring your event-driven architecture end to end, take a look at our guide on CloudWatch alarms with Terraform to set up alerts on failed invocations and DLQ depth.
Related CloudWatch Resources
The aws_cloudwatch_event_rule resource is part of a larger CloudWatch family. Related resources include:
- awscloudwatchalarmmuterule
- awscloudwatchcomposite_alarm
- awscloudwatchcontributorinsightrule
- awscloudwatchcontributormanagedinsight_rule
- awscloudwatchdashboard
- awscloudwatcheventapidestination
- awscloudwatchevent_archive
- awscloudwatchevent_bus
- awscloudwatcheventbuspolicy
- awscloudwatchevent_connection
Custom event buses are created with aws_cloudwatch_event_bus. Rules can be scoped to a custom bus via the event bus parameter on the rule resource, enabling service decoupling.
Importing Existing Rules
Cloudwatch Event Rules can be imported using the name, e.g.
bash
$ terraform import aws_cloudwatch_event_rule.console capture-console-sign-in
Import uses the rule name as the identifier. After import, Terraform state contains the ARN attribute exported by the resource.
Operational Best Practices
EventBridge is one of those AWS services that gets more useful the more you lean into it. Use scheduled rules where they fit, then add event patterns for AWS service events you care about. When your application architecture matures, custom event buses give you a clean way to decouple services.
Enable rules explicitly with isenabled to allow safe rollout and disable without destroying resources. Provide descriptions for every rule to support audit and cost allocation. Use rolearn to restrict the permissions EventBridge uses to invoke targets. For scheduled workloads, prefer EventBridge Scheduler for new standalone schedules as recommended by AWS, reserving classic rules for event matching.
Configure dead letter queues and retry policies for Lambda and Step Functions targets to avoid silent loss of events. Monitor invocation failures and DLQ depth with CloudWatch metrics.
Conclusion
The aws_cloudwatch_event_rule resource provides full lifecycle management for EventBridge rules as code. A minimal declaration creates a named rule, but effective usage requires a choice between scheduleexpression and eventpattern, a descriptive name, optional enable flag, and pairing with aws_cloudwatch_event_target resources. Arguments such as name, nameprefix, scheduleexpression, eventpattern, description, rolearn, and is_enabled control matching and invocation behavior, while the exported arn attribute enables secure cross-resource references and import workflows.
Event patterns enable fine-grained filtering on AWS service events, while schedule expressions provide cron and rate based triggers. Advanced configurations add dead letter queues, retry policies, and custom event buses for resilient, decoupled architectures. Consistent naming, descriptions, and monitoring complete a production-ready EventBridge implementation managed entirely through Terraform.