diff --git a/README.md b/README.md
index 239591a..9262527 100644
--- a/README.md
+++ b/README.md
@@ -4,16 +4,12 @@ Terraform module to create EventBridge resources.
## Supported Features
-- Creates AWS EventBridge Resources (bus, rules, targets, permissions, connections, destinations)
+- Creates AWS EventBridge Resources (bus, rules, targets, permissions, connections, destinations, schedules and schedule groups)
- Attach resources to an existing EventBridge bus
- Support AWS EventBridge Archives and Replays
- Conditional creation for many types of resources
- Support IAM policy attachments and various ways to create and attach additional policies
-## Feature Roadmap
-
-- Support monitoring usage with Cloudwatch Metrics
-
## Usage
### EventBridge Complete
@@ -230,6 +226,29 @@ module "eventbridge" {
}
```
+### EventBridge Scheduler which triggers Lambda Function
+
+```hcl
+module "eventbridge" {
+ source = "terraform-aws-modules/eventbridge/aws"
+
+ bus_name = "example" # "default" bus already support schedule_expression in rules
+
+ attach_lambda_policy = true
+ lambda_target_arns = ["arn:aws:lambda:us-east-1:135367859851:function:resolved-penguin-lambda"]
+
+ schedules = {
+ lambda-cron = {
+ description = "Trigger for a Lambda"
+ schedule_expression = "rate(1 day)"
+ timezone = "Europe/London"
+ arn = "arn:aws:lambda:us-east-1:135367859851:function:resolved-penguin-lambda"
+ input = jsonencode({ "job" : "cron-by-rate" })
+ }
+ }
+}
+```
+
### EventBridge API Destination
```hcl
@@ -324,6 +343,8 @@ module "eventbridge" {
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
+ create_schedule_groups = false # to control creation of EventBridge Schedule Group resources
+ create_schedules = false # to control creation of EventBridge Schedule resources
attach_cloudwatch_policy = false
attach_ecs_policy = false
@@ -346,8 +367,9 @@ 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.
+* [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.
-* [Lambda Scheduling Events](https://github.com/terraform-aws-modules/terraform-aws-eventbridge/tree/master/examples/with-lambda-scheduling) - Trigger Lambda functions on schedule.
+* [Lambda Scheduling Events](https://github.com/terraform-aws-modules/terraform-aws-eventbridge/tree/master/examples/with-lambda-scheduling) - Trigger Lambda functions on schedule (works only with default bus).
* [API Destination](https://github.com/terraform-aws-modules/terraform-aws-eventbridge/tree/master/examples/with-api-destination) - Control access to EventBridge using API destinations.
@@ -409,6 +431,8 @@ No modules.
| [aws_iam_role.eventbridge](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
| [aws_iam_role_policy_attachment.additional_many](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
| [aws_iam_role_policy_attachment.additional_one](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
+| [aws_scheduler_schedule.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/scheduler_schedule) | resource |
+| [aws_scheduler_schedule_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/scheduler_schedule_group) | resource |
| [aws_schemas_discoverer.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/schemas_discoverer) | resource |
| [aws_cloudwatch_event_bus.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/cloudwatch_event_bus) | data source |
| [aws_iam_policy.tracing](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy) | data source |
@@ -432,6 +456,8 @@ No modules.
| [append\_connection\_postfix](#input\_append\_connection\_postfix) | Controls whether to append '-connection' to the name of the connection | `bool` | `true` | no |
| [append\_destination\_postfix](#input\_append\_destination\_postfix) | Controls whether to append '-destination' to the name of the destination | `bool` | `true` | no |
| [append\_rule\_postfix](#input\_append\_rule\_postfix) | Controls whether to append '-rule' to the name of the rule | `bool` | `true` | no |
+| [append\_schedule\_group\_postfix](#input\_append\_schedule\_group\_postfix) | Controls whether to append '-group' to the name of the schedule group | `bool` | `true` | no |
+| [append\_schedule\_postfix](#input\_append\_schedule\_postfix) | Controls whether to append '-schedule' to the name of the schedule | `bool` | `true` | 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 |
@@ -459,6 +485,8 @@ No modules.
| [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 |
+| [create\_schedule\_groups](#input\_create\_schedule\_groups) | Controls whether EventBridge Schedule Group resources should be created | `bool` | `true` | no |
+| [create\_schedules](#input\_create\_schedules) | Controls whether EventBridge Schedule resources should be created | `bool` | `true` | no |
| [create\_schemas\_discoverer](#input\_create\_schemas\_discoverer) | Controls whether default schemas discoverer should be created | `bool` | `false` | no |
| [create\_targets](#input\_create\_targets) | Controls whether EventBridge Target resources should be created | `bool` | `true` | no |
| [ecs\_target\_arns](#input\_ecs\_target\_arns) | The Amazon Resource Name (ARN) of the AWS ECS Tasks you want to use as EventBridge targets | `list(string)` | `[]` | no |
@@ -481,29 +509,37 @@ No modules.
| [role\_permissions\_boundary](#input\_role\_permissions\_boundary) | The ARN of the policy that is used to set the permissions boundary for the IAM role used by EventBridge | `string` | `null` | no |
| [role\_tags](#input\_role\_tags) | A map of tags to assign to IAM role | `map(string)` | `{}` | no |
| [rules](#input\_rules) | A map of objects with EventBridge Rule definitions. | `map(any)` | `{}` | no |
+| [schedule\_group\_timeouts](#input\_schedule\_group\_timeouts) | A map of objects with EventBridge Schedule Group create and delete timeouts. | `map(string)` | `{}` | no |
+| [schedule\_groups](#input\_schedule\_groups) | A map of objects with EventBridge Schedule Group definitions. | `any` | `{}` | no |
+| [schedules](#input\_schedules) | A map of objects with EventBridge Schedule definitions. | `map(any)` | `{}` | no |
| [schemas\_discoverer\_description](#input\_schemas\_discoverer\_description) | Default schemas discoverer description | `string` | `"Auto schemas discoverer event"` | no |
| [sfn\_target\_arns](#input\_sfn\_target\_arns) | The Amazon Resource Name (ARN) of the StepFunctions you want to use as EventBridge targets | `list(string)` | `[]` | no |
| [sns\_target\_arns](#input\_sns\_target\_arns) | The Amazon Resource Name (ARN) of the AWS SNS's you want to use as EventBridge targets | `list(string)` | `[]` | no |
| [sqs\_target\_arns](#input\_sqs\_target\_arns) | The Amazon Resource Name (ARN) of the AWS SQS Queues you want to use as EventBridge targets | `list(string)` | `[]` | no |
| [tags](#input\_tags) | A map of tags to assign to resources. | `map(string)` | `{}` | no |
| [targets](#input\_targets) | A map of objects with EventBridge Target definitions. | `any` | `{}` | no |
-| [trusted\_entities](#input\_trusted\_entities) | Step Function additional trusted entities for assuming roles (trust relationship) | `list(string)` | `[]` | no |
+| [trusted\_entities](#input\_trusted\_entities) | Additional trusted entities for assuming roles (trust relationship) | `list(string)` | `[]` | no |
## Outputs
| 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\_api\_destination\_arns](#output\_eventbridge\_api\_destination\_arns) | The EventBridge API Destination ARNs |
+| [eventbridge\_archive\_arns](#output\_eventbridge\_archive\_arns) | The EventBridge Archive ARNs |
+| [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\_connection\_arns](#output\_eventbridge\_connection\_arns) | The EventBridge Connection Arns |
+| [eventbridge\_connection\_ids](#output\_eventbridge\_connection\_ids) | The EventBridge Connection IDs |
+| [eventbridge\_permission\_ids](#output\_eventbridge\_permission\_ids) | The EventBridge Permission IDs |
| [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 |
-| [eventbridge\_rule\_arns](#output\_eventbridge\_rule\_arns) | The EventBridge Rule ARNs created |
-| [eventbridge\_rule\_ids](#output\_eventbridge\_rule\_ids) | The EventBridge Rule IDs created |
+| [eventbridge\_rule\_arns](#output\_eventbridge\_rule\_arns) | The EventBridge Rule ARNs |
+| [eventbridge\_rule\_ids](#output\_eventbridge\_rule\_ids) | The EventBridge Rule IDs |
+| [eventbridge\_schedule\_arns](#output\_eventbridge\_schedule\_arns) | The EventBridge Schedule ARNs created |
+| [eventbridge\_schedule\_group\_arns](#output\_eventbridge\_schedule\_group\_arns) | The EventBridge Schedule Group ARNs |
+| [eventbridge\_schedule\_group\_ids](#output\_eventbridge\_schedule\_group\_ids) | The EventBridge Schedule Group IDs |
+| [eventbridge\_schedule\_group\_states](#output\_eventbridge\_schedule\_group\_states) | The EventBridge Schedule Group states |
+| [eventbridge\_schedule\_ids](#output\_eventbridge\_schedule\_ids) | The EventBridge Schedule IDs created |
## Authors
diff --git a/examples/api-gateway-event-source/main.tf b/examples/api-gateway-event-source/main.tf
index bfa10d1..de7764c 100644
--- a/examples/api-gateway-event-source/main.tf
+++ b/examples/api-gateway-event-source/main.tf
@@ -1,5 +1,5 @@
provider "aws" {
- region = "ap-southeast-1"
+ region = "eu-west-1"
# Make it faster by skipping something
skip_metadata_api_check = true
diff --git a/examples/complete/main.tf b/examples/complete/main.tf
index 998f9e6..7e7c9d1 100644
--- a/examples/complete/main.tf
+++ b/examples/complete/main.tf
@@ -1,5 +1,5 @@
provider "aws" {
- region = "ap-southeast-1"
+ region = "eu-west-1"
# Make it faster by skipping something
skip_metadata_api_check = true
diff --git a/examples/default-bus/main.tf b/examples/default-bus/main.tf
index 362c017..a36db86 100644
--- a/examples/default-bus/main.tf
+++ b/examples/default-bus/main.tf
@@ -1,5 +1,5 @@
provider "aws" {
- region = "ap-southeast-1"
+ region = "eu-west-1"
# Make it faster by skipping something
skip_metadata_api_check = true
diff --git a/examples/with-api-destination/main.tf b/examples/with-api-destination/main.tf
index e207290..7f5bb07 100644
--- a/examples/with-api-destination/main.tf
+++ b/examples/with-api-destination/main.tf
@@ -1,5 +1,5 @@
provider "aws" {
- region = "ap-southeast-1"
+ region = "eu-west-1"
# Make it faster by skipping something
skip_metadata_api_check = true
diff --git a/examples/with-archive/main.tf b/examples/with-archive/main.tf
index f5f4623..5c5d009 100644
--- a/examples/with-archive/main.tf
+++ b/examples/with-archive/main.tf
@@ -1,5 +1,5 @@
provider "aws" {
- region = "ap-southeast-1"
+ region = "eu-west-1"
# Make it faster by skipping something
skip_metadata_api_check = true
diff --git a/examples/with-ecs-scheduling/main.tf b/examples/with-ecs-scheduling/main.tf
index a1515ef..1495397 100644
--- a/examples/with-ecs-scheduling/main.tf
+++ b/examples/with-ecs-scheduling/main.tf
@@ -1,5 +1,5 @@
provider "aws" {
- region = "ap-southeast-1"
+ region = "eu-west-1"
# Make it faster by skipping something
skip_metadata_api_check = true
diff --git a/examples/with-lambda-scheduling/main.tf b/examples/with-lambda-scheduling/main.tf
index 6498ba6..e3b9324 100644
--- a/examples/with-lambda-scheduling/main.tf
+++ b/examples/with-lambda-scheduling/main.tf
@@ -1,5 +1,5 @@
provider "aws" {
- region = "ap-southeast-1"
+ region = "eu-west-1"
# Make it faster by skipping something
skip_metadata_api_check = true
diff --git a/examples/with-permissions/main.tf b/examples/with-permissions/main.tf
index 0f0d711..a4e5ebf 100644
--- a/examples/with-permissions/main.tf
+++ b/examples/with-permissions/main.tf
@@ -1,5 +1,5 @@
provider "aws" {
- region = "ap-southeast-1"
+ region = "eu-west-1"
# Make it faster by skipping something
skip_metadata_api_check = true
diff --git a/examples/with-schedules/README.md b/examples/with-schedules/README.md
new file mode 100644
index 0000000..527af5a
--- /dev/null
+++ b/examples/with-schedules/README.md
@@ -0,0 +1,63 @@
+# EventBridge Scheduler with Schedule Groups Example
+
+Configuration in this directory creates EventBridge Scheduler resources which triggers Lambda Function.
+
+## 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) | >= 1.0 |
+| [aws](#requirement\_aws) | >= 4.64 |
+| [null](#requirement\_null) | >= 2.0 |
+| [random](#requirement\_random) | >= 3.0 |
+
+## Providers
+
+| Name | Version |
+|------|---------|
+| [null](#provider\_null) | >= 2.0 |
+| [random](#provider\_random) | >= 3.0 |
+
+## Modules
+
+| Name | Source | Version |
+|------|--------|---------|
+| [eventbridge](#module\_eventbridge) | ../../ | n/a |
+| [lambda](#module\_lambda) | terraform-aws-modules/lambda/aws | ~> 5.0 |
+
+## Resources
+
+| Name | Type |
+|------|------|
+| [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 |
+
+## Inputs
+
+No inputs.
+
+## Outputs
+
+| Name | Description |
+|------|-------------|
+| [eventbridge\_schedule\_arns](#output\_eventbridge\_schedule\_arns) | The EventBridge Schedule ARNs created |
+| [eventbridge\_schedule\_group\_arns](#output\_eventbridge\_schedule\_group\_arns) | The EventBridge Schedule Group ARNs |
+| [eventbridge\_schedule\_group\_ids](#output\_eventbridge\_schedule\_group\_ids) | The EventBridge Schedule Group IDs |
+| [eventbridge\_schedule\_group\_states](#output\_eventbridge\_schedule\_group\_states) | The EventBridge Schedule Group states |
+| [eventbridge\_schedule\_ids](#output\_eventbridge\_schedule\_ids) | The EventBridge Schedule IDs created |
+| [lambda\_function\_arn](#output\_lambda\_function\_arn) | The ARN of the Lambda Function |
+| [lambda\_function\_name](#output\_lambda\_function\_name) | The name of the Lambda Function |
+
diff --git a/examples/with-schedules/main.tf b/examples/with-schedules/main.tf
new file mode 100644
index 0000000..c710ad9
--- /dev/null
+++ b/examples/with-schedules/main.tf
@@ -0,0 +1,96 @@
+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
+ skip_requesting_account_id = true
+}
+
+module "eventbridge" {
+ source = "../../"
+
+ create_bus = true
+ bus_name = "example" # "default" bus already support schedule_expression in rules
+
+ attach_lambda_policy = true
+ lambda_target_arns = [module.lambda.lambda_function_arn]
+
+ schedule_groups = {
+ dev = {
+ name_prefix = "tmp-dev-"
+ }
+ prod = {
+ name = "prod"
+ tags = {
+ Env = "SuperProd"
+ }
+ }
+ }
+
+ schedules = {
+ lambda-cron = {
+ group_name = "dev"
+ description = "Trigger for a Lambda"
+ schedule_expression = "cron(0 1 * * ? *)"
+ timezone = "Europe/London"
+ arn = module.lambda.lambda_function_arn
+ input = jsonencode({ "job" : "cron-by-rate" })
+ }
+ prod-lambda-cron = {
+ group_name = "prod"
+ schedule_expression = "rate(10 hours)"
+ arn = module.lambda.lambda_function_arn
+ }
+ }
+}
+
+##################
+# Extra resources
+##################
+
+resource "random_pet" "this" {
+ length = 2
+}
+
+#############################################
+# Using packaged function from Lambda module
+#############################################
+
+module "lambda" {
+ source = "terraform-aws-modules/lambda/aws"
+ version = "~> 5.0"
+
+ function_name = "${random_pet.this.id}-lambda"
+ handler = "index.lambda_handler"
+ runtime = "python3.8"
+
+ create_package = false
+ local_existing_package = local.downloaded
+
+ trusted_entities = ["scheduler.amazonaws.com"]
+
+ create_current_version_allowed_triggers = false
+ allowed_triggers = {
+ ScanAmiRule = {
+ principal = "scheduler.amazonaws.com"
+ source_arn = module.eventbridge.eventbridge_schedule_arns["lambda-cron"]
+ }
+ }
+}
+
+locals {
+ package_url = "https://raw.githubusercontent.com/terraform-aws-modules/terraform-aws-lambda/master/examples/fixtures/python3.8-zip/existing_package.zip"
+ downloaded = "downloaded_package_${md5(local.package_url)}.zip"
+}
+
+resource "null_resource" "download_package" {
+ triggers = {
+ downloaded = local.downloaded
+ }
+
+ provisioner "local-exec" {
+ command = "curl -L -o ${local.downloaded} ${local.package_url}"
+ }
+}
diff --git a/examples/with-schedules/outputs.tf b/examples/with-schedules/outputs.tf
new file mode 100644
index 0000000..b4ceac4
--- /dev/null
+++ b/examples/with-schedules/outputs.tf
@@ -0,0 +1,37 @@
+# EventBridge Schedule Group
+output "eventbridge_schedule_group_ids" {
+ description = "The EventBridge Schedule Group IDs"
+ value = module.eventbridge.eventbridge_schedule_arns
+}
+
+output "eventbridge_schedule_group_arns" {
+ description = "The EventBridge Schedule Group ARNs"
+ value = module.eventbridge.eventbridge_schedule_group_arns
+}
+
+output "eventbridge_schedule_group_states" {
+ description = "The EventBridge Schedule Group states"
+ value = module.eventbridge.eventbridge_schedule_group_states
+}
+
+# EventBridge Schedule
+output "eventbridge_schedule_ids" {
+ description = "The EventBridge Schedule IDs created"
+ value = module.eventbridge.eventbridge_schedule_ids
+}
+
+output "eventbridge_schedule_arns" {
+ description = "The EventBridge Schedule ARNs created"
+ value = module.eventbridge.eventbridge_schedule_arns
+}
+
+# Lambda Function
+output "lambda_function_arn" {
+ description = "The ARN of the Lambda Function"
+ value = module.lambda.lambda_function_arn
+}
+
+output "lambda_function_name" {
+ description = "The name of the Lambda Function"
+ value = module.lambda.lambda_function_name
+}
diff --git a/examples/with-schedules/variables.tf b/examples/with-schedules/variables.tf
new file mode 100644
index 0000000..e69de29
diff --git a/examples/with-schedules/versions.tf b/examples/with-schedules/versions.tf
new file mode 100644
index 0000000..cdf3d85
--- /dev/null
+++ b/examples/with-schedules/versions.tf
@@ -0,0 +1,18 @@
+terraform {
+ required_version = ">= 1.0"
+
+ required_providers {
+ aws = {
+ source = "hashicorp/aws"
+ version = ">= 4.64"
+ }
+ random = {
+ source = "hashicorp/random"
+ version = ">= 3.0"
+ }
+ null = {
+ source = "hashicorp/null"
+ version = ">= 2.0"
+ }
+ }
+}
diff --git a/iam.tf b/iam.tf
index 55927f9..1ae6a2f 100644
--- a/iam.tf
+++ b/iam.tf
@@ -21,7 +21,7 @@ data "aws_iam_policy_document" "assume_role" {
principals {
type = "Service"
- identifiers = distinct(concat(["events.amazonaws.com"], var.trusted_entities))
+ identifiers = distinct(concat(["events.amazonaws.com"], var.trusted_entities, length(keys(var.schedules)) > 0 && var.create_schedules ? ["scheduler.amazonaws.com"] : []))
}
}
}
diff --git a/main.tf b/main.tf
index 43528a0..6fddaee 100644
--- a/main.tf
+++ b/main.tf
@@ -29,6 +29,19 @@ locals {
"Name" = var.append_destination_postfix ? "${replace(index, "_", "-")}-destination" : index
})
])
+ eventbridge_schedule_groups = {
+ for index, group in var.schedule_groups :
+ index => merge(group, {
+ "Name" = var.append_schedule_group_postfix ? "${replace(index, "_", "-")}-group" : index
+ })
+ }
+ eventbridge_schedules = flatten([
+ for index, sched in var.schedules :
+ merge(sched, {
+ "name" = index
+ "Name" = var.append_schedule_postfix ? "${replace(index, "_", "-")}-schedule" : index
+ })
+ ])
}
data "aws_cloudwatch_event_bus" "this" {
@@ -232,7 +245,7 @@ resource "aws_cloudwatch_event_target" "this" {
resource "aws_cloudwatch_event_archive" "this" {
for_each = var.create && var.create_archives ? var.archives : {}
- name = each.key
+ name = lookup(each.value, "name", each.key)
event_source_arn = try(each.value["event_source_arn"], aws_cloudwatch_event_bus.this[0].arn)
description = lookup(each.value, "description", null)
@@ -402,3 +415,182 @@ resource "aws_cloudwatch_event_api_destination" "this" {
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
}
+
+resource "aws_scheduler_schedule_group" "this" {
+ for_each = { for k, v in local.eventbridge_schedule_groups : k => v if var.create && var.create_schedule_groups }
+
+ name = lookup(each.value, "name_prefix", null) == null ? try(each.value.name, each.key) : null
+ name_prefix = lookup(each.value, "name_prefix", null) != null ? each.value.name_prefix : null
+
+ tags = lookup(each.value, "tags", {})
+
+ timeouts {
+ create = try(var.schedule_group_timeouts.create, null)
+ delete = try(var.schedule_group_timeouts.delete, null)
+ }
+
+ lifecycle {
+ create_before_destroy = true
+ }
+}
+
+resource "aws_scheduler_schedule" "this" {
+ for_each = { for k, v in local.eventbridge_schedules : v.name => v if var.create && var.create_schedules }
+
+ name = each.value.Name
+ name_prefix = lookup(each.value, "name_prefix", null)
+ description = lookup(each.value, "description", null)
+ group_name = try(aws_scheduler_schedule_group.this[each.value.group_name].id, lookup(each.value, "group_name", null))
+
+ start_date = lookup(each.value, "start_date", null)
+ end_date = lookup(each.value, "end_date", null)
+
+ kms_key_arn = lookup(each.value, "kms_key_arn", null)
+
+ schedule_expression = each.value.schedule_expression
+ schedule_expression_timezone = lookup(each.value, "timezone", null)
+
+ state = lookup(each.value, "state", true) ? "ENABLED" : "DISABLED"
+
+ flexible_time_window {
+ maximum_window_in_minutes = lookup(each.value, "maximum_window_in_minutes", null)
+ mode = lookup(each.value, "use_flexible_time_window", false) ? "FLEXIBLE" : "OFF"
+ }
+
+ target {
+ arn = each.value.arn
+ role_arn = can(length(each.value.role_arn) > 0) ? each.value.role_arn : aws_iam_role.eventbridge[0].arn
+
+ input = lookup(each.value, "input", null)
+
+ dynamic "dead_letter_config" {
+ for_each = lookup(each.value, "dead_letter_arn", null) != null ? [true] : []
+
+ content {
+ arn = each.value.dead_letter_arn
+ }
+ }
+
+ dynamic "ecs_parameters" {
+ for_each = lookup(each.value, "ecs_parameters", null) != null ? [
+ each.value.ecs_parameters
+ ] : []
+
+ content {
+ task_definition_arn = ecs_parameters.value.task_definition_arn
+ enable_ecs_managed_tags = lookup(ecs_parameters.value, "enable_ecs_managed_tags", null)
+ enable_execute_command = lookup(ecs_parameters.value, "enable_execute_command", null)
+ group = lookup(ecs_parameters.value, "group", null)
+ launch_type = lookup(ecs_parameters.value, "launch_type", null)
+ platform_version = lookup(ecs_parameters.value, "platform_version", null)
+ propagate_tags = lookup(ecs_parameters.value, "propagate_tags", null)
+ reference_id = lookup(ecs_parameters.value, "reference_id", null)
+ tags = lookup(ecs_parameters.value, "tags", null)
+ task_count = lookup(ecs_parameters.value, "task_count", null)
+
+ dynamic "capacity_provider_strategy" {
+ for_each = lookup(ecs_parameters.value, "capacity_provider_strategy", null) != null ? [
+ ecs_parameters.value.capacity_provider_strategy
+ ] : []
+
+ content {
+ capacity_provider = capacity_provider_strategy.value.capacity_provider
+ base = lookup(capacity_provider_strategy.value, "base", null)
+ weight = lookup(capacity_provider_strategy.value, "weight", null)
+ }
+ }
+
+ dynamic "network_configuration" {
+ for_each = lookup(ecs_parameters.value, "network_configuration", null) != null ? [
+ ecs_parameters.value.network_configuration
+ ] : []
+
+ content {
+ subnets = lookup(network_configuration.value, "subnets", null)
+ security_groups = lookup(network_configuration.value, "security_groups", null)
+ assign_public_ip = lookup(network_configuration.value, "assign_public_ip", null)
+ }
+ }
+
+ dynamic "placement_constraints" {
+ for_each = lookup(ecs_parameters.value, "placement_constraints", null) != null ? [
+ ecs_parameters.value.placement_constraints
+ ] : []
+
+ content {
+ type = placement_constraints.value.type
+ expression = lookup(placement_constraints.value, "expression", null)
+ }
+ }
+
+ dynamic "placement_strategy" {
+ for_each = lookup(ecs_parameters.value, "placement_strategy", null) != null ? [
+ ecs_parameters.value.placement_strategy
+ ] : []
+
+ content {
+ type = placement_strategy.value.type
+ field = lookup(placement_strategy.value, "field", null)
+ }
+ }
+ }
+ }
+
+ dynamic "eventbridge_parameters" {
+ for_each = lookup(each.value, "eventbridge_parameters", null) != null ? [
+ each.value.eventbridge_parameters
+ ] : []
+
+ content {
+ detail_type = eventbridge_parameters.value.detail_type
+ source = eventbridge_parameters.value.source
+ }
+ }
+
+ dynamic "kinesis_parameters" {
+ for_each = lookup(each.value, "kinesis_parameters", null) != null ? [true] : []
+
+ content {
+ partition_key = kinesis_parameters.value.partition_key
+ }
+ }
+
+ dynamic "sagemaker_pipeline_parameters" {
+ for_each = lookup(each.value, "sagemaker_pipeline_parameters", null) != null ? [
+ each.value.sagemaker_pipeline_parameters
+ ] : []
+
+ content {
+ dynamic "pipeline_parameter" {
+ for_each = lookup(sagemaker_pipeline_parameters, "pipeline_parameter", null) != null ? [
+ sagemaker_pipeline_parameters.value.pipeline_parameter
+ ] : []
+
+ content {
+ name = pipeline_parameter.value.name
+ value = pipeline_parameter.value.value
+ }
+ }
+ }
+ }
+
+ dynamic "sqs_parameters" {
+ for_each = lookup(each.value, "message_group_id", null) != null ? [true] : []
+
+ content {
+ message_group_id = each.value.message_group_id
+ }
+ }
+
+ dynamic "retry_policy" {
+ for_each = lookup(each.value, "retry_policy", null) != null ? [
+ each.value.retry_policy
+ ] : []
+
+ content {
+ maximum_event_age_in_seconds = retry_policy.value.maximum_event_age_in_seconds
+ maximum_retry_attempts = retry_policy.value.maximum_retry_attempts
+ }
+ }
+ }
+}
diff --git a/outputs.tf b/outputs.tf
index 83d02d8..0261ceb 100644
--- a/outputs.tf
+++ b/outputs.tf
@@ -5,48 +5,75 @@ output "eventbridge_bus_name" {
}
output "eventbridge_bus_arn" {
- description = "The EventBridge Bus Arn"
+ description = "The EventBridge Bus ARN"
value = try(aws_cloudwatch_event_bus.this[0].arn, "")
}
# EventBridge Archive
output "eventbridge_archive_arns" {
- description = "The EventBridge Archive Arns created"
+ description = "The EventBridge Archive ARNs"
value = { for v in aws_cloudwatch_event_archive.this : v.name => v.arn }
}
# EventBridge Permission
output "eventbridge_permission_ids" {
- description = "The EventBridge Permission Arns created"
+ description = "The 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"
+ description = "The EventBridge Connection IDs"
value = { for k, v in aws_cloudwatch_event_connection.this : k => v.id }
}
output "eventbridge_connection_arns" {
- description = "The EventBridge Connection Arns created"
+ description = "The EventBridge Connection Arns"
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"
+ description = "The EventBridge API Destination ARNs"
value = { for k, v in aws_cloudwatch_event_api_destination.this : k => v.arn }
}
# EventBridge Rule
output "eventbridge_rule_ids" {
- description = "The EventBridge Rule IDs created"
- value = { for k in sort(keys(var.rules)) : k => try(aws_cloudwatch_event_rule.this[k].id, null) if var.create && var.create_rules }
+ description = "The EventBridge Rule IDs"
+ value = { for k, v in aws_cloudwatch_event_rule.this : k => v.id }
}
output "eventbridge_rule_arns" {
- description = "The EventBridge Rule ARNs created"
- value = { for k in sort(keys(var.rules)) : k => try(aws_cloudwatch_event_rule.this[k].arn, null) if var.create && var.create_rules }
+ description = "The EventBridge Rule ARNs"
+ value = { for k, v in aws_cloudwatch_event_rule.this : k => v.arn }
+}
+
+# EventBridge Schedule Groups
+output "eventbridge_schedule_group_ids" {
+ description = "The EventBridge Schedule Group IDs"
+ value = { for k, v in aws_scheduler_schedule_group.this : k => v.id }
+}
+
+output "eventbridge_schedule_group_arns" {
+ description = "The EventBridge Schedule Group ARNs"
+ value = { for k, v in aws_scheduler_schedule_group.this : k => v.arn }
+}
+
+output "eventbridge_schedule_group_states" {
+ description = "The EventBridge Schedule Group states"
+ value = { for k, v in aws_scheduler_schedule_group.this : k => v.state }
+}
+
+# EventBridge Schedule
+output "eventbridge_schedule_ids" {
+ description = "The EventBridge Schedule IDs created"
+ value = { for k, v in aws_scheduler_schedule.this : k => v.id }
+}
+
+output "eventbridge_schedule_arns" {
+ description = "The EventBridge Schedule ARNs created"
+ value = { for k, v in aws_scheduler_schedule.this : k => v.arn }
}
# IAM Role
diff --git a/variables.tf b/variables.tf
index e598631..c130322 100644
--- a/variables.tf
+++ b/variables.tf
@@ -28,6 +28,18 @@ variable "append_destination_postfix" {
default = true
}
+variable "append_schedule_group_postfix" {
+ description = "Controls whether to append '-group' to the name of the schedule group"
+ type = bool
+ default = true
+}
+
+variable "append_schedule_postfix" {
+ description = "Controls whether to append '-schedule' to the name of the schedule"
+ type = bool
+ default = true
+}
+
variable "create_bus" {
description = "Controls whether EventBridge Bus resource should be created"
type = bool
@@ -76,6 +88,18 @@ variable "create_schemas_discoverer" {
default = false
}
+variable "create_schedule_groups" {
+ description = "Controls whether EventBridge Schedule Group resources should be created"
+ type = bool
+ default = true
+}
+
+variable "create_schedules" {
+ description = "Controls whether EventBridge Schedule resources should be created"
+ type = bool
+ default = true
+}
+
#######################
variable "bus_name" {
@@ -132,12 +156,30 @@ variable "api_destinations" {
default = {}
}
+variable "schedule_groups" {
+ description = "A map of objects with EventBridge Schedule Group definitions."
+ type = any
+ default = {}
+}
+
+variable "schedules" {
+ description = "A map of objects with EventBridge Schedule definitions."
+ type = map(any)
+ default = {}
+}
+
variable "tags" {
description = "A map of tags to assign to resources."
type = map(string)
default = {}
}
+variable "schedule_group_timeouts" {
+ description = "A map of objects with EventBridge Schedule Group create and delete timeouts."
+ type = map(string)
+ default = {}
+}
+
######
# IAM
######
@@ -337,7 +379,7 @@ variable "attach_policy_statements" {
}
variable "trusted_entities" {
- description = "Step Function additional trusted entities for assuming roles (trust relationship)"
+ description = "Additional trusted entities for assuming roles (trust relationship)"
type = list(string)
default = []
}