diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 776bc24..f065bdd 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/antonbabenko/pre-commit-terraform - rev: v1.99.4 + rev: v1.101.0 hooks: - id: terraform_fmt - id: terraform_docs @@ -23,7 +23,7 @@ repos: - '--args=--only=terraform_workspace_remote' - id: terraform_validate - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v5.0.0 + rev: v6.0.0 hooks: - id: check-merge-conflict - id: end-of-file-fixer diff --git a/README.md b/README.md index dd1e178..080e2c6 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ Terraform module to create EventBridge resources. ### EventBridge Complete -Most common use-case which creates custom bus, rules and targets. +Most common use-case which creates custom bus, logging, rules and targets. ```hcl module "eventbridge" { @@ -22,6 +22,20 @@ module "eventbridge" { bus_name = "my-bus" + log_config = { + include_detail = "FULL" + level = "INFO" + } + + log_delivery = { + cloudwatch_logs = { + destination_arn = "arn:aws:logs:us-east-1:123456789012:log-group:my-log-group" + } + s3 = { + destination_arn = "arn:aws:s3:::my-log-bucket" + } + } + rules = { orders = { description = "Capture all order data" @@ -347,6 +361,8 @@ module "eventbridge" { create_schedule_groups = false # to control creation of EventBridge Schedule Group resources create_schedules = false # to control creation of EventBridge Schedule resources create_pipes = false # to control creation of EventBridge Pipes resources + create_log_delivery_source = false # to control creation of EventBridge Log Delivery Source resources + create_log_delivery = false # to control creation of EventBridge Log Delivery resources attach_cloudwatch_policy = false attach_ecs_policy = false @@ -368,6 +384,7 @@ module "eventbridge" { * [HTTP API Gateway](https://github.com/terraform-aws-modules/terraform-aws-eventbridge/tree/master/examples/api-gateway-event-source) - Creates an integration with HTTP API Gateway as event source. * [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. +* [Logging](https://github.com/terraform-aws-modules/terraform-aws-eventbridge/tree/master/examples/with-bus-logging) - EventBridge Logging resources in various configurations. * [Permissions](https://github.com/terraform-aws-modules/terraform-aws-eventbridge/tree/master/examples/with-permissions) - Controls permissions to EventBridge. * [Scheduler](https://github.com/terraform-aws-modules/terraform-aws-eventbridge/tree/master/examples/with-schedules) - EventBridge Scheduler which works with any bus (recommended way). * [ECS Scheduling Events](https://github.com/terraform-aws-modules/terraform-aws-eventbridge/tree/master/examples/with-ecs-scheduling) - Use default bus to schedule events on ECS. @@ -382,13 +399,13 @@ module "eventbridge" { | Name | Version | |------|---------| | [terraform](#requirement\_terraform) | >= 1.5.7 | -| [aws](#requirement\_aws) | >= 6.0 | +| [aws](#requirement\_aws) | >= 6.6 | ## Providers | Name | Version | |------|---------| -| [aws](#provider\_aws) | >= 6.0 | +| [aws](#provider\_aws) | >= 6.6 | ## Modules @@ -405,6 +422,9 @@ No modules. | [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_cloudwatch_log_delivery.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_delivery) | resource | +| [aws_cloudwatch_log_delivery_destination.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_delivery_destination) | resource | +| [aws_cloudwatch_log_delivery_source.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_delivery_source) | 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 | @@ -496,6 +516,8 @@ No modules. | [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\_log\_delivery](#input\_create\_log\_delivery) | Controls whether EventBridge log delivery resources should be created | `bool` | `true` | no | +| [create\_log\_delivery\_source](#input\_create\_log\_delivery\_source) | Controls whether EventBridge log delivery source resource should be created | `bool` | `true` | no | | [create\_permissions](#input\_create\_permissions) | Controls whether EventBridge Permission resources should be created | `bool` | `true` | no | | [create\_pipe\_role\_only](#input\_create\_pipe\_role\_only) | Controls whether an IAM role should be created for the pipes only | `bool` | `false` | no | | [create\_pipes](#input\_create\_pipes) | Controls whether EventBridge Pipes resources should be created | `bool` | `true` | no | @@ -513,6 +535,9 @@ No modules. | [kinesis\_target\_arns](#input\_kinesis\_target\_arns) | The Amazon Resource Name (ARN) of the Kinesis Streams you want to use as EventBridge targets | `list(string)` | `[]` | no | | [kms\_key\_identifier](#input\_kms\_key\_identifier) | The identifier of the AWS KMS customer managed key for EventBridge to use, if you choose to use a customer managed key to encrypt events on this event bus. The identifier can be the key Amazon Resource Name (ARN), KeyId, key alias, or key alias ARN. | `string` | `null` | no | | [lambda\_target\_arns](#input\_lambda\_target\_arns) | The Amazon Resource Name (ARN) of the Lambda Functions you want to use as EventBridge targets | `list(string)` | `[]` | no | +| [log\_config](#input\_log\_config) | The configuration block for the EventBridge bus log config settings |
object({
include_detail = string
level = string
})
| `null` | no | +| [log\_delivery](#input\_log\_delivery) | Map of the configuration block for the EventBridge bus log delivery settings (key is the type of log delivery: cloudwatch\_logs, s3, firehose) |
map(object({
enabled = optional(bool, true)
destination_arn = string
source_name = optional(string)
name = optional(string)
output_format = optional(string)
field_delimiter = optional(string)
record_fields = optional(list(string))
s3_delivery_configuration = optional(object({
enable_hive_compatible_path = optional(bool)
suffix_path = optional(string)
}))
}))
| `{}` | no | +| [log\_delivery\_source\_name](#input\_log\_delivery\_source\_name) | Name of log delivery source | `string` | `null` | no | | [number\_of\_policies](#input\_number\_of\_policies) | Number of policies to attach to IAM role | `number` | `0` | no | | [number\_of\_policy\_jsons](#input\_number\_of\_policy\_jsons) | Number of policies JSON to attach to IAM role | `number` | `0` | no | | [permissions](#input\_permissions) | A map of objects with EventBridge Permission definitions. | `map(any)` | `{}` | no | @@ -558,6 +583,8 @@ No modules. | [eventbridge\_connection\_ids](#output\_eventbridge\_connection\_ids) | The EventBridge Connection IDs | | [eventbridge\_connections](#output\_eventbridge\_connections) | The EventBridge Connections created and their attributes | | [eventbridge\_iam\_roles](#output\_eventbridge\_iam\_roles) | The EventBridge IAM roles created and their attributes | +| [eventbridge\_log\_delivery\_source\_arn](#output\_eventbridge\_log\_delivery\_source\_arn) | The EventBridge Bus CloudWatch Log Delivery Source ARN | +| [eventbridge\_log\_delivery\_source\_name](#output\_eventbridge\_log\_delivery\_source\_name) | The EventBridge Bus CloudWatch Log Delivery Source Name | | [eventbridge\_permission\_ids](#output\_eventbridge\_permission\_ids) | The EventBridge Permission IDs | | [eventbridge\_permissions](#output\_eventbridge\_permissions) | The EventBridge Permissions created and their attributes | | [eventbridge\_pipe\_arns](#output\_eventbridge\_pipe\_arns) | The EventBridge Pipes ARNs | diff --git a/examples/api-gateway-event-source/README.md b/examples/api-gateway-event-source/README.md index 0d788a9..9c0300f 100644 --- a/examples/api-gateway-event-source/README.md +++ b/examples/api-gateway-event-source/README.md @@ -20,14 +20,14 @@ Note that this example may create resources which cost money. Run `terraform des | Name | Version | |------|---------| | [terraform](#requirement\_terraform) | >= 1.5.7 | -| [aws](#requirement\_aws) | >= 6.0 | +| [aws](#requirement\_aws) | >= 6.6 | | [random](#requirement\_random) | >= 3.0 | ## Providers | Name | Version | |------|---------| -| [aws](#provider\_aws) | >= 6.0 | +| [aws](#provider\_aws) | >= 6.6 | | [random](#provider\_random) | >= 3.0 | ## Modules diff --git a/examples/api-gateway-event-source/versions.tf b/examples/api-gateway-event-source/versions.tf index 3fe2eaf..a8d1901 100644 --- a/examples/api-gateway-event-source/versions.tf +++ b/examples/api-gateway-event-source/versions.tf @@ -4,7 +4,7 @@ terraform { required_providers { aws = { source = "hashicorp/aws" - version = ">= 6.0" + version = ">= 6.6" } random = { source = "hashicorp/random" diff --git a/examples/complete/README.md b/examples/complete/README.md index 5995298..2fc4a81 100644 --- a/examples/complete/README.md +++ b/examples/complete/README.md @@ -20,7 +20,7 @@ Note that this example may create resources which cost money. Run `terraform des | Name | Version | |------|---------| | [terraform](#requirement\_terraform) | >= 1.5.7 | -| [aws](#requirement\_aws) | >= 6.0 | +| [aws](#requirement\_aws) | >= 6.6 | | [null](#requirement\_null) | >= 2.0 | | [random](#requirement\_random) | >= 3.0 | @@ -28,7 +28,7 @@ Note that this example may create resources which cost money. Run `terraform des | Name | Version | |------|---------| -| [aws](#provider\_aws) | >= 6.0 | +| [aws](#provider\_aws) | >= 6.6 | | [null](#provider\_null) | >= 2.0 | | [random](#provider\_random) | >= 3.0 | @@ -38,7 +38,7 @@ Note that this example may create resources which cost money. Run `terraform des |------|--------|---------| | [bucket](#module\_bucket) | terraform-aws-modules/s3-bucket/aws | ~> 5.0 | | [disabled](#module\_disabled) | ../../ | n/a | -| [ecs](#module\_ecs) | terraform-aws-modules/ecs/aws | ~> 3.0 | +| [ecs](#module\_ecs) | terraform-aws-modules/ecs/aws | ~> 6.0 | | [eventbridge](#module\_eventbridge) | ../../ | n/a | | [lambda](#module\_lambda) | terraform-aws-modules/lambda/aws | ~> 8.0 | | [sns](#module\_sns) | terraform-aws-modules/sns/aws | ~> 6.0 | @@ -50,8 +50,6 @@ Note that this example may create resources which cost money. Run `terraform des |------|------| | [aws_cloudtrail.trail](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudtrail) | resource | | [aws_cloudwatch_log_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_group) | resource | -| [aws_ecs_service.hello_world](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ecs_service) | resource | -| [aws_ecs_task_definition.hello_world](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ecs_task_definition) | resource | | [aws_kinesis_stream.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kinesis_stream) | resource | | [aws_sqs_queue.dlq](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sqs_queue) | resource | | [aws_sqs_queue.fifo](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sqs_queue) | resource | @@ -59,10 +57,9 @@ Note that this example may create resources which cost money. Run `terraform des | [aws_sqs_queue_policy.queue](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sqs_queue_policy) | resource | | [null_resource.download_package](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | resource | | [random_pet.this](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/pet) | resource | -| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source | -| [aws_iam_policy_document.bucket_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | | [aws_iam_policy_document.queue](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | -| [aws_region.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/region) | data source | +| [aws_subnets.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/subnets) | data source | +| [aws_vpc.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/vpc) | data source | ## Inputs diff --git a/examples/complete/main.tf b/examples/complete/main.tf index 8eff736..8fac152 100644 --- a/examples/complete/main.tf +++ b/examples/complete/main.tf @@ -38,7 +38,7 @@ module "eventbridge" { append_rule_postfix = false attach_ecs_policy = true - ecs_target_arns = [aws_ecs_task_definition.hello_world.arn] + ecs_target_arns = [module.ecs.services.hello-world.task_definition_arn] rules = { orders = { @@ -114,11 +114,11 @@ module "eventbridge" { }, { name = "process-email-with-ecs-task", - arn = module.ecs.ecs_cluster_arn, + arn = module.ecs.cluster_arn, attach_role_arn = true ecs_target = { task_count = 1 - task_definition_arn = aws_ecs_task_definition.hello_world.arn + task_definition_arn = module.ecs.services.hello-world.task_definition_arn } } ] @@ -229,6 +229,19 @@ locals { EOF } } +############################################################# +# Data sources to get VPC and default security group details +############################################################# +data "aws_vpc" "default" { + default = true +} + +data "aws_subnets" "default" { + filter { + name = "vpc-id" + values = [data.aws_vpc.default.id] + } +} ################## # Extra resources @@ -314,37 +327,36 @@ module "step_function" { module "ecs" { source = "terraform-aws-modules/ecs/aws" - version = "~> 3.0" - - name = random_pet.this.id - - capacity_providers = ["FARGATE", "FARGATE_SPOT"] -} - -resource "aws_ecs_service" "hello_world" { - name = "hello_world-${random_pet.this.id}" - cluster = module.ecs.ecs_cluster_id - task_definition = aws_ecs_task_definition.hello_world.arn - - desired_count = 1 + version = "~> 6.0" - deployment_maximum_percent = 100 - deployment_minimum_healthy_percent = 0 -} + cluster_name = random_pet.this.id -resource "aws_ecs_task_definition" "hello_world" { - family = "hello_world-${random_pet.this.id}" + default_capacity_provider_strategy = { + FARGATE = { + weight = 100 + base = 20 + } + FARGATE_SPOT = { + weight = 100 + } + } - container_definitions = < [terraform](#requirement\_terraform) | >= 1.5.7 | -| [aws](#requirement\_aws) | >= 6.0 | +| [aws](#requirement\_aws) | >= 6.6 | | [random](#requirement\_random) | >= 3.0 | ## Providers | Name | Version | |------|---------| -| [aws](#provider\_aws) | >= 6.0 | +| [aws](#provider\_aws) | >= 6.6 | | [random](#provider\_random) | >= 3.0 | ## Modules diff --git a/examples/default-bus/versions.tf b/examples/default-bus/versions.tf index 3fe2eaf..a8d1901 100644 --- a/examples/default-bus/versions.tf +++ b/examples/default-bus/versions.tf @@ -4,7 +4,7 @@ terraform { required_providers { aws = { source = "hashicorp/aws" - version = ">= 6.0" + version = ">= 6.6" } random = { source = "hashicorp/random" diff --git a/examples/with-api-destination/README.md b/examples/with-api-destination/README.md index 28c0a9d..00cd3bf 100644 --- a/examples/with-api-destination/README.md +++ b/examples/with-api-destination/README.md @@ -20,14 +20,14 @@ Note that this example may create resources which cost money. Run `terraform des | Name | Version | |------|---------| | [terraform](#requirement\_terraform) | >= 1.5.7 | -| [aws](#requirement\_aws) | >= 6.0 | +| [aws](#requirement\_aws) | >= 6.6 | | [random](#requirement\_random) | >= 3.0 | ## Providers | Name | Version | |------|---------| -| [aws](#provider\_aws) | >= 6.0 | +| [aws](#provider\_aws) | >= 6.6 | | [random](#provider\_random) | >= 3.0 | ## Modules diff --git a/examples/with-api-destination/versions.tf b/examples/with-api-destination/versions.tf index 3fe2eaf..a8d1901 100644 --- a/examples/with-api-destination/versions.tf +++ b/examples/with-api-destination/versions.tf @@ -4,7 +4,7 @@ terraform { required_providers { aws = { source = "hashicorp/aws" - version = ">= 6.0" + version = ">= 6.6" } random = { source = "hashicorp/random" diff --git a/examples/with-archive/README.md b/examples/with-archive/README.md index 00840dd..7710410 100644 --- a/examples/with-archive/README.md +++ b/examples/with-archive/README.md @@ -20,14 +20,14 @@ Note that this example may create resources which cost money. Run `terraform des | Name | Version | |------|---------| | [terraform](#requirement\_terraform) | >= 1.5.7 | -| [aws](#requirement\_aws) | >= 6.0 | +| [aws](#requirement\_aws) | >= 6.6 | | [random](#requirement\_random) | >= 3.0 | ## Providers | Name | Version | |------|---------| -| [aws](#provider\_aws) | >= 6.0 | +| [aws](#provider\_aws) | >= 6.6 | | [random](#provider\_random) | >= 3.0 | ## Modules @@ -36,6 +36,7 @@ Note that this example may create resources which cost money. Run `terraform des |------|--------|---------| | [eventbridge](#module\_eventbridge) | ../../ | n/a | | [eventbridge\_archive\_only](#module\_eventbridge\_archive\_only) | ../../ | n/a | +| [kms](#module\_kms) | terraform-aws-modules/kms/aws | ~> 2.0 | ## Resources @@ -43,6 +44,8 @@ Note that this example may create resources which cost money. Run `terraform des |------|------| | [aws_cloudwatch_event_bus.existing_bus](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_bus) | resource | | [random_pet.this](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/pet) | resource | +| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source | +| [aws_region.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/region) | data source | ## Inputs diff --git a/examples/with-archive/versions.tf b/examples/with-archive/versions.tf index 3fe2eaf..a8d1901 100644 --- a/examples/with-archive/versions.tf +++ b/examples/with-archive/versions.tf @@ -4,7 +4,7 @@ terraform { required_providers { aws = { source = "hashicorp/aws" - version = ">= 6.0" + version = ">= 6.6" } random = { source = "hashicorp/random" diff --git a/examples/with-bus-logging/README.md b/examples/with-bus-logging/README.md new file mode 100644 index 0000000..b79e0b5 --- /dev/null +++ b/examples/with-bus-logging/README.md @@ -0,0 +1,55 @@ +# EventBridge with Bus Logging Example + + +## Usage + +To run this example you need to execute: + +```bash +$ terraform init +$ terraform plan +$ terraform apply +``` + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.5.7 | +| [aws](#requirement\_aws) | >= 6.6 | +| [random](#requirement\_random) | >= 3.0 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | >= 6.6 | +| [random](#provider\_random) | >= 3.0 | + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [cloudwatch\_log\_group](#module\_cloudwatch\_log\_group) | terraform-aws-modules/cloudwatch/aws//modules/log-group | ~> 5.0 | +| [eventbridge](#module\_eventbridge) | ../../ | n/a | +| [eventbridge\_external](#module\_eventbridge\_external) | ../../ | n/a | +| [eventbridge\_log\_delivery\_only](#module\_eventbridge\_log\_delivery\_only) | ../../ | n/a | +| [s3\_bucket](#module\_s3\_bucket) | terraform-aws-modules/s3-bucket/aws | ~> 5.0 | + +## Resources + +| Name | Type | +|------|------| +| [random_pet.this](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/pet) | resource | +| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source | +| [aws_iam_policy_document.bucket_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | + +## Inputs + +No inputs. + +## Outputs + +No outputs. + diff --git a/examples/with-bus-logging/main.tf b/examples/with-bus-logging/main.tf new file mode 100644 index 0000000..e828d4b --- /dev/null +++ b/examples/with-bus-logging/main.tf @@ -0,0 +1,146 @@ +provider "aws" { + region = "eu-west-1" + + # Make it faster by skipping something + skip_metadata_api_check = true + skip_region_validation = true + skip_credentials_validation = true +} + +data "aws_caller_identity" "current" {} + +module "eventbridge" { + source = "../../" + + create_bus = true + + bus_name = random_pet.this.id + + log_config = { + include_detail = "NONE" + level = "INFO" + } + + log_delivery = { + cloudwatch_logs = { + destination_arn = module.cloudwatch_log_group.cloudwatch_log_group_arn + } + s3 = { + destination_arn = module.s3_bucket.s3_bucket_arn + } + } +} + +# External EventBridge bus with log delivery attached to the bus +module "eventbridge_external" { + source = "../../" + + create_bus = true + + bus_name = "${random_pet.this.id}-external-bus" + + log_config = { + include_detail = "FULL" + level = "TRACE" + } +} + +module "eventbridge_log_delivery_only" { + source = "../../" + + create_bus = false + create_role = false + + bus_name = module.eventbridge_external.eventbridge_bus_name + + create_log_delivery_source = false + + log_delivery = { + cloudwatch_logs = { + destination_arn = module.cloudwatch_log_group.cloudwatch_log_group_arn + source_name = module.eventbridge_external.eventbridge_log_delivery_source_name + } + s3 = { + destination_arn = module.s3_bucket.s3_bucket_arn + source_name = module.eventbridge_external.eventbridge_log_delivery_source_name + } + } + + depends_on = [module.eventbridge_external] +} + +################# +# Extra resources +################# + +resource "random_pet" "this" { + length = 2 +} + +###################### +# CloudWatch Log Group +###################### +module "cloudwatch_log_group" { + source = "terraform-aws-modules/cloudwatch/aws//modules/log-group" + version = "~> 5.0" + + name = "/aws/vendedlogs/events/event-bus/${random_pet.this.id}-bus" + retention_in_days = 14 +} + +#### +# S3 +#### +module "s3_bucket" { + source = "terraform-aws-modules/s3-bucket/aws" + version = "~> 5.0" + + bucket = "${random_pet.this.id}-eventbridge-bus-logs-bucket" + force_destroy = true + + attach_policy = true + policy = data.aws_iam_policy_document.bucket_policy.json + + acl = "private" + + control_object_ownership = true + object_ownership = "ObjectWriter" + + versioning = { + enabled = true + } +} + +data "aws_iam_policy_document" "bucket_policy" { + statement { + effect = "Allow" + principals { + type = "Service" + identifiers = ["delivery.logs.amazonaws.com"] + } + actions = [ + "s3:PutObject" + ] + resources = [ + "${module.s3_bucket.s3_bucket_arn}/AWSLogs/${data.aws_caller_identity.current.account_id}/EventBusLogs/*" + ] + condition { + test = "StringEquals" + variable = "s3:x-amz-acl" + values = ["bucket-owner-full-control"] + } + condition { + test = "StringEquals" + variable = "aws:SourceAccount" + values = [data.aws_caller_identity.current.account_id] + } + condition { + test = "ArnLike" + variable = "aws:SourceArn" + values = [ + module.eventbridge.eventbridge_log_delivery_source_arn, + module.eventbridge_external.eventbridge_log_delivery_source_arn + ] + } + } +} diff --git a/examples/with-bus-logging/outputs.tf b/examples/with-bus-logging/outputs.tf new file mode 100644 index 0000000..e69de29 diff --git a/examples/with-bus-logging/variables.tf b/examples/with-bus-logging/variables.tf new file mode 100644 index 0000000..e69de29 diff --git a/examples/with-bus-logging/versions.tf b/examples/with-bus-logging/versions.tf new file mode 100644 index 0000000..a8d1901 --- /dev/null +++ b/examples/with-bus-logging/versions.tf @@ -0,0 +1,14 @@ +terraform { + required_version = ">= 1.5.7" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 6.6" + } + random = { + source = "hashicorp/random" + version = ">= 3.0" + } + } +} diff --git a/examples/with-ecs-scheduling/README.md b/examples/with-ecs-scheduling/README.md index 6bfc101..e49099c 100644 --- a/examples/with-ecs-scheduling/README.md +++ b/examples/with-ecs-scheduling/README.md @@ -20,21 +20,21 @@ Note that this example may create resources which cost money. Run `terraform des | Name | Version | |------|---------| | [terraform](#requirement\_terraform) | >= 1.5.7 | -| [aws](#requirement\_aws) | >= 6.0 | +| [aws](#requirement\_aws) | >= 6.6 | | [random](#requirement\_random) | >= 3.0 | ## Providers | Name | Version | |------|---------| -| [aws](#provider\_aws) | >= 6.0 | +| [aws](#provider\_aws) | >= 6.6 | | [random](#provider\_random) | >= 3.0 | ## Modules | Name | Source | Version | |------|--------|---------| -| [ecs\_cluster](#module\_ecs\_cluster) | terraform-aws-modules/ecs/aws | ~> 5.0 | +| [ecs\_cluster](#module\_ecs\_cluster) | terraform-aws-modules/ecs/aws | ~> 6.0 | | [eventbridge](#module\_eventbridge) | ../../ | n/a | ## Resources diff --git a/examples/with-ecs-scheduling/main.tf b/examples/with-ecs-scheduling/main.tf index 011e347..2d01a79 100644 --- a/examples/with-ecs-scheduling/main.tf +++ b/examples/with-ecs-scheduling/main.tf @@ -106,20 +106,17 @@ module "eventbridge" { module "ecs_cluster" { source = "terraform-aws-modules/ecs/aws" - version = "~> 5.0" + version = "~> 6.0" cluster_name = random_pet.this.id - fargate_capacity_providers = { + default_capacity_provider_strategy = { FARGATE = { - default_capacity_provider_strategy = { - weight = 100 - } + weight = 100 + base = 20 } FARGATE_SPOT = { - default_capacity_provider_strategy = { - weight = 100 - } + weight = 100 } } diff --git a/examples/with-ecs-scheduling/versions.tf b/examples/with-ecs-scheduling/versions.tf index 3fe2eaf..a8d1901 100644 --- a/examples/with-ecs-scheduling/versions.tf +++ b/examples/with-ecs-scheduling/versions.tf @@ -4,7 +4,7 @@ terraform { required_providers { aws = { source = "hashicorp/aws" - version = ">= 6.0" + version = ">= 6.6" } random = { source = "hashicorp/random" diff --git a/examples/with-lambda-scheduling/README.md b/examples/with-lambda-scheduling/README.md index e1f70e4..1352eb2 100644 --- a/examples/with-lambda-scheduling/README.md +++ b/examples/with-lambda-scheduling/README.md @@ -20,7 +20,7 @@ Note that this example may create resources which cost money. Run `terraform des | Name | Version | |------|---------| | [terraform](#requirement\_terraform) | >= 1.5.7 | -| [aws](#requirement\_aws) | >= 6.0 | +| [aws](#requirement\_aws) | >= 6.6 | | [null](#requirement\_null) | >= 2.0 | | [random](#requirement\_random) | >= 3.0 | diff --git a/examples/with-lambda-scheduling/versions.tf b/examples/with-lambda-scheduling/versions.tf index b54c439..cb0c2fc 100644 --- a/examples/with-lambda-scheduling/versions.tf +++ b/examples/with-lambda-scheduling/versions.tf @@ -4,7 +4,7 @@ terraform { required_providers { aws = { source = "hashicorp/aws" - version = ">= 6.0" + version = ">= 6.6" } random = { source = "hashicorp/random" diff --git a/examples/with-permissions/README.md b/examples/with-permissions/README.md index 3ceb3a0..ac2852a 100644 --- a/examples/with-permissions/README.md +++ b/examples/with-permissions/README.md @@ -20,14 +20,14 @@ Note that this example may create resources which cost money. Run `terraform des | Name | Version | |------|---------| | [terraform](#requirement\_terraform) | >= 1.5.7 | -| [aws](#requirement\_aws) | >= 6.0 | +| [aws](#requirement\_aws) | >= 6.6 | | [random](#requirement\_random) | >= 3.0 | ## Providers | Name | Version | |------|---------| -| [aws](#provider\_aws) | >= 6.0 | +| [aws](#provider\_aws) | >= 6.6 | | [random](#provider\_random) | >= 3.0 | ## Modules diff --git a/examples/with-permissions/versions.tf b/examples/with-permissions/versions.tf index 3fe2eaf..a8d1901 100644 --- a/examples/with-permissions/versions.tf +++ b/examples/with-permissions/versions.tf @@ -4,7 +4,7 @@ terraform { required_providers { aws = { source = "hashicorp/aws" - version = ">= 6.0" + version = ">= 6.6" } random = { source = "hashicorp/random" diff --git a/examples/with-pipes/README.md b/examples/with-pipes/README.md index b8c1b42..fdc1604 100644 --- a/examples/with-pipes/README.md +++ b/examples/with-pipes/README.md @@ -20,7 +20,7 @@ Note that this example may create resources which cost money. Run `terraform des | Name | Version | |------|---------| | [terraform](#requirement\_terraform) | >= 1.5.7 | -| [aws](#requirement\_aws) | >= 6.0 | +| [aws](#requirement\_aws) | >= 6.6 | | [null](#requirement\_null) | >= 2.0 | | [random](#requirement\_random) | >= 3.0 | @@ -28,7 +28,7 @@ Note that this example may create resources which cost money. Run `terraform des | Name | Version | |------|---------| -| [aws](#provider\_aws) | >= 6.0 | +| [aws](#provider\_aws) | >= 6.6 | | [null](#provider\_null) | >= 2.0 | | [random](#provider\_random) | >= 3.0 | diff --git a/examples/with-pipes/versions.tf b/examples/with-pipes/versions.tf index b54c439..cb0c2fc 100644 --- a/examples/with-pipes/versions.tf +++ b/examples/with-pipes/versions.tf @@ -4,7 +4,7 @@ terraform { required_providers { aws = { source = "hashicorp/aws" - version = ">= 6.0" + version = ">= 6.6" } random = { source = "hashicorp/random" diff --git a/examples/with-schedules/README.md b/examples/with-schedules/README.md index de1cf6e..de0b349 100644 --- a/examples/with-schedules/README.md +++ b/examples/with-schedules/README.md @@ -20,7 +20,7 @@ Note that this example may create resources which cost money. Run `terraform des | Name | Version | |------|---------| | [terraform](#requirement\_terraform) | >= 1.5.7 | -| [aws](#requirement\_aws) | >= 6.0 | +| [aws](#requirement\_aws) | >= 6.6 | | [null](#requirement\_null) | >= 2.0 | | [random](#requirement\_random) | >= 3.0 | @@ -28,7 +28,7 @@ Note that this example may create resources which cost money. Run `terraform des | Name | Version | |------|---------| -| [aws](#provider\_aws) | >= 6.0 | +| [aws](#provider\_aws) | >= 6.6 | | [null](#provider\_null) | >= 2.0 | | [random](#provider\_random) | >= 3.0 | diff --git a/examples/with-schedules/versions.tf b/examples/with-schedules/versions.tf index b54c439..cb0c2fc 100644 --- a/examples/with-schedules/versions.tf +++ b/examples/with-schedules/versions.tf @@ -4,7 +4,7 @@ terraform { required_providers { aws = { source = "hashicorp/aws" - version = ">= 6.0" + version = ">= 6.6" } random = { source = "hashicorp/random" diff --git a/main.tf b/main.tf index 55634ed..5bccc50 100644 --- a/main.tf +++ b/main.tf @@ -53,6 +53,8 @@ locals { "Name" = var.append_pipe_postfix ? "${replace(index, "_", "-")}-pipe" : index }) ]) + + create_log_delivery = var.create && var.create_log_delivery } data "aws_cloudwatch_event_bus" "this" { @@ -73,11 +75,71 @@ resource "aws_cloudwatch_event_bus" "this" { dynamic "dead_letter_config" { for_each = length(var.dead_letter_config) > 0 ? [var.dead_letter_config] : [] + content { arn = try(dead_letter_config.value.arn, null) } } + dynamic "log_config" { + for_each = var.log_config != null ? [var.log_config] : [] + + content { + include_detail = try(log_config.value.include_detail, null) + level = try(upper(log_config.value.level), null) + } + } + + tags = var.tags +} + +resource "aws_cloudwatch_log_delivery_source" "this" { + count = local.create_log_delivery && var.create_log_delivery_source ? 1 : 0 + + region = var.region + + name = coalesce(var.log_delivery_source_name, var.bus_name) + log_type = try(format("%s_LOGS", contains(["INFO", "ERROR", "TRACE"], upper(var.log_config.level)) ? upper(var.log_config.level) : "ERROR"), "ERROR_LOGS") + resource_arn = var.create_bus ? aws_cloudwatch_event_bus.this[0].arn : data.aws_cloudwatch_event_bus.this[0].arn + + tags = var.tags +} + +resource "aws_cloudwatch_log_delivery_destination" "this" { + for_each = { for k, v in var.log_delivery : k => v if(local.create_log_delivery && try(v.enabled, true)) } + + region = var.region + + name = coalesce(each.value.name, "${var.bus_name}-${each.key}") + output_format = each.value.output_format + + delivery_destination_configuration { + destination_resource_arn = each.value.destination_arn + } + + tags = var.tags +} + +resource "aws_cloudwatch_log_delivery" "this" { + for_each = { for k, v in var.log_delivery : k => v if(local.create_log_delivery && try(v.enabled, true)) } + + region = var.region + + delivery_source_name = var.create_log_delivery_source ? aws_cloudwatch_log_delivery_source.this[0].name : each.value.source_name + delivery_destination_arn = aws_cloudwatch_log_delivery_destination.this[each.key].arn + + field_delimiter = each.value.field_delimiter + record_fields = each.value.record_fields + + dynamic "s3_delivery_configuration" { + for_each = each.value.s3_delivery_configuration != null ? [each.value.s3_delivery_configuration] : [] + + content { + enable_hive_compatible_path = s3_delivery_configuration.value.enable_hive_compatible_path + suffix_path = s3_delivery_configuration.value.suffix_path + } + } + tags = var.tags } diff --git a/outputs.tf b/outputs.tf index 97e2b66..0246b0b 100644 --- a/outputs.tf +++ b/outputs.tf @@ -161,6 +161,17 @@ output "eventbridge_pipes" { value = aws_pipes_pipe.this } +# EventBridge Log Delivery Source +output "eventbridge_log_delivery_source_arn" { + description = "The EventBridge Bus CloudWatch Log Delivery Source ARN" + value = try(aws_cloudwatch_log_delivery_source.this[0].arn, "") +} + +output "eventbridge_log_delivery_source_name" { + description = "The EventBridge Bus CloudWatch Log Delivery Source Name" + value = try(aws_cloudwatch_log_delivery_source.this[0].name, "") +} + # IAM Roles output "eventbridge_pipes_iam_roles" { description = "The EventBridge Pipes IAM roles created and their attributes" diff --git a/variables.tf b/variables.tf index 445a993..fa86a99 100644 --- a/variables.tf +++ b/variables.tf @@ -118,6 +118,18 @@ variable "create_pipes" { default = true } +variable "create_log_delivery_source" { + description = "Controls whether EventBridge log delivery source resource should be created" + type = bool + default = true +} + +variable "create_log_delivery" { + description = "Controls whether EventBridge log delivery resources should be created" + type = bool + default = true +} + ####################### variable "region" { @@ -138,6 +150,39 @@ variable "bus_description" { default = null } +variable "log_config" { + description = "The configuration block for the EventBridge bus log config settings" + type = object({ + include_detail = string + level = string + }) + default = null +} + +variable "log_delivery" { + description = "Map of the configuration block for the EventBridge bus log delivery settings (key is the type of log delivery: cloudwatch_logs, s3, firehose)" + type = map(object({ + enabled = optional(bool, true) + destination_arn = string + source_name = optional(string) + name = optional(string) + output_format = optional(string) + field_delimiter = optional(string) + record_fields = optional(list(string)) + s3_delivery_configuration = optional(object({ + enable_hive_compatible_path = optional(bool) + suffix_path = optional(string) + })) + })) + default = {} +} + +variable "log_delivery_source_name" { + description = "Name of log delivery source" + type = string + default = null +} + variable "event_source_name" { description = "The partner event source that the new event bus will be matched with. Must match name." type = string diff --git a/versions.tf b/versions.tf index 0d66b2d..36ee0bc 100644 --- a/versions.tf +++ b/versions.tf @@ -4,7 +4,7 @@ terraform { required_providers { aws = { source = "hashicorp/aws" - version = ">= 6.2" + version = ">= 6.6" } } }