diff --git a/README.md b/README.md index 4b6fc9e..dc7859a 100644 --- a/README.md +++ b/README.md @@ -2,17 +2,9 @@ Terraform module to create EventBridge resources. -The following resources are currently supported: - -* [EventBridge Archive](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_archive) -* [EventBridge Bus](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_bus) -* [EventBridge Permission](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_permission) -* [EventBridge Rule](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_rule) -* [EventBridge Target](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_target) - ## Supported Features -- Creates AWS EventBridge Resources (bus, rules, targets, permissions) +- Creates AWS EventBridge Resources (bus, rules, targets, permissions, connections, destinations) - Attach resources to an existing EventBridge bus - Support AWS EventBridge Archives and Replays - Conditional creation for many types of resources @@ -61,7 +53,7 @@ module "eventbridge" { } ] } - + tags = { Name = "my-bus" } @@ -82,7 +74,7 @@ module "eventbridge" { } ``` -### EventBridge Rule +### EventBridge Rule ```hcl module "eventbridge" { @@ -91,7 +83,7 @@ module "eventbridge" { bus_name = "my-bus" create_targets = false - + rules = { logs = { description = "Capture log data" @@ -108,14 +100,14 @@ module "eventbridge" { source = "terraform-aws-modules/eventbridge/aws" bus_name = "my-bus" - + rules = { logs = { description = "Capture log data" event_pattern = jsonencode({ "source" : ["my.app.logs"] }) } } - + targets = { logs = [ { @@ -138,7 +130,7 @@ module "eventbridge_with_archive" { source = "terraform-aws-modules/eventbridge/aws" bus_name = "my-bus" - + create_archives = true archives = { @@ -160,7 +152,7 @@ module "eventbridge_with_archive" { } ``` -### EventBridge Permission +### EventBridge Permission ```hcl module "eventbridge_with_permissions" { @@ -175,13 +167,76 @@ module "eventbridge_with_permissions" { "099720109466 ProdAccess" = {} } - tags = { Name = "my-bus" } } ``` +### EventBridge API Destination + +```hcl +module "eventbridge_with_api_destination" { + source = "terraform-aws-modules/eventbridge/aws" + + bus_name = "my-bus" + + create_connections = true + create_api_destinations = true + + attach_api_destination_policy = true + + connections = { + smee = { + authorization_type = "OAUTH_CLIENT_CREDENTIALS" + auth_parameters = { + oauth = { + authorization_endpoint = "https://oauth.endpoint.com" + http_method = "GET" + + client_parameters = { + client_id = "1234567890" + client_secret = "Pass1234!" + } + + oauth_http_parameters = { + body = [{ + key = "body-parameter-key" + value = "body-parameter-value" + is_value_secret = false + }] + + header = [{ + key = "header-parameter-key1" + value = "header-parameter-value1" + }, { + key = "header-parameter-key2" + value = "header-parameter-value2" + is_value_secret = true + }] + + query_string = [{ + key = "query-string-parameter-key" + value = "query-string-parameter-value" + is_value_secret = false + }] + } + } + } + } + } + + api_destinations = { + smee = { + description = "my smee endpoint" + invocation_endpoint = "https://smee.io/hgoubgoibwekt331" + http_method = "POST" + invocation_rate_limit_per_second = 200 + } + } +} +``` + ## Additional IAM policies for Step Function In addition to all supported AWS service integrations you may want to create and attach additional policies. @@ -204,12 +259,14 @@ module "eventbridge" { create = false # to disable all resources - create_bus = false # to control creation of the EventBridge Bus and related resources - create_rule = false # to control creation of EventBridge Rules and related resources - create_targets = false # to control creation of EventBridge Targets and related resources - create_archives = false # to control creation of EventBridge Archives - create_permissions = false # to control creation of EventBridge Permissions - create_role = false # to control creation of the IAM role and policies required for EventBridge + create_bus = false # to control creation of the EventBridge Bus and related resources + create_rule = false # to control creation of EventBridge Rules and related resources + create_targets = false # to control creation of EventBridge Targets and related resources + create_archives = false # to control creation of EventBridge Archives + create_permissions = false # to control creation of EventBridge Permissions + create_role = false # to control creation of the IAM role and policies required for EventBridge + create_connections = false # to control creation of EventBridge Connection resources + create_api_destinations = false # to control creation of EventBridge Destination resources attach_cloudwatch_policy = false attach_ecs_policy = false @@ -219,6 +276,7 @@ module "eventbridge" { attach_sfn_policy = false attach_sqs_policy = false attach_tracing_policy = false + attach_api_destination_policy = false # ... omitted } @@ -231,6 +289,7 @@ module "eventbridge" { * [Using Default Bus](https://github.com/terraform-aws-modules/terraform-aws-eventbridge/tree/master/examples/default-bus) - Creates resources in the `default` bus. * [Archive](https://github.com/terraform-aws-modules/terraform-aws-eventbridge/tree/master/examples/with-archive) - EventBridge Archives resources in various configurations. * [Permissions](https://github.com/terraform-aws-modules/terraform-aws-eventbridge/tree/master/examples/with-permissions) - Controls permissions to EventBridge. +* [API Destination](https://github.com/terraform-aws-modules/terraform-aws-eventbridge/tree/master/examples/with-api-destination) - Control access to EventBridge using API destinations. * [ECS Scheduled Events](https://github.com/terraform-aws-modules/terraform-aws-eventbridge/tree/master/examples/with-ecs-scheduling) - Use default bus to schedule events on ECS. @@ -240,13 +299,13 @@ module "eventbridge" { | Name | Version | |------|---------| | [terraform](#requirement\_terraform) | >= 0.13.1 | -| [aws](#requirement\_aws) | >= 3.40 | +| [aws](#requirement\_aws) | >= 3.44 | ## Providers | Name | Version | |------|---------| -| [aws](#provider\_aws) | >= 3.40 | +| [aws](#provider\_aws) | >= 3.44 | ## Modules @@ -256,14 +315,17 @@ No modules. | Name | Type | |------|------| +| [aws_cloudwatch_event_api_destination.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_api_destination) | resource | | [aws_cloudwatch_event_archive.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_archive) | resource | | [aws_cloudwatch_event_bus.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_bus) | resource | +| [aws_cloudwatch_event_connection.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_connection) | resource | | [aws_cloudwatch_event_permission.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_permission) | resource | | [aws_cloudwatch_event_rule.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_rule) | resource | | [aws_cloudwatch_event_target.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_target) | resource | | [aws_iam_policy.additional_inline](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource | | [aws_iam_policy.additional_json](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource | | [aws_iam_policy.additional_jsons](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource | +| [aws_iam_policy.api_destination](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource | | [aws_iam_policy.cloudwatch](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource | | [aws_iam_policy.ecs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource | | [aws_iam_policy.kinesis](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource | @@ -275,6 +337,7 @@ No modules. | [aws_iam_policy_attachment.additional_inline](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy_attachment) | resource | | [aws_iam_policy_attachment.additional_json](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy_attachment) | resource | | [aws_iam_policy_attachment.additional_jsons](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy_attachment) | resource | +| [aws_iam_policy_attachment.api_destination](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy_attachment) | resource | | [aws_iam_policy_attachment.cloudwatch](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy_attachment) | resource | | [aws_iam_policy_attachment.ecs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy_attachment) | resource | | [aws_iam_policy_attachment.kinesis](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy_attachment) | resource | @@ -288,6 +351,7 @@ No modules. | [aws_iam_role_policy_attachment.additional_one](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | | [aws_iam_policy.tracing](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy) | data source | | [aws_iam_policy_document.additional_inline](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_iam_policy_document.api_destination](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | | [aws_iam_policy_document.assume_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | | [aws_iam_policy_document.cloudwatch](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | | [aws_iam_policy_document.ecs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | @@ -301,7 +365,9 @@ No modules. | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| +| [api\_destinations](#input\_api\_destinations) | A map of objects with EventBridge Destination definitions. | `map(any)` | `{}` | no | | [archives](#input\_archives) | A map of objects with the EventBridge Archive definitions. | `map(any)` | `{}` | no | +| [attach\_api\_destination\_policy](#input\_attach\_api\_destination\_policy) | Controls whether the API Destination policy should be added to IAM role for EventBridge Target | `bool` | `false` | no | | [attach\_cloudwatch\_policy](#input\_attach\_cloudwatch\_policy) | Controls whether the Cloudwatch policy should be added to IAM role for EventBridge Target | `bool` | `false` | no | | [attach\_ecs\_policy](#input\_attach\_ecs\_policy) | Controls whether the ECS policy should be added to IAM role for EventBridge Target | `bool` | `false` | no | | [attach\_kinesis\_firehose\_policy](#input\_attach\_kinesis\_firehose\_policy) | Controls whether the Kinesis Firehose policy should be added to IAM role for EventBridge Target | `bool` | `false` | no | @@ -317,9 +383,12 @@ No modules. | [attach\_tracing\_policy](#input\_attach\_tracing\_policy) | Controls whether X-Ray tracing policy should be added to IAM role for EventBridge | `bool` | `false` | no | | [bus\_name](#input\_bus\_name) | A unique name for your EventBridge Bus | `string` | `"default"` | no | | [cloudwatch\_target\_arns](#input\_cloudwatch\_target\_arns) | The Amazon Resource Name (ARN) of the Cloudwatch Log Streams you want to use as EventBridge targets | `list(string)` | `[]` | no | +| [connections](#input\_connections) | A map of objects with EventBridge Connection definitions. | `any` | `{}` | no | | [create](#input\_create) | Controls whether resources should be created | `bool` | `true` | no | +| [create\_api\_destinations](#input\_create\_api\_destinations) | Controls whether EventBridge Destination resources should be created | `bool` | `false` | no | | [create\_archives](#input\_create\_archives) | Controls whether EventBridge Archive resources should be created | `bool` | `false` | no | | [create\_bus](#input\_create\_bus) | Controls whether EventBridge Bus resource should be created | `bool` | `true` | no | +| [create\_connections](#input\_create\_connections) | Controls whether EventBridge Connection resources should be created | `bool` | `false` | no | | [create\_permissions](#input\_create\_permissions) | Controls whether EventBridge Permission resources should be created | `bool` | `true` | no | | [create\_role](#input\_create\_role) | Controls whether IAM roles should be created | `bool` | `true` | no | | [create\_rules](#input\_create\_rules) | Controls whether EventBridge Rule resources should be created | `bool` | `true` | no | @@ -353,9 +422,12 @@ No modules. | Name | Description | |------|-------------| +| [eventbridge\_api\_destination\_arns](#output\_eventbridge\_api\_destination\_arns) | The EventBridge API Destination ARNs created | | [eventbridge\_archive\_arns](#output\_eventbridge\_archive\_arns) | The EventBridge Archive Arns created | | [eventbridge\_bus\_arn](#output\_eventbridge\_bus\_arn) | The EventBridge Bus Arn | | [eventbridge\_bus\_name](#output\_eventbridge\_bus\_name) | The EventBridge Bus Name | +| [eventbridge\_connection\_arns](#output\_eventbridge\_connection\_arns) | The EventBridge Connection Arns created | +| [eventbridge\_connection\_ids](#output\_eventbridge\_connection\_ids) | The EventBridge Connection IDs created | | [eventbridge\_permission\_ids](#output\_eventbridge\_permission\_ids) | The EventBridge Permission Arns created | | [eventbridge\_role\_arn](#output\_eventbridge\_role\_arn) | The ARN of the IAM role created for EventBridge | | [eventbridge\_role\_name](#output\_eventbridge\_role\_name) | The name of the IAM role created for EventBridge | diff --git a/examples/with-api-destination/README.md b/examples/with-api-destination/README.md new file mode 100644 index 0000000..1e2b3e6 --- /dev/null +++ b/examples/with-api-destination/README.md @@ -0,0 +1,56 @@ +# EventBridge API Destination Example + +Configuration in this directory creates resources to control access to EventBridge using API destinations. + +## Usage + +To run this example you need to execute: + +```bash +$ terraform init +$ terraform plan +$ terraform apply +``` + +Note that this example may create resources which cost money. Run `terraform destroy` when you don't need these resources. + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 0.13.1 | +| [aws](#requirement\_aws) | >= 3.44 | +| [random](#requirement\_random) | >= 3 | + +## Providers + +| Name | Version | +|------|---------| +| [random](#provider\_random) | >= 3 | + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [eventbridge](#module\_eventbridge) | ../../ | | + +## Resources + +| Name | Type | +|------|------| +| [random_pet.this](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/pet) | resource | + +## Inputs + +No inputs. + +## Outputs + +| Name | Description | +|------|-------------| +| [eventbridge\_api\_destination\_arns](#output\_eventbridge\_api\_destination\_arns) | The EventBridge API Destination ARNs | +| [eventbridge\_bus\_arn](#output\_eventbridge\_bus\_arn) | The EventBridge Bus ARN | +| [eventbridge\_connection\_arns](#output\_eventbridge\_connection\_arns) | The EventBridge Connection ARNs | +| [eventbridge\_connection\_ids](#output\_eventbridge\_connection\_ids) | The EventBridge Connection IDs created | + diff --git a/examples/with-api-destination/main.tf b/examples/with-api-destination/main.tf new file mode 100644 index 0000000..9789db9 --- /dev/null +++ b/examples/with-api-destination/main.tf @@ -0,0 +1,166 @@ +provider "aws" { + region = "ap-southeast-1" + + # Make it faster by skipping something + skip_get_ec2_platforms = true + skip_metadata_api_check = true + skip_region_validation = true + skip_credentials_validation = true + skip_requesting_account_id = true +} + +module "eventbridge" { + source = "../../" + + create_bus = true + create_connections = true + create_api_destinations = true + + bus_name = "${random_pet.this.id}-bus" + + attach_api_destination_policy = true + + rules = { + orders = { + description = "Capture all order data" + event_pattern = jsonencode({ "source" : ["myapp.orders"] }) + enabled = true + } + } + + targets = { + orders = [ + { + name = "send-orders-to-requestbin" + destination = "requestbin" + attach_role_arn = true + }, + { + name = "send-orders-to-github" + destination = "github" + attach_role_arn = true + } + ] + } + + connections = { + requestbin = { + authorization_type = "BASIC" + auth_parameters = { + + basic = { + username = random_pet.this.id + password = random_pet.this.id + } + + invocation_http_parameters = { + body = [{ + key = "body-parameter-key" + value = "body-parameter-value" + is_value_secret = false + }, { + key = "body-secret-key" + value = "body-secret-value" + is_value_secret = true + } + ] + + header = [{ + key = "header-parameter-key1" + value = "header-parameter-value1" + is_value_secret = false + }, { + key = "header-parameter-key2" + value = "header-parameter-value2" + }] + + query_string = [{ + key = "query-string-parameter-key1" + value = "query-string-parameter-value1" + is_value_secret = false + }, { + key = "query-string-parameter-key2" + value = "query-string-parameter-value2" + }] + } + } + } + + smee = { + authorization_type = "OAUTH_CLIENT_CREDENTIALS" + auth_parameters = { + oauth = { + authorization_endpoint = "https://smee.io/hgoubgoibwekt331" + http_method = "GET" + + client_parameters = { + client_id = "1234567890" + client_secret = "Pass1234!" + } + + oauth_http_parameters = { + body = [{ + key = "body-parameter-key" + value = "body-parameter-value" + is_value_secret = false + }] + + header = [{ + key = "header-parameter-key1" + value = "header-parameter-value1" + }, { + key = "header-parameter-key2" + value = "header-parameter-value2" + is_value_secret = true + }] + + query_string = [{ + key = "query-string-parameter-key" + value = "query-string-parameter-value" + is_value_secret = false + }] + } + } + } + } + + github = { + authorization_type = "API_KEY" + auth_parameters = { + api_key = { + key = "x-signature-id" + value = random_pet.this.id + } + } + } + } + + api_destinations = { + smee = { + description = "my smee endpoint" + invocation_endpoint = "https://smee.io/hgoubgoibwekt331" + http_method = "POST" + invocation_rate_limit_per_second = 200 + } + requestbin = { + description = "my requestbin endpoint" + invocation_endpoint = "https://smee.io/hgoubGoIbWEKt331" + http_method = "POST" + invocation_rate_limit_per_second = 20 + } + github = { + description = "my github endpoint" + invocation_endpoint = "https://smee.io/hgoubGoIbWEKt331" + http_method = "POST" + invocation_rate_limit_per_second = 20 + } + } +} + +################## +# Extra resources +################## + +resource "random_pet" "this" { + length = 2 +} diff --git a/examples/with-api-destination/outputs.tf b/examples/with-api-destination/outputs.tf new file mode 100644 index 0000000..ba92c9e --- /dev/null +++ b/examples/with-api-destination/outputs.tf @@ -0,0 +1,20 @@ +output "eventbridge_bus_arn" { + description = "The EventBridge Bus ARN" + value = module.eventbridge.eventbridge_bus_arn +} + +# EventBridge Connection +output "eventbridge_connection_ids" { + description = "The EventBridge Connection IDs created" + value = module.eventbridge.eventbridge_connection_ids +} + +output "eventbridge_connection_arns" { + description = "The EventBridge Connection ARNs" + value = module.eventbridge.eventbridge_connection_arns +} + +output "eventbridge_api_destination_arns" { + description = "The EventBridge API Destination ARNs" + value = module.eventbridge.eventbridge_api_destination_arns +} diff --git a/examples/with-api-destination/variables.tf b/examples/with-api-destination/variables.tf new file mode 100644 index 0000000..e69de29 diff --git a/examples/with-api-destination/versions.tf b/examples/with-api-destination/versions.tf new file mode 100644 index 0000000..fa5b27e --- /dev/null +++ b/examples/with-api-destination/versions.tf @@ -0,0 +1,8 @@ +terraform { + required_version = ">= 0.13.1" + + required_providers { + aws = ">= 3.44" + random = ">= 3" + } +} diff --git a/examples/with-ecs-scheduling/main.tf b/examples/with-ecs-scheduling/main.tf index 0b22271..5cc30a1 100644 --- a/examples/with-ecs-scheduling/main.tf +++ b/examples/with-ecs-scheduling/main.tf @@ -117,4 +117,3 @@ resource "aws_ecs_task_definition" "hello_world" { resource "random_pet" "this" { length = 2 } - diff --git a/iam.tf b/iam.tf index 8254ff7..8e399ae 100644 --- a/iam.tf +++ b/iam.tf @@ -257,6 +257,36 @@ resource "aws_iam_policy_attachment" "sfn" { policy_arn = aws_iam_policy.sfn[0].arn } +######################### +# API Destination Config +######################### + +data "aws_iam_policy_document" "api_destination" { + count = local.create_role && var.attach_api_destination_policy ? 1 : 0 + + statement { + sid = "APIDestinationAccess" + effect = "Allow" + actions = ["events:InvokeApiDestination"] + resources = [for k, v in aws_cloudwatch_event_api_destination.this : v.arn] + } +} + +resource "aws_iam_policy" "api_destination" { + count = local.create_role && var.attach_api_destination_policy ? 1 : 0 + + name = "${local.role_name}-api-destination" + policy = data.aws_iam_policy_document.api_destination[0].json +} + +resource "aws_iam_policy_attachment" "api_destination" { + count = local.create_role && var.attach_api_destination_policy ? 1 : 0 + + name = "${local.role_name}-api-destination" + roles = [aws_iam_role.eventbridge[0].name] + policy_arn = aws_iam_policy.api_destination[0].arn +} + #################### # Cloudwatch Config #################### diff --git a/main.tf b/main.tf index 5e4d18a..c07976a 100644 --- a/main.tf +++ b/main.tf @@ -15,6 +15,20 @@ locals { }) ] if length(var.targets) != 0 ]) + eventbridge_connections = flatten([ + for index, conn in var.connections : + merge(conn, { + "name" = index + "Name" = "${replace(index, "_", "-")}-connection" + }) + ]) + eventbridge_api_destinations = flatten([ + for index, dest in var.api_destinations : + merge(dest, { + "name" = index + "Name" = "${replace(index, "_", "-")}-destination" + }) + ]) } resource "aws_cloudwatch_event_bus" "this" { @@ -53,7 +67,7 @@ resource "aws_cloudwatch_event_target" "this" { event_bus_name = var.create_bus ? aws_cloudwatch_event_bus.this[0].name : var.bus_name rule = each.value.Name - arn = each.value.arn + arn = lookup(each.value, "destination", null) != null ? aws_cloudwatch_event_api_destination.this[each.value.destination].arn : each.value.arn role_arn = lookup(each.value, "attach_role_arn", null) != null ? try(aws_iam_role.eventbridge[0].arn, "") : null target_id = lookup(each.value, "target_id", null) @@ -187,3 +201,150 @@ resource "aws_cloudwatch_event_permission" "this" { action = lookup(each.value, "action", null) event_bus_name = try(each.value["event_bus_name"], aws_cloudwatch_event_bus.this[0].name, var.bus_name, null) } + +resource "aws_cloudwatch_event_connection" "this" { + for_each = var.create && var.create_connections ? { + for conn in local.eventbridge_connections : conn.name => conn + } : tomap({}) + + name = each.value.Name + description = lookup(each.value, "description", null) + authorization_type = each.value.authorization_type + + dynamic "auth_parameters" { + for_each = [each.value.auth_parameters] + + content { + dynamic "api_key" { + for_each = lookup(each.value.auth_parameters, "api_key", null) != null ? [ + each.value.auth_parameters.api_key + ] : [] + + content { + key = api_key.value.key + value = api_key.value.value + } + } + + dynamic "basic" { + for_each = lookup(each.value.auth_parameters, "basic", null) != null ? [ + each.value.auth_parameters.basic + ] : [] + + content { + username = basic.value.username + password = basic.value.password + } + } + + dynamic "oauth" { + for_each = lookup(each.value.auth_parameters, "oauth", null) != null ? [ + each.value.auth_parameters.oauth + ] : [] + + content { + authorization_endpoint = oauth.value.authorization_endpoint + http_method = oauth.value.http_method + + dynamic "client_parameters" { + for_each = [each.value.auth_parameters.oauth.client_parameters] + + content { + client_id = client_parameters.value.client_id + client_secret = client_parameters.value.client_secret + } + } + + dynamic "oauth_http_parameters" { + for_each = lookup(each.value.auth_parameters.oauth, "oauth_http_parameters", null) != null ? [ + each.value.auth_parameters.oauth.oauth_http_parameters + ] : [] + + content { + dynamic "body" { + for_each = lookup(each.value.auth_parameters.oauth.oauth_http_parameters, "body", []) + + content { + key = body.value.key + value = body.value.value + is_value_secret = lookup(body.value, "is_value_secret", null) + } + } + + dynamic "header" { + for_each = lookup(each.value.auth_parameters.oauth.oauth_http_parameters, "header", []) + + content { + key = header.value.key + value = header.value.value + is_value_secret = lookup(header.value, "is_value_secret", null) + } + } + + dynamic "query_string" { + for_each = lookup(each.value.auth_parameters.oauth.oauth_http_parameters, "query_string", []) + + content { + key = query_string.value.key + value = query_string.value.value + is_value_secret = lookup(query_string.value, "is_value_secret", null) + } + } + } + } + } + } + + dynamic "invocation_http_parameters" { + for_each = lookup(each.value.auth_parameters, "invocation_http_parameters", null) != null ? [ + each.value.auth_parameters.invocation_http_parameters + ] : [] + + content { + dynamic "body" { + for_each = lookup(each.value.auth_parameters.invocation_http_parameters, "body", []) + + content { + key = body.value.key + value = body.value.value + is_value_secret = lookup(body.value, "is_value_secret", null) + } + } + + dynamic "header" { + for_each = lookup(each.value.auth_parameters.invocation_http_parameters, "header", []) + + content { + key = header.value.key + value = header.value.value + is_value_secret = lookup(header.value, "is_value_secret", null) + } + } + + dynamic "query_string" { + for_each = lookup(each.value.auth_parameters.invocation_http_parameters, "query_string", []) + + content { + key = query_string.value.key + value = query_string.value.value + is_value_secret = lookup(query_string.value, "is_value_secret", null) + } + } + } + } + } + } +} + +resource "aws_cloudwatch_event_api_destination" "this" { + for_each = var.create && var.create_api_destinations ? { + for dest in local.eventbridge_api_destinations : dest.name => dest + } : {} + + name = each.value.Name + description = lookup(each.value, "description", null) + invocation_endpoint = each.value.invocation_endpoint + http_method = each.value.http_method + invocation_rate_limit_per_second = lookup(each.value, "invocation_rate_limit_per_second", null) + connection_arn = aws_cloudwatch_event_connection.this[each.value.name].arn +} diff --git a/outputs.tf b/outputs.tf index c3fbad9..346b494 100644 --- a/outputs.tf +++ b/outputs.tf @@ -21,6 +21,23 @@ output "eventbridge_permission_ids" { value = { for k, v in aws_cloudwatch_event_permission.this : k => v.id } } +# EventBridge Connection +output "eventbridge_connection_ids" { + description = "The EventBridge Connection IDs created" + value = { for k, v in aws_cloudwatch_event_connection.this : k => v.id } +} + +output "eventbridge_connection_arns" { + description = "The EventBridge Connection Arns created" + value = { for k, v in aws_cloudwatch_event_connection.this : k => v.arn } +} + +# EventBridge Destination +output "eventbridge_api_destination_arns" { + description = "The EventBridge API Destination ARNs created" + value = { for k, v in aws_cloudwatch_event_api_destination.this : k => v.id } +} + # EventBridge Rule output "eventbridge_rule_ids" { description = "The EventBridge Rule IDs created" diff --git a/variables.tf b/variables.tf index fdd678a..ab618af 100644 --- a/variables.tf +++ b/variables.tf @@ -40,6 +40,18 @@ variable "create_archives" { default = false } +variable "create_connections" { + description = "Controls whether EventBridge Connection resources should be created" + type = bool + default = false +} + +variable "create_api_destinations" { + description = "Controls whether EventBridge Destination resources should be created" + type = bool + default = false +} + ####################### variable "bus_name" { @@ -72,6 +84,18 @@ variable "permissions" { default = {} } +variable "connections" { + description = "A map of objects with EventBridge Connection definitions." + type = any + default = {} +} + +variable "api_destinations" { + description = "A map of objects with EventBridge Destination definitions." + type = map(any) + default = {} +} + variable "tags" { description = "A map of tags to assign to resources." type = map(string) @@ -164,6 +188,12 @@ variable "attach_cloudwatch_policy" { default = false } +variable "attach_api_destination_policy" { + description = "Controls whether the API Destination policy should be added to IAM role for EventBridge Target" + type = bool + default = false +} + variable "attach_tracing_policy" { description = "Controls whether X-Ray tracing policy should be added to IAM role for EventBridge" type = bool diff --git a/versions.tf b/versions.tf index 9ecc4a5..0441068 100644 --- a/versions.tf +++ b/versions.tf @@ -2,6 +2,6 @@ terraform { required_version = ">= 0.13.1" required_providers { - aws = ">= 3.40" + aws = ">= 3.44" } }