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

如何将CloudFormation模板中的ECS集群从Fargate改为EC2启动类型?

将ECS启动类型从Fargate改为EC2的CloudFormation模板修改方案

我拥有一个可创建Fargate类型ECS集群、服务及其他必要资源的CloudFormation模板,现在需要将ECS的启动类型从Fargate修改为EC2。由于该CloudFormation模板关联了另一个栈,无法更换其他模板,恳请告知需对模板做出哪些修改。


1. 修改任务定义(TaskDefinition)

  • 移除RequiresCompatibilities中的FARGATE,替换为EC2(或直接删除该字段,EC2是默认兼容项)
  • 将Memory和Cpu改为字符串格式的软限制(Fargate用固定规格,EC2支持弹性资源分配)
  • 移除PortMappings中的HostPort:awsvpc网络模式下该配置会被忽略;若使用bridge模式则需保留并确保与容器端口匹配
  • 保留NetworkMode: awsvpc(EC2支持该模式,推荐使用),也可根据需求改为bridge

修改后的TaskDefinition示例:

TaskDefinition:
  Type: AWS::ECS::TaskDefinition
  Properties: 
    Memory: "1024"
    Cpu: "512"
    NetworkMode: awsvpc
    RequiresCompatibilities:
      - 'EC2'
    TaskRoleArn: !Ref ExecutionRole
    ExecutionRoleArn: !Ref ExecutionRole
    ContainerDefinitions:
      - Name: !Join ['-', [!Ref Stage, !Ref 'AWS::AccountId', 'Container']]
        Image: !Ref ImageURI
        PortMappings:
          - ContainerPort: !Ref ContainerPort

2. 修改ECS服务(ECSService)

  • 将LaunchType从FARGATE改为EC2
  • 保留NetworkConfiguration(awsvpc模式下需要),若使用bridge模式则可删除该配置
  • 可选:添加DeploymentConfiguration自定义EC2模式下的部署策略(如最小健康百分比、最大百分比)

修改后的ECSService示例:

ECSService:
  Type: AWS::ECS::Service
  DependsOn: LoadBalancerListener
  Properties:
    ServiceName: !Join ['-', [!Ref Stage, !Ref 'AWS::AccountId', 'ECSService']]
    Cluster: !Ref Cluster
    TaskDefinition: !Ref TaskDefinition
    DesiredCount: 2
    LaunchType: EC2
    NetworkConfiguration: 
      AwsvpcConfiguration:
        AssignPublicIp: ENABLED
        Subnets:
          - !Ref SubnetA
          - !Ref SubnetB
        SecurityGroups:
          - !Ref ContainerSecurityGroup
    LoadBalancers:
      - ContainerName: !Join ['-', [!Ref Stage, !Ref 'AWS::AccountId', 'Container']]
        ContainerPort: !Ref ContainerPort
        TargetGroupArn: !Ref TargetGroup

3. 新增EC2实例管理资源(核心必填项)

EC2模式需要手动管理容器实例,需在模板中添加以下资源:

3.1 ECS实例IAM角色

用于EC2实例与ECS集群通信:

ECSInstanceRole:
  Type: AWS::IAM::Role
  Properties:
    RoleName: !Join ['-', [!Ref Stage, !Ref 'AWS::AccountId', 'ECSInstanceRole']]
    AssumeRolePolicyDocument:
      Statement:
        - Effect: Allow
          Principal:
            Service: ec2.amazonaws.com
          Action: 'sts:AssumeRole'
    ManagedPolicyArns:
      - 'arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role'

3.2 实例配置文件

将IAM角色绑定到EC2实例:

ECSInstanceProfile:
  Type: AWS::IAM::InstanceProfile
  Properties:
    InstanceProfileName: !Join ['-', [!Ref Stage, !Ref 'AWS::AccountId', 'ECSInstanceProfile']]
    Roles:
      - !Ref ECSInstanceRole

3.3 EC2实例安全组

允许实例与ECS集群、负载均衡器通信:

ECSInstanceSecurityGroup:
  Type: AWS::EC2::SecurityGroup
  Properties:
    GroupDescription: !Join ['-', [!Ref Stage, !Ref 'AWS::AccountId', 'ECSInstanceSecurityGroup']]
    VpcId: !Ref VPC
    SecurityGroupIngress:
      - IpProtocol: tcp
        FromPort: 22
        ToPort: 22
        CidrIp: 0.0.0.0/0 # 可选,用于SSH访问,按需调整
      - IpProtocol: tcp
        FromPort: !Ref ContainerPort
        ToPort: !Ref ContainerPort
        SourceSecurityGroupId: !Ref LoadBalancerSecurityGroup
      - IpProtocol: tcp
        FromPort: 51678
        ToPort: 51678
        CidrIp: 0.0.0.0/0 # ECS代理与集群通信端口
    SecurityGroupEgress:
      - IpProtocol: -1
        CidrIp: 0.0.0.0/0 # 允许实例出站访问

3.4 Auto Scaling Group与启动模板

管理EC2实例的生命周期,并将实例注册到ECS集群:

ECSAutoScalingGroup:
  Type: AWS::AutoScaling::AutoScalingGroup
  Properties:
    AutoScalingGroupName: !Join ['-', [!Ref Stage, !Ref 'AWS::AccountId', 'ECSAutoScalingGroup']]
    MinSize: 1
    MaxSize: 3
    DesiredCapacity: 2
    VPCZoneIdentifier:
      - !Ref SubnetA
      - !Ref SubnetB
    LaunchTemplate:
      LaunchTemplateId: !Ref ECSLaunchTemplate
      Version: !GetAtt ECSLaunchTemplate.LatestVersionNumber
  CreationPolicy:
    ResourceSignal:
      Count: 2
      Timeout: PT15M

ECSLaunchTemplate:
  Type: AWS::EC2::LaunchTemplate
  Properties:
    LaunchTemplateName: !Join ['-', [!Ref Stage, !Ref 'AWS::AccountId', 'ECSLaunchTemplate']]
    LaunchTemplateData:
      ImageId: ami-0c55b159cbfafe1f0 # 替换为对应区域的ECS优化AMI(如Amazon Linux 2 ECS AMI)
      InstanceType: t2.micro # 按需选择实例类型
      IamInstanceProfile:
        Name: !Ref ECSInstanceProfile
      SecurityGroupIds:
        - !Ref ECSInstanceSecurityGroup
      UserData:
        Fn::Base64: !Sub |
          #!/bin/bash
          echo ECS_CLUSTER=${Cluster} >> /etc/ecs/ecs.config
          yum install -y aws-cfn-bootstrap
          /opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackName} --resource ECSAutoScalingGroup --region ${AWS::Region}

4. 调整目标组(TargetGroup)

  • 若使用awsvpc模式,保留TargetType: ip
  • 若使用bridge模式,将TargetType改为instance,并将Port设置为容器映射的主机端口(与容器端口一致即可)

修改后的TargetGroup示例(awsvpc模式):

TargetGroup:
  Type: AWS::ElasticLoadBalancingV2::TargetGroup
  Properties:
    Name: !Join ['-', [!Ref Stage, !Ref 'AWS::AccountId', 'TargetGroup']]
    Port: !Ref ContainerPort
    Protocol: HTTP
    TargetType: ip
    VpcId: !Ref VPC

内容的提问来源于stack exchange,提问作者Rehan Shakeel

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 17:45:28