Skip to content

Terraform module for managing an AWS EventBridge event bus

License

Notifications You must be signed in to change notification settings

proactiveops/eventbus

Repository files navigation

EventBus++ for Amazon EventBridge

EventBus++ is a Terraform module for deploying a managed instance of Amazon’s EventBridge and associated services. The instance is configured with sane defaults and options to extend the functionality for the needs of your application.

Using this Module

The most minimal implementation of this module can be deployed by including the following terraform block:

module "eventbus_example" {
  source = "git::ssh://[email protected]/proactiveops/eventbus?ref=main"

  name = "example"

  tags = {
    environment = "dev"
  }
}

In the example above a new EventBridge instance will be deployed with the name example-dev.

Debugging targets

EventBus++ makes it easy to enable debugging on a cross bus rule. When enabled on a target it logs all events to a CloudWatch Log group.

debug is optional and it defaults to false. When set to true to create all the necessary resources required for debugging rules managed by EventBus++.

You can configure this feature with the following code

module "eventbus_debug" {
  source = "git::ssh://[email protected]/proactiveops/eventbus?ref=main"

  name = "example"
  # ...
  cross_bus_rules = [
    {
      name       = "cross_bus_test_rule",
      pattern    = jsonencode({ "source" = ["event-source"] }),
      target_arn = "arn:aws:events:us-east-1:012345678910:event-bus/target"
      debug      = true
    }
  ]

  tags = {
    environment = "dev"
  }
}

Adding Dead Letter Queues

For most rules there should be a Dead Letter Queue (DLQ). EventBus++ makes it easy to configure a DLQ for a cross bus rule. The 'dlq_arn' property is optional, so if it is omitted it won't be configured.

You can configure this feature with the following code:

module "eventbus_dlq" {
  source = "git::ssh://[email protected]/proactiveops/eventbus?ref=main"

  name = "example"
  # ...
  cross_bus_rules = [
    {
      name       = "cross_bus_test_rule",
      pattern    = jsonencode({ "source" = ["event-source"] }),
      target_arn = "arn:aws:events:us-east-1:012345678910:event-bus/target"
      dlq_arn    = module.eventbus_dlq_config.dlq_arn
    }
  ]

  tags = {
    environment = "dev"
  }
}

EventBus++ includes a sub module for creating an encrypted SQS queue that can be used as a DLQ. This queue created by the DLQ sub module can be passed to a cross bus rule via the dlq\_arn property in the rule config. See the DLQ submodule for details on how to use this module.

Rules

Within AWS EventBridge event routing is broken up into two parts - rules and targets. Rules specify a pattern to match events. The rule doesn’t route the event.

While it is possible to implement complex rules for matching events, this can make debugging in production more difficult. Aim for simpler rules where ever possible, your future self will thank you.

Here is an example of a simple rule which matches all deployment completed events.

resource "aws_cloudwatch_event_rule" "example_deployment_complete" {
  name           = "deployments-complete"
  description    = "Capture deployment complete events from my-service"
  event_bus_name = module.eventbus_example.eventbridge.name # Needed so we listen to the correct bridge instance.

  event_pattern = jsonencode({
    "source" : ["my-service"],
    "detail-type" : ["deployment-completed"]
  })
}

Amazon’s documentation on event pattern matching provides more examples of matching rules. For full details of the configuration options for the aws_cloudwatch_event_rule resource, refer to the terraform documentation.

The default limit of rules per event bus is 300. This can be raised by requesting a quota increase if you have a business need for a higher quota.

Targets

Once we have our rules, we need to use targets to route our events to another service.

In this example we are routing our deployment complete events to an SQS queue in the same account.

resource "aws_cloudwatch_event_target" "example_deployment_complete_to_sqs" {
  rule           = aws_cloudwatch_event_rule.example_deployment_complete.name
  target_id      = "example-deployment-complete-to-sqs"
  arn            = aws_sqs_queue.this.arn
  event_bus_name = aws_cloudwatch_event_rule.example_deployment_complete.event_bus_name
}

You may need to configure the resource policy on the target resource before it accepts your events. Amazon provides example resource policies for common services.

For other resources or cross account routing you will need to provision an IAM role for the bridge to assume when sending the events.

If you need to route events from one EventBus++ instance to another, you can use the cross_bus_rules variable to simplify your setup. Each map in the list will provision the rule, target and IAM role for you. Each name property must be unique for each bus to avoid conflicts. The pattern property is any valid event matching pattern. See rules section above for event pattern matching configuration.

module "eventbus_example" {
  source = "git::ssh://[email protected]/proactiveops/eventbus?ref=main"

  name = "example"

  cross_bus_rules = [
    {
      name       = "cross_bus_test_rule",
      pattern    = jsonencode({ "source" = ["event-source"] }),
      target_arn = "arn:aws:events:us-east-1:012345678910:event-bus/target"
      debug      = true
    },
    # ...
  ]

  tags = {
    environment = "dev"
  }
}

The list of supported EventBridge targets is growing all the time. If a target isn’t supported, you can use a Lambda function to invoke the API call with your event payload.

For all available configuration options for the aws_cloudwatch_event_target resource, refer to the terraform documentation.

Both the AWS and terraform documentation provide examples of using input transformers to manipulate events before sending them to the target. This is a useful feature if you only need some of the event payload to be sent to the target.

Receiving Events

Each EventBridge instance provisioned by EventBus++ has a resource policy attached to it that implements IAM controls, so that roles in the same account can be granted access to the bridge. Granting the events:PutEvents action on your bridge resource is enough to allow the role access.

When sending events from another account, additional configuration is required. The allow_put_events_arns variable allows you to specify a list of EventBridge rule ARNs that can send events to the bridge. An example of this is included below.

module "eventbus_put_events" {
  source = "git::ssh://[email protected]/proactiveops/eventbus?ref=main"

  name = "example"

  allow_put_events_arns = [
    "arn:aws:events:us-east-1:012345678910:rule/EventBus-example-dev/my-rule",
    # ...
  ]

  tags = {
    environment = "dev"
  }
}

If you require more complex rules, you can pass a list of data.aws_iam_policy_document.json strings to the EventBus++ module using the bus_policy_docs variable. An example of this is included below.

data "aws_iam_policy_document" "example_document" {
  # ...
}

module "eventbus_bus_policies" {
  source = "git::ssh://[email protected]/proactiveops/eventbus?ref=main"

  name = "example"

  bus_policy_docs = [data.aws_iam_policy_document.example_document.json]

  allow_put_events_arns = [
    "arn:aws:events:us-east-1:012345678910:rule/EventBus-example-dev/my-rule",
    # ...
  ]

  tags = {
    environment = "dev"
  }
}

dlq Sub Module

The dlq sub module provisions a new SQS queue that can be used as Dead Letter Queue (DLQ). It will optionally create a new KMS key for encrypting the messages at rest.

A single DLQ can be used for more than one rule.

Add the sub module to your terraform module like so:

module "eventbus_dlq_example" {
  source = "git::ssh://[email protected]/proactiveops/eventbus//modules/dlq?ref=main"

  queue_name = "[sub-name]-[optional-rule-name]" # Must not exceed 60 characters as the module appends "-dlq" to the name
  kms_key_id = aws_kms_key.my_key.id             # omit if you want a new KMS key to be created.
  tags       = var.tags
}

Requirements

Name Version
terraform >= 1.0
aws >= 4.0, <5.0

Providers

Name Version
aws >= 4.0, <5.0

Modules

No modules.

Resources

Name Type
aws_cloudwatch_event_archive.this resource
aws_cloudwatch_event_bus.this resource
aws_cloudwatch_event_bus_policy.this resource
aws_cloudwatch_event_rule.targets resource
aws_cloudwatch_event_target.targets resource
aws_cloudwatch_event_target.this resource
aws_cloudwatch_log_group.this resource
aws_iam_policy.events_cross_account resource
aws_iam_role.events_cross_account resource
aws_iam_role_policy_attachment.events_cross_account resource
aws_schemas_discoverer.this resource
aws_caller_identity.current data source
aws_cloudwatch_event_source.partner data source
aws_iam_policy_document.event_bus data source
aws_iam_policy_document.events_assume data source
aws_iam_policy_document.events_cross_account data source
aws_partition.current data source
aws_region.current data source

Inputs

Name Description Type Default Required
allow_put_events_arns List of ARNs allowed to call PutEvents on this instance. Used for resource based cross account/region access. list(string) [] no
bus_policy_docs List of additional IAM policy documents to append to the access policy for this instance. Ignored if using a partner bus. Generally you will want to use allow_put_events_arns over this. list(string) [] no
cross_bus_rules List of cross bus routing rules.
list(
object(
{
name = string # Name of the rule
target_arn = string # ARN of the target event bus
pattern = string # JSON string representation of event pattern used for matching events
debug = optional(bool, false) # Enable debug logging for this rule
dlq_arn = optional(string, null) # ARN of the dead letter queue to use for this rule
}
)
)
[] no
enable_schema_discovery_registry Enable the EventBridge schema discovery resource. bool true no
name The name of the eventbus or partner source. This must be unique per region per account. string n/a yes
tags Tags for resources created by module. map(string) n/a yes

Outputs

Name Description
bus The bus resource created by this module.
cross_bus_rules_arns ARNs of cross bus rules created for this bus.
discoverer_arn ARN of the EventBridge Schema Discover.

About

Terraform module for managing an AWS EventBridge event bus

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages