From 2a2938d444833c0c716466ec70dbe9f6c77df2b6 Mon Sep 17 00:00:00 2001 From: William Shelley Date: Fri, 4 Oct 2024 15:39:06 +0100 Subject: [PATCH] feat: add eventbridge rule and sns topic --- infra/terraform/modules/service/README.md | 78 ++++++++++---------- infra/terraform/modules/service/batch.tf | 89 ++++++++++++++++++++++- 2 files changed, 129 insertions(+), 38 deletions(-) diff --git a/infra/terraform/modules/service/README.md b/infra/terraform/modules/service/README.md index 3d6f53398e..fdf254af07 100644 --- a/infra/terraform/modules/service/README.md +++ b/infra/terraform/modules/service/README.md @@ -1,58 +1,62 @@ + ## Requirements -| Name | Version | -|------|---------| -| [terraform](#requirement\_terraform) | >= 1.0 | -| [aws](#requirement\_aws) | >= 5.0.0 | +| Name | Version | +| ------------------------------------------------------------------------ | -------- | +| [terraform](#requirement_terraform) | >= 1.0 | +| [aws](#requirement_aws) | >= 5.0.0 | ## Providers -| Name | Version | -|------|---------| -| [aws](#provider\_aws) | >= 5.0.0 | +| Name | Version | +| ------------------------------------------------ | -------- | +| [aws](#provider_aws) | >= 5.0.0 | ## Modules -| Name | Source | Version | -|------|--------|---------| -| [acm](#module\_acm) | terraform-aws-modules/acm/aws | ~> 5.0 | -| [batch](#module\_batch) | terraform-aws-modules/batch/aws | ~> 2.0 | -| [cloudfront](#module\_cloudfront) | terraform-aws-modules/cloudfront/aws | ~> 3.4 | -| [ecs\_cluster](#module\_ecs\_cluster) | terraform-aws-modules/ecs/aws//modules/cluster | ~> 5.10 | -| [ecs\_service](#module\_ecs\_service) | terraform-aws-modules/ecs/aws//modules/service | ~> 5.10 | -| [eventbridge](#module\_eventbridge) | terraform-aws-modules/eventbridge/aws | ~> 3.7 | -| [log\_bucket](#module\_log\_bucket) | terraform-aws-modules/s3-bucket/aws | ~> 4.0 | -| [records](#module\_records) | terraform-aws-modules/route53/aws//modules/records | ~> 4.0 | -| [route53\_records](#module\_route53\_records) | terraform-aws-modules/acm/aws | ~> 5.0 | +| Name | Source | Version | +| -------------------------------------------------------------------------------- | -------------------------------------------------- | ------- | +| [acm](#module_acm) | terraform-aws-modules/acm/aws | ~> 5.0 | +| [batch](#module_batch) | terraform-aws-modules/batch/aws | ~> 2.0 | +| [cloudfront](#module_cloudfront) | terraform-aws-modules/cloudfront/aws | ~> 3.4 | +| [ecs_cluster](#module_ecs_cluster) | terraform-aws-modules/ecs/aws//modules/cluster | ~> 5.10 | +| [ecs_service](#module_ecs_service) | terraform-aws-modules/ecs/aws//modules/service | ~> 5.10 | +| [eventbridge](#module_eventbridge) | terraform-aws-modules/eventbridge/aws | ~> 3.7 | +| [eventbridge_sns](#module_eventbridge_sns) | terraform-aws-modules/eventbridge/aws | n/a | +| [log_bucket](#module_log_bucket) | terraform-aws-modules/s3-bucket/aws | ~> 4.0 | +| [records](#module_records) | terraform-aws-modules/route53/aws//modules/records | ~> 4.0 | +| [route53_records](#module_route53_records) | terraform-aws-modules/acm/aws | ~> 5.0 | +| [sns_batch_fail](#module_sns_batch_fail) | terraform-aws-modules/sns/aws | n/a | ## Resources -| Name | Type | -|------|------| -| [aws_cloudfront_function.rewrite_uri](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudfront_function) | resource | -| [aws_cloudwatch_log_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_group) | resource | -| [aws_lb_listener_rule.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb_listener_rule) | resource | -| [aws_lb_target_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb_target_group) | resource | -| [aws_canonical_user_id.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/canonical_user_id) | data source | +| Name | Type | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------- | +| [aws_cloudfront_function.rewrite_uri](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudfront_function) | resource | +| [aws_cloudwatch_log_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_group) | resource | +| [aws_lb_listener_rule.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb_listener_rule) | resource | +| [aws_lb_target_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb_target_group) | resource | +| [aws_canonical_user_id.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/canonical_user_id) | data source | | [aws_cloudfront_log_delivery_canonical_user_id.cloudfront](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/cloudfront_log_delivery_canonical_user_id) | data source | -| [aws_route53_zone.public](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/route53_zone) | data source | -| [aws_s3_bucket.assets](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/s3_bucket) | data source | +| [aws_route53_zone.public](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/route53_zone) | data source | +| [aws_s3_bucket.assets](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/s3_bucket) | data source | ## Inputs -| Name | Description | Type | Default | Required | -|------|-------------|------|---------|:--------:| -| [assets\_version](#input\_assets\_version) | The version of the assets | `string` | n/a | yes | -| [batch](#input\_batch) | Configuration for the batch process |
object({
version = string
repository = string
subnet_ids = list(string)
task_iam_role_statements = list(object({
effect = string
actions = list(string)
resources = list(string)
}))
jobs = list(object({
name = string
commands = list(string)
cpu = optional(number, 1)
memory = optional(number, 2048)
timeout = optional(number, 300)
schedule = optional(string, "")
}))
})
| n/a | yes | -| [domain\_name](#input\_domain\_name) | The domain name for the environment | `string` | n/a | yes | -| [elasticache\_url](#input\_elasticache\_url) | The URL of the Elasticache cluster | `string` | n/a | yes | -| [environment](#input\_environment) | The environment to deploy to | `string` | n/a | yes | -| [legacy\_environment](#input\_legacy\_environment) | The legacy environment to deploy use | `string` | n/a | yes | -| [services](#input\_services) | The services to deploy |
map(object({
version = string
repository = string
cpu = number
memory = number
task_iam_role_statements = list(object({
effect = string
actions = list(string)
resources = list(string)
}))
add_cdn_url_to_env = optional(bool, false)
lb_listener_arn = string
// The reason for this was to enable the parallel running of ECS and EC2 services.
// This boolean will control the flow of traffic. If `true`, traffic will go to ECS. If `false`, traffic will go to EC2.
// Can be removed when EC2 services are removed.
listener_rule_enable = optional(bool, true)
listener_rule_priority = optional(number, 10)
listener_rule_host_header = optional(string, "*")
security_group_ids = list(string)
subnet_ids = list(string)
vpc_id = optional(string, null)
}))
| `{}` | no | -| [vpc\_id](#input\_vpc\_id) | The VPC ID | `string` | n/a | yes | +| Name | Description | Type | Default | Required | +| --------------------------------------------------------------------------------------- | ------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | :------: | +| [assets_version](#input_assets_version) | The version of the assets | `string` | n/a | yes | +| [batch](#input_batch) | Configuration for the batch process |
object({
version = string
repository = string
subnet_ids = list(string)
task_iam_role_statements = list(object({
effect = string
actions = list(string)
resources = list(string)
}))
jobs = list(object({
name = string
commands = list(string)
cpu = optional(number, 1)
memory = optional(number, 2048)
timeout = optional(number, 300)
schedule = optional(string, "")
}))
})
| n/a | yes | +| [domain_name](#input_domain_name) | The domain name for the environment | `string` | n/a | yes | +| [elasticache_url](#input_elasticache_url) | The URL of the Elasticache cluster | `string` | n/a | yes | +| [environment](#input_environment) | The environment to deploy to | `string` | n/a | yes | +| [legacy_environment](#input_legacy_environment) | The legacy environment to deploy use | `string` | n/a | yes | +| [services](#input_services) | The services to deploy |
map(object({
version = string
repository = string
cpu = number
memory = number
task_iam_role_statements = list(object({
effect = string
actions = list(string)
resources = list(string)
}))
add_cdn_url_to_env = optional(bool, false)
lb_listener_arn = string
// The reason for this was to enable the parallel running of ECS and EC2 services.
// This boolean will control the flow of traffic. If `true`, traffic will go to ECS. If `false`, traffic will go to EC2.
// Can be removed when EC2 services are removed.
listener_rule_enable = optional(bool, true)
listener_rule_priority = optional(number, 10)
listener_rule_host_header = optional(string, "\*")
security_group_ids = list(string)
subnet_ids = list(string)
vpc_id = optional(string, null)
}))
| `{}` | no | +| [vpc_id](#input_vpc_id) | The VPC ID | `string` | n/a | yes | ## Outputs No outputs. + diff --git a/infra/terraform/modules/service/batch.tf b/infra/terraform/modules/service/batch.tf index 7beb1d3b95..8c53c9c346 100644 --- a/infra/terraform/modules/service/batch.tf +++ b/infra/terraform/modules/service/batch.tf @@ -155,9 +155,96 @@ module "eventbridge" { } schedules = local.schedules + +} + +module "eventbridge_sns" { + source = "terraform-aws-modules/eventbridge/aws" + + create_bus = false + + role_name = "batch-fail-role" + + rules = { + batch-fail-sns = { + name = "${var.environment}-batch-fail-event" + description = "Capture failed Batch Events sent to SNS" + event_pattern = jsonencode({ + "detail-type" : [ + "Batch Job State Change" + ], + "source" : [ + "aws.batch" + ], + "detail" : { + "status" : [ + "FAILED" + ] + } + }) + enabled = true + } + } + + targets = { + batch-fail-sns = [ + { + name = "batch-fail-event" + arn = module.sns_batch_fail.topic_arn + } + ] + } + +} + +module "sns_batch_fail" { + source = "terraform-aws-modules/sns/aws" + + name = "${var.environment}-batch-fail-topic" + use_name_prefix = true + display_name = "batch-event-failed" + + + create_topic_policy = true + enable_default_topic_policy = true + topic_policy_statements = { + pub = { + actions = ["sns:Publish"] + principals = [{ + type = "AWS" + identifiers = [ + "arn:aws:iam::${data.aws_caller_identity.current.account_id}:root" + ] + }] + }, + + sub = { + actions = [ + "sns:Subscribe", + "sns:Receive", + ] + + principals = [{ + type = "Service" + identifiers = ["events.amazonaws.com"] + }] + + conditions = [{ + test = "ArnLike" + variable = "aws:SourceArn" + values = [module.eventbridge_sns.eventbridge_bus_arn] + }] + } + } + + tags = { + "Name" = "${var.environment}-aws-sns-batch-fail" + + } + } resource "aws_cloudwatch_log_group" "this" { name = "/aws/batch/vol-app-${var.environment}" retention_in_days = 1 -} +} \ No newline at end of file