Terraform and CDK can both manage EventBridge rules and buses, but they approach it with fundamentally different philosophies and strengths.

EventBridge Rules and Buses with Terraform

Terraform excels at declarative infrastructure management. You define the desired state of your EventBridge resources, and Terraform figures out how to get there.

Let’s say you want to create a custom EventBridge bus and a rule that triggers a Lambda function when a specific source event occurs.

Terraform Configuration (main.tf):

provider "aws" {
  region = "us-east-1"
}

resource "aws_cloudwatch_event_bus" "custom_bus" {
  name = "my-custom-event-bus"
}

resource "aws_cloudwatch_event_rule" "my_lambda_rule" {
  name        = "invoke-my-lambda-rule"
  description = "Triggers Lambda on specific events"
  event_bus_name = aws_cloudwatch_event_bus.custom_bus.name
  event_pattern = jsonencode({
    source = ["com.mycompany.myapp"]
    detail-type = ["UserLoggedIn"]
  })

  tags = {
    Environment = "dev"
  }
}

resource "aws_cloudwatch_event_target" "lambda_target" {
  rule      = aws_cloudwatch_event_rule.my_lambda_rule.name
  target_id = "my-lambda-target"
  arn       = "arn:aws:lambda:us-east-1:123456789012:function:my-lambda-function" # Replace with your Lambda ARN
  event_bus_name = aws_cloudwatch_event_bus.custom_bus.name
}

Explanation:

  • aws_cloudwatch_event_bus: This resource defines a custom event bus named my-custom-event-bus. By default, EventBridge has a default bus. Custom buses allow for better organization and isolation of events.
  • aws_cloudwatch_event_rule: This defines a rule named invoke-my-lambda-rule that listens to events on my-custom-event-bus.
    • event_pattern: This is the core of the rule. It’s a JSON string specifying the criteria for an event to be matched. In this case, it matches events where the source is com.mycompany.myapp and the detail-type is UserLoggedIn.
  • aws_cloudwatch_event_target: This resource links the rule to a target. When the rule matches an event, this target will be invoked. Here, it points to a Lambda function.

To run this:

  1. Save the code as main.tf.
  2. Initialize Terraform: terraform init
  3. Review the plan: terraform plan
  4. Apply the changes: terraform apply

EventBridge Rules and Buses with AWS CDK

The AWS Cloud Development Kit (CDK) allows you to define your cloud infrastructure using familiar programming languages, which can offer more dynamic and programmatic control.

Here’s the equivalent setup using TypeScript with the AWS CDK.

CDK Configuration (TypeScript):

import * as cdk from 'aws-cdk-lib';
import * as events from 'aws-cdk-lib/aws-events';
import * as targets from 'aws-cdk-lib/aws-events-targets';
import * as lambda from 'aws-cdk-lib/aws-lambda';
import { Construct } from 'constructs';

export class EventBridgeStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // Define a custom event bus
    const customBus = new events.EventBus(this, 'CustomEventBus', {
      eventBusName: 'my-custom-event-bus-cdk',
    });

    // Assume a Lambda function already exists or define it here
    const myLambda = lambda.Function.fromFunctionName(this, 'MyLambda', 'my-lambda-function-cdk'); // Replace with your Lambda function name

    // Define a rule that matches specific events and targets the Lambda function
    const myRule = new events.Rule(this, 'InvokeMyLambdaRule', {
      eventBus: customBus,
      description: 'Triggers Lambda on specific events',
      eventPattern: {
        source: ['com.mycompany.myapp.cdk'],
        detailType: ['UserLoggedInCDK'],
      },
      targets: [
        new targets.LambdaFunction(myLambda, {
          id: 'MyLambdaTarget',
        }),
      ],
    });
  }
}

Explanation:

  • events.EventBus: This constructs a custom event bus. Similar to Terraform, it allows for custom naming and management.
  • lambda.Function.fromFunctionName: In this example, we’re assuming the Lambda function my-lambda-function-cdk already exists. You could also define a new Lambda function within this stack.
  • events.Rule: This defines the EventBridge rule.
    • eventBus: Associates the rule with the customBus we created.
    • eventPattern: This is an object literal in TypeScript that directly maps to the EventBridge event pattern structure.
    • targets: An array of targets. Here, we instantiate a targets.LambdaFunction to point to our Lambda.

To run this:

  1. Ensure you have Node.js and the AWS CDK installed.
  2. Create a new CDK project or add this stack to an existing one.
  3. Synthesize the CloudFormation template: cdk synth
  4. Deploy the stack: cdk deploy

The Mental Model: Abstraction and Control

Terraform’s strength lies in its declarative nature and broad cloud provider support. You declare what you want, and Terraform figures out how to achieve it using its provider plugins. It’s excellent for managing diverse infrastructure across multiple clouds or services.

The CDK, on the other hand, leverages programming language constructs. This allows for more complex logic, conditional resource creation, and easier integration with application code. You’re essentially writing code that generates CloudFormation (or other IaC templates). This is powerful when you want to build reusable, parameterized infrastructure components or tightly couple infrastructure with your application’s deployment.

A key difference: Terraform manages the state of your infrastructure. It knows what resources it created and how they are configured. The CDK, when deployed, generates CloudFormation, and CloudFormation is the state manager. You interact with the CDK for development, but CloudFormation is what ultimately orchestrates and tracks deployments.

When defining event patterns, both tools use a JSON-like structure. Terraform uses jsonencode to ensure the literal JSON string is passed correctly. The CDK uses native TypeScript objects that are then serialized into the correct JSON format for the EventBridge API.

The most impactful concept is understanding where the "intelligence" resides. With Terraform, it’s in the Terraform engine and its state file. With CDK, it’s in the programming language and the resulting CloudFormation template. This difference dictates how you approach complex scenarios: Terraform for broad, declarative state management; CDK for programmable, application-aware infrastructure.

The next step after defining rules and buses is often to implement robust error handling and dead-letter queues for your EventBridge targets, ensuring that events are not lost if a target fails to process them.

Want structured learning?

Take the full Eventbridge course →