From d66d1e24b98f6c88c9faae07a6a3cdbb4e8d7822 Mon Sep 17 00:00:00 2001 From: "Byungjin Park (Claud)" Date: Wed, 20 Dec 2023 10:38:41 +0900 Subject: [PATCH] Update eventbridge-event-bus module to support default event bus (#14) * Update eventbridge-event-bus module to support default event bus * Add eventbridge-rule module --- .github/labeler.yaml | 2 + .github/labels.yaml | 3 + README.md | 2 + modules/eventbridge-event-bus/README.md | 9 +- modules/eventbridge-event-bus/main.tf | 22 ++++- modules/eventbridge-event-bus/outputs.tf | 6 +- modules/eventbridge-event-bus/variables.tf | 5 +- modules/eventbridge-rule/README.md | 61 ++++++++++++++ modules/eventbridge-rule/main.tf | 58 +++++++++++++ modules/eventbridge-rule/outputs.tf | 50 +++++++++++ modules/eventbridge-rule/resource-group.tf | 31 +++++++ modules/eventbridge-rule/variables.tf | 97 ++++++++++++++++++++++ modules/eventbridge-rule/versions.tf | 10 +++ 13 files changed, 344 insertions(+), 12 deletions(-) create mode 100644 modules/eventbridge-rule/README.md create mode 100644 modules/eventbridge-rule/main.tf create mode 100644 modules/eventbridge-rule/outputs.tf create mode 100644 modules/eventbridge-rule/resource-group.tf create mode 100644 modules/eventbridge-rule/variables.tf create mode 100644 modules/eventbridge-rule/versions.tf diff --git a/.github/labeler.yaml b/.github/labeler.yaml index 3819632..f30a7a5 100644 --- a/.github/labeler.yaml +++ b/.github/labeler.yaml @@ -1,6 +1,8 @@ # Modules ":floppy_disk: eventbridge-event-bus": - modules/eventbridge-event-bus/**/* +":floppy_disk: eventbridge-rule": +- modules/eventbridge-rule/**/* ":floppy_disk: msk-cluster": - modules/msk-cluster/**/* ":floppy_disk: sns-fifo-topic": diff --git a/.github/labels.yaml b/.github/labels.yaml index 3c8a5fb..f3a5bc2 100644 --- a/.github/labels.yaml +++ b/.github/labels.yaml @@ -43,6 +43,9 @@ - color: "fbca04" description: "This issue or pull request is related to eventbridge-event-bus module." name: ":floppy_disk: eventbridge-event-bus" +- color: "fbca04" + description: "This issue or pull request is related to eventbridge-rule module." + name: ":floppy_disk: eventbridge-rule" - color: "fbca04" description: "This issue or pull request is related to msk-cluster module." name: ":floppy_disk: msk-cluster" diff --git a/README.md b/README.md index fe5e54b..f7a5048 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ Terraform module which creates messaging related resources on AWS. - [eventbridge-event-bus](./modules/eventbridge-event-bus) +- [eventbridge-rule](./modules/eventbridge-rule) - [msk-cluster](./modules/msk-cluster) - [sns-fifo-topic](./modules/sns-fifo-topic) - [sns-standard-topic](./modules/sns-standard-topic) @@ -18,6 +19,7 @@ Terraform Modules from [this package](https://github.com/tedilabs/terraform-aws- - **AWS EventBridge (Formerly known as CloudWatch Events)** - Event Bus + - Rule - **AWS MSK (Managed Streaming for Apache Kafka)** - Cluster - **AWS SNS (Simple Notification Service)** diff --git a/modules/eventbridge-event-bus/README.md b/modules/eventbridge-event-bus/README.md index ebca131..2dc3575 100644 --- a/modules/eventbridge-event-bus/README.md +++ b/modules/eventbridge-event-bus/README.md @@ -2,7 +2,7 @@ This module creates following resources. -- `aws_cloudwatch_event_bus` +- `aws_cloudwatch_event_bus` (optional) - `aws_cloudwatch_event_bus_policy` (optional) - `aws_cloudwatch_event_archive` (optional) - `aws_schemas_discoverer` (optional) @@ -19,7 +19,7 @@ This module creates following resources. | Name | Version | |------|---------| -| [aws](#provider\_aws) | 5.19.0 | +| [aws](#provider\_aws) | 5.31.0 | ## Modules @@ -35,14 +35,15 @@ This module creates following resources. | [aws_cloudwatch_event_bus.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_bus) | resource | | [aws_cloudwatch_event_bus_policy.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_bus_policy) | resource | | [aws_schemas_discoverer.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/schemas_discoverer) | resource | +| [aws_cloudwatch_event_bus.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/cloudwatch_event_bus) | data source | ## Inputs | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| [name](#input\_name) | (Required) The name of the new event bus. The name of custom event bus can't contain the `/` character, but you can use the `/` character in partner event bus names. You can't use the name `default` for a custom event bus, as this name is already used for your account's default event bus. | `string` | n/a | yes | -| [archives](#input\_archives) | (Required) The configuration to create archives for the event bus. Events are continuously saved in archives, and individual events will be deleted after the retention period. An archive will persist until you manually delete it. Each block of `archives` as defined below.
(Required) `name` - The name of the new event archive. Maximum of 48 characters consisting of numbers, lower/upper case letters, `.`, `-`, `_`. You can't change the name of the archive after it is created.
(Optional) `description` - The description of the new event archive.
(Optional) `retention_in_days` - The maximum number of days to retain events in the new event archive. `0` is equivalent to Indefinite. The maximum is 2 billion days. Defaults to `0`.
(Optional) `event_pattern` - An event pattern to use to filter events sent to the archive. |
list(object({
name = string
description = optional(string, "Managed by Terraform.")
retention_in_days = optional(number, 0)
event_pattern = optional(string)
}))
| `[]` | no | +| [archives](#input\_archives) | (Required) The configuration to create archives for the event bus. Events are continuously saved in archives, and individual events will be deleted after the retention period. An archive will persist until you manually delete it. Each block of `archives` as defined below.
(Required) `name` - The name of the new event archive. Maximum of 48 characters consisting of numbers, lower/upper case letters, `.`, `-`, `_`. You can't change the name of the archive after it is created.
(Optional) `description` - The description of the new event archive.
(Optional) `retention_in_days` - The maximum number of days to retain events in the new event archive. `0` is equivalent to Indefinite. The maximum is 2 billion days. Defaults to `0`.
(Optional) `event_pattern` - An event pattern to use to filter events sent to the archive. All events from the source will be archived when `event_pattern` is not provided. |
list(object({
name = string
description = optional(string, "Managed by Terraform.")
retention_in_days = optional(number, 0)
event_pattern = optional(string)
}))
| `[]` | no | | [module\_tags\_enabled](#input\_module\_tags\_enabled) | (Optional) Whether to create AWS Resource Tags for the module informations. | `bool` | `true` | no | +| [name](#input\_name) | (Optional) The name of the new event bus. The name of custom event bus can't contain the `/` character, but you can use the `/` character in partner event bus names. You can't use the name `default` for a custom event bus, as this name is already used for your account's default event bus. If the value is `default`, it will load the `default` event bus that already exists instead of creating a new one. Defaults to `default`. | `string` | `"default"` | no | | [policy](#input\_policy) | (Optional) A valid policy JSON document. The resource-based policy defines who can access your event bus. By default, only the event bus owner can send events to the event bus. | `string` | `null` | no | | [resource\_group\_description](#input\_resource\_group\_description) | (Optional) The description of Resource Group. | `string` | `"Managed by Terraform."` | no | | [resource\_group\_enabled](#input\_resource\_group\_enabled) | (Optional) Whether to create Resource Group to find and group AWS resources which are created by this module. | `bool` | `true` | no | diff --git a/modules/eventbridge-event-bus/main.tf b/modules/eventbridge-event-bus/main.tf index 182effa..4354a5d 100644 --- a/modules/eventbridge-event-bus/main.tf +++ b/modules/eventbridge-event-bus/main.tf @@ -14,12 +14,28 @@ locals { } : {} } +locals { + is_default = var.name == "default" + event_bus = (local.is_default + ? data.aws_cloudwatch_event_bus.default[0] + : aws_cloudwatch_event_bus.this[0] + ) +} + ################################################### # Event Bus on EventBridge ################################################### +data "aws_cloudwatch_event_bus" "default" { + count = local.is_default ? 1 : 0 + + name = "default" +} + resource "aws_cloudwatch_event_bus" "this" { + count = local.is_default ? 0 : 1 + name = var.name event_source_name = startswith(var.name, "aws.partner/") ? var.name : null @@ -40,7 +56,7 @@ resource "aws_cloudwatch_event_bus" "this" { resource "aws_cloudwatch_event_bus_policy" "this" { count = var.policy != null ? 1 : 0 - event_bus_name = aws_cloudwatch_event_bus.this.name + event_bus_name = local.event_bus.name policy = var.policy } @@ -55,7 +71,7 @@ resource "aws_cloudwatch_event_archive" "this" { archive.name => archive } - event_source_arn = aws_cloudwatch_event_bus.this.arn + event_source_arn = local.event_bus.arn name = each.key description = each.value.description @@ -72,7 +88,7 @@ resource "aws_cloudwatch_event_archive" "this" { resource "aws_schemas_discoverer" "this" { count = var.schema_discovery.enabled ? 1 : 0 - source_arn = aws_cloudwatch_event_bus.this.arn + source_arn = local.event_bus.arn description = var.schema_discovery.description tags = merge( diff --git a/modules/eventbridge-event-bus/outputs.tf b/modules/eventbridge-event-bus/outputs.tf index 925025c..25bde47 100644 --- a/modules/eventbridge-event-bus/outputs.tf +++ b/modules/eventbridge-event-bus/outputs.tf @@ -1,16 +1,16 @@ output "id" { description = "The unique identifier for the event bus." - value = aws_cloudwatch_event_bus.this.id + value = local.event_bus.id } output "arn" { description = "The Amazon Resource Name (ARN) of the event bus." - value = aws_cloudwatch_event_bus.this.arn + value = local.event_bus.arn } output "name" { description = "The name of the event bus." - value = aws_cloudwatch_event_bus.this.name + value = local.event_bus.name } output "archives" { diff --git a/modules/eventbridge-event-bus/variables.tf b/modules/eventbridge-event-bus/variables.tf index e5eb5b1..40ec2c8 100644 --- a/modules/eventbridge-event-bus/variables.tf +++ b/modules/eventbridge-event-bus/variables.tf @@ -1,6 +1,7 @@ variable "name" { - description = "(Required) The name of the new event bus. The name of custom event bus can't contain the `/` character, but you can use the `/` character in partner event bus names. You can't use the name `default` for a custom event bus, as this name is already used for your account's default event bus." + description = "(Optional) The name of the new event bus. The name of custom event bus can't contain the `/` character, but you can use the `/` character in partner event bus names. You can't use the name `default` for a custom event bus, as this name is already used for your account's default event bus. If the value is `default`, it will load the `default` event bus that already exists instead of creating a new one. Defaults to `default`." type = string + default = "default" nullable = false } @@ -16,7 +17,7 @@ variable "archives" { (Required) `name` - The name of the new event archive. Maximum of 48 characters consisting of numbers, lower/upper case letters, `.`, `-`, `_`. You can't change the name of the archive after it is created. (Optional) `description` - The description of the new event archive. (Optional) `retention_in_days` - The maximum number of days to retain events in the new event archive. `0` is equivalent to Indefinite. The maximum is 2 billion days. Defaults to `0`. - (Optional) `event_pattern` - An event pattern to use to filter events sent to the archive. + (Optional) `event_pattern` - An event pattern to use to filter events sent to the archive. All events from the source will be archived when `event_pattern` is not provided. EOF type = list(object({ name = string diff --git a/modules/eventbridge-rule/README.md b/modules/eventbridge-rule/README.md new file mode 100644 index 0000000..2bf5d80 --- /dev/null +++ b/modules/eventbridge-rule/README.md @@ -0,0 +1,61 @@ +# eventbridge-rule + +This module creates following resources. + +- `aws_cloudwatch_event_rule` +- `aws_cloudwatch_event_target` (optional) + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.6 | +| [aws](#requirement\_aws) | >= 5.27 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | 5.31.0 | + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [resource\_group](#module\_resource\_group) | tedilabs/misc/aws//modules/resource-group | ~> 0.10.0 | + +## Resources + +| Name | Type | +|------|------| +| [aws_cloudwatch_event_rule.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_rule) | resource | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [name](#input\_name) | (Required) A name of the rule for the event bus. | `string` | n/a | yes | +| [description](#input\_description) | (Optional) The description of the rule. | `string` | `"Managed by Terraform."` | no | +| [event\_bus](#input\_event\_bus) | (Optional) The name or ARN of the event bus to associate with this rule. If you omit this, the `default` event bus is used. | `string` | `"default"` | no | +| [module\_tags\_enabled](#input\_module\_tags\_enabled) | (Optional) Whether to create AWS Resource Tags for the module informations. | `bool` | `true` | no | +| [resource\_group\_description](#input\_resource\_group\_description) | (Optional) The description of Resource Group. | `string` | `"Managed by Terraform."` | no | +| [resource\_group\_enabled](#input\_resource\_group\_enabled) | (Optional) Whether to create Resource Group to find and group AWS resources which are created by this module. | `bool` | `true` | no | +| [resource\_group\_name](#input\_resource\_group\_name) | (Optional) The name of Resource Group. A Resource Group name can have a maximum of 127 characters, including letters, numbers, hyphens, dots, and underscores. The name cannot start with `AWS` or `aws`. | `string` | `""` | no | +| [state](#input\_state) | (Optional) The state of the rule. Valid values are `DISABLED`, `ENABLED`, and `ENABLED_WITH_ALL_CLOUDTRAIL_MANAGEMENT_EVENTS`. Defaults to `ENABLED`.
`DISABLED` - The rule is disabled. EventBridge does not match any events against the rule.
`ENABLED` - The rule is enabled. EventBridge matches events against the rule, except for Amazon Web Services management events delivered through CloudTrail.
`ENABLED_WITH_ALL_CLOUDTRAIL_MANAGEMENT_EVENTS` - The rule is enabled for all events, including Amazon Web Services management events delivered through CloudTrail. Management events provide visibility into management operations that are performed on resources in your Amazon Web Services account. These are also known as control plane operations. This value is only valid for rules on the default event bus or custom event buses. It does not apply to partner event buses. | `string` | `"ENABLED"` | no | +| [tags](#input\_tags) | (Optional) A map of tags to add to all resources. | `map(string)` | `{}` | no | +| [trigger](#input\_trigger) | (Required) The configuration for the rule trigger. At least one of `schedule_expression` or `event_pattern` is required. `trigger` as defined below.
(Optional) `event_pattern` - The event pattern to trigger when an event matching the pattern occurs. This is described in a JSON object. The `event_pattern` size is 2048 by default but it is adjustable up to 4096 characters by submitting a service quota increase request.
(Optional) `schedule_expression` - The scheduling expression. For example, `cron(0 20 * * ? *)` or `rate(5 minutes)`. Can only be used on the default event bus. |
object({
event_pattern = optional(string)
schedule_expression = optional(string)
})
| `{}` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [arn](#output\_arn) | The Amazon Resource Name (ARN) of the rule. | +| [description](#output\_description) | The description of the rule. | +| [event\_bus](#output\_event\_bus) | The name of the event bus. | +| [id](#output\_id) | The unique identifier for the rule. | +| [name](#output\_name) | The name of the rule. | +| [state](#output\_state) | The state of the rule. | +| [targets](#output\_targets) | A list of archives for the event bus. | +| [trigger](#output\_trigger) | The configuration for the rule trriger. | + diff --git a/modules/eventbridge-rule/main.tf b/modules/eventbridge-rule/main.tf new file mode 100644 index 0000000..7a30231 --- /dev/null +++ b/modules/eventbridge-rule/main.tf @@ -0,0 +1,58 @@ +locals { + metadata = { + package = "terraform-aws-messaging" + version = trimspace(file("${path.module}/../../VERSION")) + module = basename(path.module) + name = var.name + } + module_tags = var.module_tags_enabled ? { + "module.terraform.io/package" = local.metadata.package + "module.terraform.io/version" = local.metadata.version + "module.terraform.io/name" = local.metadata.module + "module.terraform.io/full-name" = "${local.metadata.package}/${local.metadata.module}" + "module.terraform.io/instance" = local.metadata.name + } : {} +} + + +################################################### +# Rule of Event Bus on EventBridge +################################################### + +# role_arn - (Optional) The Amazon Resource Name (ARN) associated with the role that is used for target invocation. +# INFO: Not supported attributes +# - `is_enabled` +# - `name_prefix` +resource "aws_cloudwatch_event_rule" "this" { + event_bus_name = var.event_bus + + name = var.name + description = var.description + state = var.state + + + ## Triggers + event_pattern = var.trigger.event_pattern + schedule_expression = var.trigger.schedule_expression + + + tags = merge( + { + "Name" = local.metadata.name + }, + local.module_tags, + var.tags, + ) +} + + +################################################### +# Rule Targets +################################################### + +# resource "aws_cloudwatch_event_target" "this" { +# count = var.policy != null ? 1 : 0 +# +# event_bus_name = aws_cloudwatch_event_bus.this.name +# policy = var.policy +# } diff --git a/modules/eventbridge-rule/outputs.tf b/modules/eventbridge-rule/outputs.tf new file mode 100644 index 0000000..11f5dd8 --- /dev/null +++ b/modules/eventbridge-rule/outputs.tf @@ -0,0 +1,50 @@ +output "id" { + description = "The unique identifier for the rule." + value = aws_cloudwatch_event_rule.this.id +} + +output "arn" { + description = "The Amazon Resource Name (ARN) of the rule." + value = aws_cloudwatch_event_rule.this.arn +} + +output "name" { + description = "The name of the rule." + value = aws_cloudwatch_event_rule.this.name +} + +output "description" { + description = "The description of the rule." + value = aws_cloudwatch_event_rule.this.description +} + +output "event_bus" { + description = "The name of the event bus." + value = aws_cloudwatch_event_rule.this.event_bus_name +} + +output "state" { + description = "The state of the rule." + value = aws_cloudwatch_event_rule.this.state +} + +output "trigger" { + description = "The configuration for the rule trriger." + value = { + event_pattern = aws_cloudwatch_event_rule.this.event_pattern + schedule_expression = aws_cloudwatch_event_rule.this.schedule_expression + } +} + +output "targets" { + description = "A list of archives for the event bus." + value = [ + # for target in aws_cloudwatch_event_target.this : { + # id = archive.id + # arn = archive.arn + # name = archive.name + # description = archive.description + # retention_in_days = archive.retention_days + # } + ] +} diff --git a/modules/eventbridge-rule/resource-group.tf b/modules/eventbridge-rule/resource-group.tf new file mode 100644 index 0000000..7487ba0 --- /dev/null +++ b/modules/eventbridge-rule/resource-group.tf @@ -0,0 +1,31 @@ +locals { + resource_group_name = (var.resource_group_name != "" + ? var.resource_group_name + : join(".", [ + local.metadata.package, + local.metadata.module, + replace(local.metadata.name, "/[^a-zA-Z0-9_\\.-]/", "-"), + ]) + ) +} + + +module "resource_group" { + source = "tedilabs/misc/aws//modules/resource-group" + version = "~> 0.10.0" + + count = (var.resource_group_enabled && var.module_tags_enabled) ? 1 : 0 + + name = local.resource_group_name + description = var.resource_group_description + + query = { + resource_tags = local.module_tags + } + + module_tags_enabled = false + tags = merge( + local.module_tags, + var.tags, + ) +} diff --git a/modules/eventbridge-rule/variables.tf b/modules/eventbridge-rule/variables.tf new file mode 100644 index 0000000..368c20a --- /dev/null +++ b/modules/eventbridge-rule/variables.tf @@ -0,0 +1,97 @@ +variable "event_bus" { + description = "(Optional) The name or ARN of the event bus to associate with this rule. If you omit this, the `default` event bus is used." + type = string + default = "default" + nullable = false +} + +variable "name" { + description = "(Required) A name of the rule for the event bus." + type = string + nullable = false +} + +variable "description" { + description = "(Optional) The description of the rule." + type = string + default = "Managed by Terraform." + nullable = false +} + +variable "state" { + description = <