求助:Terraform配置AWS Service Connect与ECS(Fargate)失效,求可行方案
可运行的AWS Service Connect + ECS Fargate Terraform配置方案
完整配置代码
1. 基础网络资源(VPC、安全组)
# VPC resource "aws_vpc" "ecs_vpc" { cidr_block = "10.0.0.0/16" tags = { Name = "ecs-service-connect-vpc" } } # 公有子网(Fargate需至少2个可用区子网) resource "aws_subnet" "ecs_public_subnet_1" { vpc_id = aws_vpc.ecs_vpc.id cidr_block = "10.0.1.0/24" availability_zone = "us-east-1a" tags = { Name = "ecs-public-subnet-1" } } resource "aws_subnet" "ecs_public_subnet_2" { vpc_id = aws_vpc.ecs_vpc.id cidr_block = "10.0.2.0/24" availability_zone = "us-east-1b" tags = { Name = "ecs-public-subnet-2" } } # 互联网网关与路由配置 resource "aws_internet_gateway" "ecs_igw" { vpc_id = aws_vpc.ecs_vpc.id tags = { Name = "ecs-igw" } } resource "aws_route_table" "ecs_public_route_table" { vpc_id = aws_vpc.ecs_vpc.id route { cidr_block = "0.0.0.0/0" gateway_id = aws_internet_gateway.ecs_igw.id } tags = { Name = "ecs-public-route-table" } } resource "aws_route_table_association" "public_subnet_1_assoc" { subnet_id = aws_subnet.ecs_public_subnet_1.id route_table_id = aws_route_table.ecs_public_route_table.id } resource "aws_route_table_association" "public_subnet_2_assoc" { subnet_id = aws_subnet.ecs_public_subnet_2.id route_table_id = aws_route_table.ecs_public_route_table.id } # ECS服务安全组:允许VPC内流量互通 resource "aws_security_group" "ecs_service_sg" { name = "ecs-service-connect-sg" description = "Allow inbound traffic for ECS services" vpc_id = aws_vpc.ecs_vpc.id ingress { from_port = 0 to_port = 65535 protocol = "tcp" cidr_blocks = [aws_vpc.ecs_vpc.cidr_block] } egress { from_port = 0 to_port = 65535 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } tags = { Name = "ecs-service-connect-sg" } }
2. ECS集群
resource "aws_ecs_cluster" "my_cluster" { name = "service-connect-cluster" capacity_providers = ["FARGATE", "FARGATE_SPOT"] default_capacity_provider_strategy { capacity_provider = "FARGATE" weight = 1 base = 1 } }
3. CloudMap私有DNS命名空间
resource "aws_service_discovery_private_dns_namespace" "my-cloudmap-namespace" { name = "service.local" description = "Private DNS namespace for Service Connect" vpc_id = aws_vpc.ecs_vpc.id }
4. ECS任务定义
resource "aws_ecs_task_definition" "my_service_task" { family = "my-service-task" network_mode = "awsvpc" # Fargate强制要求 requires_compatibilities = ["FARGATE"] cpu = "256" memory = "512" execution_role_arn = aws_iam_role.ecs_execution_role.arn task_role_arn = aws_iam_role.ecs_task_role.arn container_definitions = jsonencode([ { name = "my-service-container" image = "nginx:alpine" # 替换为你的业务镜像 cpu = 0 essential = true portMappings = [ { name = "my-service" containerPort = 4002 hostPort = 4002 protocol = "tcp" appProtocol = "http" } ] } ]) } # ECS执行角色 resource "aws_iam_role" "ecs_execution_role" { name = "ecs-execution-role" assume_role_policy = jsonencode({ Version = "2012-10-17" Statement = [ { Action = "sts:AssumeRole" Effect = "Allow" Principal = { Service = "ecs-tasks.amazonaws.com" } } ] }) } resource "aws_iam_role_policy_attachment" "ecs_execution_role_policy" { role = aws_iam_role.ecs_execution_role.name policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy" } # ECS任务角色 resource "aws_iam_role" "ecs_task_role" { name = "ecs-task-role" assume_role_policy = jsonencode({ Version = "2012-10-17" Statement = [ { Action = "sts:AssumeRole" Effect = "Allow" Principal = { Service = "ecs-tasks.amazonaws.com" } } ] }) }
5. ECS服务(配置Service Connect)
resource "aws_ecs_service" "my_service" { name = "my-service" cluster = aws_ecs_cluster.my_cluster.id task_definition = aws_ecs_task_definition.my_service_task.arn desired_count = 1 launch_type = "FARGATE" network_configuration { subnets = [aws_subnet.ecs_public_subnet_1.id, aws_subnet.ecs_public_subnet_2.id] security_groups = [aws_security_group.ecs_service_sg.id] assign_public_ip = true # 无需公网访问可设为false } service_connect_configuration { enabled = true namespace = aws_service_discovery_private_dns_namespace.my-cloudmap-namespace.arn # 健康检查配置(可选) discovery_health_check { enabled = true type = "HTTP" resource_path = "/" port = 4002 } service { discovery_name = "my-service" port_name = "my-service" # 对应容器portMappings的name client_alias { dns_name = "my-service" port = 4002 # 注意:此处为数字类型,不能用字符串 } } } depends_on = [aws_iam_role_policy_attachment.ecs_execution_role_policy] }
原有配置错误修正说明
- Port类型错误:
client_alias中的port必须是数字,不能用字符串(原配置写的是"4002",需改为4002) - 命名空间类型:Service Connect推荐使用私有DNS命名空间,HTTP命名空间仅支持有限的服务发现功能,无法满足完整的Service Connect通信需求
- 网络模式:Fargate任务必须使用
awsvpc网络模式,这是Service Connect代理正常工作的前提 - 安全组限制:必须允许VPC内部流量互通,否则Service Connect代理无法在服务间建立连接
访问验证方法
若要从其他ECS服务访问该服务,需在目标服务的service_connect_configuration中添加如下配置:
service { discovery_name = "my-service" port_name = "my-service" }
之后在目标服务的容器内执行curl http://my-service:4002即可访问到服务。
内容的提问来源于stack exchange,提问作者Jaydeep Dave
相关产品推荐
相关产品推荐

