provider "aws" { region = local.region } locals { name = "ecsdemo-frontend" region = "us-east-2" container_image = "public.ecr.aws/aws-containers/ecsdemo-frontend" container_port = 3000 # Container port is specific to this app example container_name = "ecsdemo-frontend" tags = { Blueprint = local.name GithubRepo = "github.com/aws-ia/ecs-blueprints" } } ################################################################################ # ECS Blueprint ################################################################################ module "service_alb" { source = "terraform-aws-modules/alb/aws" version = "~> 8.3" name = "${local.name}-alb" load_balancer_type = "application" vpc_id = data.aws_vpc.vpc.id subnets = data.aws_subnets.public.ids security_group_rules = { ingress_all_http = { type = "ingress" from_port = 80 to_port = 80 protocol = "tcp" description = "HTTP web traffic" cidr_blocks = ["0.0.0.0/0"] } egress_all = { type = "egress" from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = [for s in data.aws_subnet.private_cidr : s.cidr_block] } } http_tcp_listeners = [ { port = "80" protocol = "HTTP" target_group_index = 0 }, ] target_groups = [ { name = "${local.name}-tg" backend_protocol = "HTTP" backend_port = local.container_port target_type = "ip" health_check = { path = "/" port = local.container_port matcher = "200-299" } }, ] tags = local.tags } resource "aws_service_discovery_service" "this" { name = local.name dns_config { namespace_id = data.aws_service_discovery_dns_namespace.this.id dns_records { ttl = 10 type = "A" } routing_policy = "MULTIVALUE" } health_check_custom_config { failure_threshold = 1 } } module "ecs_service_definition" { source = "terraform-aws-modules/ecs/aws//modules/service" version = "~> 5.0" name = local.name desired_count = 3 cluster_arn = data.aws_ecs_cluster.core_infra.arn enable_autoscaling = false subnet_ids = data.aws_subnets.private.ids security_group_rules = { ingress_alb_service = { type = "ingress" from_port = local.container_port to_port = local.container_port protocol = "tcp" description = "Service port" source_security_group_id = module.service_alb.security_group_id } egress_all = { type = "egress" from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } } load_balancer = [{ container_name = local.container_name container_port = local.container_port target_group_arn = element(module.service_alb.target_group_arns, 0) }] service_registries = { registry_arn = aws_service_discovery_service.this.arn } # service_connect_configuration = { # enabled = false # } # Task Definition create_iam_role = false task_exec_iam_role_arn = one(data.aws_iam_roles.ecs_core_infra_exec_role.arns) enable_execute_command = true container_definitions = { main_container = { name = local.container_name image = local.container_image readonly_root_filesystem = false port_mappings = [{ protocol : "tcp", containerPort : local.container_port hostPort : local.container_port }], "environment" = [{ "name" = "NODEJS_URL", "value" = "http://ecsdemo-backend.default.core-infra.local:3000" }] } } ignore_task_definition_changes = false tags = local.tags } ################################################################################ # Supporting Resources ################################################################################ data "aws_vpc" "vpc" { filter { name = "tag:Name" values = ["core-infra"] } } data "aws_subnets" "public" { filter { name = "tag:Name" values = ["core-infra-public-*"] } } data "aws_subnets" "private" { filter { name = "tag:Name" values = ["core-infra-private-*"] } } data "aws_subnet" "private_cidr" { for_each = toset(data.aws_subnets.private.ids) id = each.value } data "aws_ecs_cluster" "core_infra" { cluster_name = "core-infra" } data "aws_iam_roles" "ecs_core_infra_exec_role" { name_regex = "core-infra-*" } data "aws_service_discovery_dns_namespace" "this" { name = "default.${data.aws_ecs_cluster.core_infra.cluster_name}.local" type = "DNS_PRIVATE" }