From 171e14272be3699aa954bef01eb3c1c1d2b80c25 Mon Sep 17 00:00:00 2001 From: Andrew Pepler Date: Thu, 7 Dec 2023 11:05:19 +0000 Subject: [PATCH] cdpt-chaps ecs config (#4171) --- .../cdpt-chaps/application_variables.json | 12 +- terraform/environments/cdpt-chaps/ecs.tf | 244 ++++++++++++++++++ .../environments/cdpt-chaps/loadbalancer.tf | 98 +++++++ terraform/environments/cdpt-chaps/locals.tf | 18 +- terraform/environments/cdpt-chaps/outputs.tf | 3 + .../cdpt-chaps/platform_locals.tf | 1 - terraform/environments/cdpt-chaps/route53.tf | 59 +++++ 7 files changed, 427 insertions(+), 8 deletions(-) create mode 100644 terraform/environments/cdpt-chaps/ecs.tf create mode 100644 terraform/environments/cdpt-chaps/loadbalancer.tf create mode 100644 terraform/environments/cdpt-chaps/outputs.tf create mode 100644 terraform/environments/cdpt-chaps/route53.tf diff --git a/terraform/environments/cdpt-chaps/application_variables.json b/terraform/environments/cdpt-chaps/application_variables.json index 6b52bfe9b30..601d785bd20 100644 --- a/terraform/environments/cdpt-chaps/application_variables.json +++ b/terraform/environments/cdpt-chaps/application_variables.json @@ -1,16 +1,16 @@ { "accounts": { "development": { - "example_var": "dev-data" - }, - "test": { - "example_var": "test-data" + "region": "eu-west-2", + "docker_image_tag": "development" }, "preproduction": { - "example_var": "preproduction-data" + "region": "eu-west-2", + "docker_image_tag": "preproduction" }, "production": { - "example_var": "production-data" + "region": "eu-west-2", + "docker_image_tag": "production" } } } diff --git a/terraform/environments/cdpt-chaps/ecs.tf b/terraform/environments/cdpt-chaps/ecs.tf new file mode 100644 index 00000000000..e5cc2584446 --- /dev/null +++ b/terraform/environments/cdpt-chaps/ecs.tf @@ -0,0 +1,244 @@ +data "aws_ecs_task_definition" "task_definition" { + task_definition = "${local.application_name}-task-definition" + depends_on = [aws_ecs_task_definition.chaps_task_definition] +} + +resource "aws_ecs_cluster" "ecs_cluster" { + name = "${local.application_name}-ecs-cluster" + setting { + name = "containerInsights" + value = "enabled" + } +} + +resource "aws_cloudwatch_log_group" "deployment_logs" { + name = "/aws/events/deploymentLogs" + retention_in_days = "7" +} + +resource "aws_ecs_task_definition" "chaps_task_definition" { + family = "chapsFamily" + requires_compatibilities = ["FARGATE"] + network_mode = "awsvpc" + execution_role_arn = aws_iam_role.app_execution.arn + task_role_arn = aws_iam_role.app_task.arn + cpu = 1024 + memory = 2048 + container_definitions = jsonencode([ + { + name = local.application_name + image = "${local.ecr_url}:${local.application_data.accounts[local.environment].docker_image_tag}" + cpu = 1024 + memory = 2048 + essential = true + portMappings = [ + { + containerPort = 80 + protocol = "tcp" + hostPort = 80 + } + ] + environment = [ + ] + } + ]) + runtime_platform { + operating_system_family = "WINDOWS_SERVER_2019_CORE" + cpu_architecture = "X86_64" + } +} + +resource "aws_ecs_service" "ecs_service" { + depends_on = [ + aws_lb_listener.listener + ] + + name = var.networking[0].application + cluster = aws_ecs_cluster.ecs_cluster.id + task_definition = aws_ecs_task_definition.chaps_task_definition.arn + launch_type = "FARGATE" + enable_execute_command = true + desired_count = 2 + health_check_grace_period_seconds = 180 + + network_configuration { + subnets = data.aws_subnets.shared-public.ids + security_groups = [aws_security_group.ecs_service.id] + assign_public_ip = true + } + + load_balancer { + target_group_arn = aws_lb_target_group.chaps_target_group.arn + container_name = local.application_name + container_port = 80 + } + + deployment_controller { + type = "ECS" + } +} + +resource "aws_iam_role" "app_execution" { + name = "execution-${var.networking[0].application}" + + assume_role_policy = < { + name = dvo.resource_record_name + record = dvo.resource_record_value + type = dvo.resource_record_type + } + } + + domain_name_main = [for k, v in local.domain_types : v.name if k == "modernisation-platform.service.justice.gov.uk"] + domain_name_sub = [for k, v in local.domain_types : v.name if k != "modernisation-platform.service.justice.gov.uk"] + domain_record_main = [for k, v in local.domain_types : v.record if k == "modernisation-platform.service.justice.gov.uk"] + domain_record_sub = [for k, v in local.domain_types : v.record if k != "modernisation-platform.service.justice.gov.uk"] + domain_type_main = [for k, v in local.domain_types : v.type if k == "modernisation-platform.service.justice.gov.uk"] + domain_type_sub = [for k, v in local.domain_types : v.type if k != "modernisation-platform.service.justice.gov.uk"] + + ecr_url = "${local.environment_management.account_ids["core-shared-services-production"]}.dkr.ecr.eu-west-2.amazonaws.com/cdpt-chaps-ecr-repo" +} diff --git a/terraform/environments/cdpt-chaps/outputs.tf b/terraform/environments/cdpt-chaps/outputs.tf new file mode 100644 index 00000000000..49ce7495121 --- /dev/null +++ b/terraform/environments/cdpt-chaps/outputs.tf @@ -0,0 +1,3 @@ +output "task_definition" { + value = data.aws_ecs_task_definition.task_definition +} diff --git a/terraform/environments/cdpt-chaps/platform_locals.tf b/terraform/environments/cdpt-chaps/platform_locals.tf index d68844f5e25..eb0e1aa0c01 100644 --- a/terraform/environments/cdpt-chaps/platform_locals.tf +++ b/terraform/environments/cdpt-chaps/platform_locals.tf @@ -1,5 +1,4 @@ locals { - application_name = "cdpt-chaps" environment_management = jsondecode(data.aws_secretsmanager_secret_version.environment_management.secret_string) diff --git a/terraform/environments/cdpt-chaps/route53.tf b/terraform/environments/cdpt-chaps/route53.tf new file mode 100644 index 00000000000..d34737a0f59 --- /dev/null +++ b/terraform/environments/cdpt-chaps/route53.tf @@ -0,0 +1,59 @@ +// DEV + PRE-PRODUCTION DNS CONFIGURATION + +// ACM Public Certificate +resource "aws_acm_certificate" "external" { + domain_name = "modernisation-platform.service.justice.gov.uk" + validation_method = "DNS" + + subject_alternative_names = ["${var.networking[0].application}.${var.networking[0].business-unit}-${local.environment}.modernisation-platform.service.justice.gov.uk"] + tags = { + Environment = local.environment + } + + lifecycle { + create_before_destroy = true + } +} + +resource "aws_acm_certificate_validation" "external" { + certificate_arn = aws_acm_certificate.external.arn + validation_record_fqdns = [local.domain_name_main[0], local.domain_name_sub[0]] +} + +// Route53 DNS records for certificate validation +resource "aws_route53_record" "external_validation" { + provider = aws.core-network-services + + allow_overwrite = true + name = local.domain_name_main[0] + records = local.domain_record_main + ttl = 60 + type = local.domain_type_main[0] + zone_id = data.aws_route53_zone.network-services.zone_id +} + +resource "aws_route53_record" "external_validation_subdomain" { + provider = aws.core-vpc + + allow_overwrite = true + name = local.domain_name_sub[0] + records = local.domain_record_sub + ttl = 60 + type = local.domain_type_sub[0] + zone_id = data.aws_route53_zone.external.zone_id +} + +// Route53 DNS record for directing traffic to the service +resource "aws_route53_record" "external" { + provider = aws.core-vpc + + zone_id = data.aws_route53_zone.external.zone_id + name = "${var.networking[0].application}.${var.networking[0].business-unit}-${local.environment}.modernisation-platform.service.justice.gov.uk" + type = "A" + + alias { + name = aws_lb.chaps_lb.dns_name + zone_id = aws_lb.chaps_lb.zone_id + evaluate_target_health = true + } +}