From bf94603e7210fff2a660f1be29e7242ff7dd2e3d Mon Sep 17 00:00:00 2001 From: "eve n.u" Date: Thu, 25 Jan 2024 13:31:21 -0800 Subject: [PATCH] migrate ecs service to module --- infrastructure/terraform/aws/main.tf | 34 ++++--- .../terraform/aws/modules/v7-cluster/ecs.tf | 98 ------------------- .../terraform/aws/modules/v7-cluster/main.tf | 6 +- .../aws/modules/v7-cluster/outputs.tf | 24 +++++ .../aws/modules/v7-cluster/variables.tf | 50 +++++----- 5 files changed, 77 insertions(+), 135 deletions(-) diff --git a/infrastructure/terraform/aws/main.tf b/infrastructure/terraform/aws/main.tf index d1811ec37..313b9c909 100644 --- a/infrastructure/terraform/aws/main.tf +++ b/infrastructure/terraform/aws/main.tf @@ -24,19 +24,31 @@ module "cluster" { environment = var.environment region = var.region + container_ingress_port = 3000 + availability_zones = ["us-east-1a", "us-east-1c"] +} + +module "service_core" { + source = "./modules/ecs-service" + + service_name = "core" + cluster_info = module.cluster.cluster_info - core_configuration = { + + repository_url = module.cluster.ecr_repository_url + + configuration = { container_port = 3000 - environment = { - API_KEY = "undefined" - JWT_SECRET = "undefined" - MAILGUN_SMTP_USERNAME = "undefined" - NEXT_PUBLIC_PUBPUB_URL = "undefined" - NEXT_PUBLIC_SUPABASE_URL = "undefined" - SENTRY_AUTH_TOKEN = "undefined" - SUPABASE_SERVICE_ROLE_KEY = "undefined" - SUPABASE_WEBHOOKS_API_KEY = "undefined" - } + environment = [ + {name = "API_KEY", value = "undefined"}, + {name = "JWT_SECRET", value = "undefined"}, + {name = "MAILGUN_SMTP_USERNAME", value = "undefined"}, + {name = "NEXT_PUBLIC_PUBPUB_URL", value = "undefined"}, + {name = "NEXT_PUBLIC_SUPABASE_URL", value = "undefined"}, + {name = "SENTRY_AUTH_TOKEN", value = "undefined"}, + {name = "SUPABASE_SERVICE_ROLE_KEY", value = "undefined"}, + {name = "SUPABASE_WEBHOOKS_API_KEY", value = "undefined"}, + ] } } diff --git a/infrastructure/terraform/aws/modules/v7-cluster/ecs.tf b/infrastructure/terraform/aws/modules/v7-cluster/ecs.tf index 1bdf14c52..69426ef79 100644 --- a/infrastructure/terraform/aws/modules/v7-cluster/ecs.tf +++ b/infrastructure/terraform/aws/modules/v7-cluster/ecs.tf @@ -1,11 +1,3 @@ -locals { - db_user = aws_db_instance.core_postgres.username - db_pw = random_password.rds_db_password.result - db_name = aws_db_instance.core_postgres.db_name - db_host = aws_db_instance.core_postgres.address - db_sslmode = "require" -} - module "ecs_cluster" { source = "terraform-aws-modules/ecs/aws//modules/cluster" @@ -26,93 +18,3 @@ module "ecs_cluster" { } } -module "ecs_service_core" { - source = "terraform-aws-modules/ecs/aws//modules/service" - name = "${var.name}-core" - - cluster_arn = module.ecs_cluster.arn - enable_execute_command = true - - cpu = 512 - memory = 1024 - desired_count = 1 - # execution_role_arn = aws_iam_role.ecs_task_execution_role.arn - # task_role_arn = aws_iam_role.ecs_task_role.arn - - # Container definition(s) - container_definitions = { - - core = { - essential = true - image = "${aws_ecr_repository.pubpub_v7.repository_url}:latest" - port_mappings = [{ - protocol = "tcp" - containerPort = var.core_configuration.container_port - hostPort = var.core_configuration.container_port - }] - - environment = [ - # watch out for issues with a string-wrapped number in this context - { name = "PORT" - value = "${var.core_configuration.container_port}" - }, - { name = "DATABASE_URL" - value = "postgresql://${ - local.db_user}:${local.db_pw - }@${ - local.db_host - }:5432/${local.db_name}?sslmode=${local.db_sslmode}" - }, - { name = "API_KEY" , value = var.core_configuration.environment.API_KEY }, - # { name = ASSETS_REGION , value = var.core_configuration.environment.ASSETS_REGION - # { name = ASSETS_UPLOAD_KEY , value = var.core_configuration.environment.ASSETS_UPLOAD_KEY - # { name = ASSETS_UPLOAD_SECRET_KEY , value = var.core_configuration.environment.ASSETS_UPLOAD_SECRET_KEY - { name = "JWT_SECRET" , value = var.core_configuration.environment.JWT_SECRET}, - { name = "MAILGUN_SMTP_USERNAME" , value = var.core_configuration.environment.MAILGUN_SMTP_USERNAME}, - { name = "NEXT_PUBLIC_PUBPUB_URL" , value = var.core_configuration.environment.NEXT_PUBLIC_PUBPUB_URL}, - { name = "NEXT_PUBLIC_SUPABASE_URL" , value = var.core_configuration.environment.NEXT_PUBLIC_SUPABASE_URL}, - { name = "SENTRY_AUTH_TOKEN" , value = var.core_configuration.environment.SENTRY_AUTH_TOKEN}, - { name = "SUPABASE_SERVICE_ROLE_KEY" , value = var.core_configuration.environment.SUPABASE_SERVICE_ROLE_KEY}, - { name = "SUPABASE_WEBHOOKS_API_KEY" , value = var.core_configuration.environment.SUPABASE_WEBHOOKS_API_KEY}, - ] - - - # Example image used requires access to write to root filesystem - readonly_root_filesystem = false - - log_configuration = { - logDriver = "awslogs", - options = { - awslogs-group = aws_cloudwatch_log_group.ecs.name, - awslogs-region = var.region, - awslogs-stream-prefix = "ecs" - } - } - # memory_reservation = 100 - } - } - - - load_balancer = { - service = { - target_group_arn = aws_lb_target_group.main.arn - container_name = "core" # TODO: validate - container_port = var.core_configuration.container_port - } - } - - subnet_ids = aws_subnet.private.*.id - security_group_ids = [aws_security_group.ecs_tasks.id] - assign_public_ip = false - - tags = { - Environment = "${var.name}-${var.environment}" - Project = "Pubpub-v7" - } - - # this lifecycle property allows us to update the version of the container image without terraform clobbering it later - # changing the container image creates a "revision" of the task definition - # lifecycle { - # ignore_changes = [services.core.container_definitions.core.image] - # } -} diff --git a/infrastructure/terraform/aws/modules/v7-cluster/main.tf b/infrastructure/terraform/aws/modules/v7-cluster/main.tf index 73cf58d9e..302547a61 100644 --- a/infrastructure/terraform/aws/modules/v7-cluster/main.tf +++ b/infrastructure/terraform/aws/modules/v7-cluster/main.tf @@ -115,8 +115,8 @@ resource "aws_security_group" "ecs_tasks" { ingress { protocol = "tcp" - from_port = var.core_configuration.container_port - to_port = var.core_configuration.container_port + from_port = var.container_ingress_port + to_port = var.container_ingress_port cidr_blocks = ["0.0.0.0/0"] ipv6_cidr_blocks = ["::/0"] } @@ -130,6 +130,7 @@ resource "aws_security_group" "ecs_tasks" { } } + # load balancer resource "aws_lb" "main" { name = "${var.name}-lb-${var.environment}" @@ -169,6 +170,7 @@ resource "aws_lb_listener" "http" { } } + # logging resource "aws_cloudwatch_log_group" "ecs" { diff --git a/infrastructure/terraform/aws/modules/v7-cluster/outputs.tf b/infrastructure/terraform/aws/modules/v7-cluster/outputs.tf index 6ea41c122..5d5b18aea 100644 --- a/infrastructure/terraform/aws/modules/v7-cluster/outputs.tf +++ b/infrastructure/terraform/aws/modules/v7-cluster/outputs.tf @@ -1,3 +1,10 @@ +locals { + db_user = aws_db_instance.core_postgres.username + db_name = aws_db_instance.core_postgres.db_name + db_host = aws_db_instance.core_postgres.address + db_sslmode = "require" +} + output "ecr_repository_url" { value = aws_ecr_repository.pubpub_v7.repository_url } @@ -5,3 +12,20 @@ output "ecr_repository_url" { output "rds_db_password_id" { value = aws_secretsmanager_secret.rds_db_password.id } + +output "rds_connection_string_sans_password" { + value = "postgresql://${local.db_user}@${local.db_host}:5432/${local.db_name}?sslmode=${local.db_sslmode}" +} + +output "cluster_info" { + value = { + region = var.region + name = var.name + environment = var.environment + cluster_arn = module.ecs_cluster.arn + private_subnet_ids = aws_subnet.private.*.id + container_security_group_ids = [aws_security_group.ecs_tasks.id] + cloudwatch_log_group_name = aws_cloudwatch_log_group.ecs.name + lb_target_group_arn = aws_lb_target_group.main.arn + } +} diff --git a/infrastructure/terraform/aws/modules/v7-cluster/variables.tf b/infrastructure/terraform/aws/modules/v7-cluster/variables.tf index 860bb11e5..4045e3b8a 100644 --- a/infrastructure/terraform/aws/modules/v7-cluster/variables.tf +++ b/infrastructure/terraform/aws/modules/v7-cluster/variables.tf @@ -26,33 +26,35 @@ variable "availability_zones" { description = "a list of availability zones" } +# variable "container_port" { +# description = "The port the containers are listening on" +# default = 5050 +# } +# +# variable "container_environment" { +# description = "Environment variables for the containers" +# default = [] +# } +# +# variable "health_check_path" { +# description = "The path for the health check" +# default = "/v1/debug/health" +# } +# +# variable "hosted_zone_id" { +# description = "The ID of the hosted zone for the domain" +# } +# +# variable "subdomain" { +# description = "Prefix to domain name of hosted zone above, so serve app from" +# } + variable "region" { description = "Region for all resources (MUST agree with provider config)" default = "us-east-1" } -variable "core_configuration" { - description = "Container configurations for `core`" - sensitive = true - - type = object({ - container_port = number - - # This might become too cumbersome, but for now it is nice to - # make the surface area clear everywhere - environment = object({ - # DATABASE_URL = string - API_KEY = string - # ASSETS_REGION = string - # ASSETS_UPLOAD_KEY = string - # ASSETS_UPLOAD_SECRET_KEY = string - JWT_SECRET = string - MAILGUN_SMTP_USERNAME = string - NEXT_PUBLIC_PUBPUB_URL = string - NEXT_PUBLIC_SUPABASE_URL = string - SENTRY_AUTH_TOKEN = string - SUPABASE_SERVICE_ROLE_KEY = string - SUPABASE_WEBHOOKS_API_KEY = string - }) - }) +variable "container_ingress_port" { + description = "port to allow traffic in private security group" + type = number }