You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助: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]
}

原有配置错误修正说明

  1. Port类型错误:client_alias中的port必须是数字,不能用字符串(原配置写的是"4002",需改为4002)
  2. 命名空间类型:Service Connect推荐使用私有DNS命名空间,HTTP命名空间仅支持有限的服务发现功能,无法满足完整的Service Connect通信需求
  3. 网络模式:Fargate任务必须使用awsvpc网络模式,这是Service Connect代理正常工作的前提
  4. 安全组限制:必须允许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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 04:25:39