如何将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
相关产品推荐
相关产品推荐

