mcpField
A
aws-cloudformation-ecs

aws-cloudformation-ecs

github.com/giuseppe-trisciuoglio云与 DevOps36565 次安装7 周前更新
代码仓库

关于 aws-cloudformation-ecs

面向使用 AWS CloudFormation 配置 Amazon ECS 的开发与运维人员,提供集群、任务定义和服务的基础设施模板模式,并涵盖部署、扩缩与监控。

主要功能

  1. 01ECS 集群与任务定义配置
  2. 02Fargate 和 EC2 启动类型
  3. 03ALB 集成与蓝绿部署
  4. 04服务自动扩缩
  5. 05Container Insights 监控

适用场景

  1. 01通过 CloudFormation 创建 ECS 集群
  2. 02部署带负载均衡器的 ECS 服务
  3. 03为 ECS 服务设置自动扩缩
  4. 04启用容器监控与跨栈引用

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/giuseppe-trisciuoglio/developer-kit --skill aws-cloudformation-ecs

安装后在 Claude Code 中输入/aws-cloudformation-ecs确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
constraints.md
examples.md
reference.md

详细介绍

AWS CloudFormation ECS

概述

提供适用于 ECS 集群、任务定义、服务、容器定义、自动扩缩、蓝绿部署、ALB 集成、监控和跨堆栈引用的 CloudFormation 模式。

适用场景

  • 使用 CloudFormation 创建或更新 ECS 集群
  • 配置 Fargate/EC2 启动类型和容量提供程序
  • 部署与 ALB/NLB 集成或采用蓝绿部署的服务
  • 为 ECS 服务实现自动扩缩
  • 使用 Container Insights 设置监控

操作说明

按照以下步骤使用 CloudFormation 创建 ECS 基础设施:

1. 定义 ECS 集群参数

指定启动类型、网络和容量设置:

Parameters:
  LaunchType:
    Type: String
    Default: FARGATE
    AllowedValues:
      - EC2
      - FARGATE
    Description: ECS launch type

  ContainerPort:
    Type: Number
    Default: 80
    Description: Container port

  TaskCPU:
    Type: String
    Default: 256
    AllowedValues:
      - 256
      - 512
      - 1024
      - 2048
      - 4096
    Description: Task CPU units

  TaskMemory:
    Type: String
    Default: 512
    AllowedValues:
      - 512
      - 1024
      - 2048
      - 3072
      - 4096
      - 5120
      - 6144
      - 7168
      - 8192
      - 9216
      - 10240
    Description: Task memory in MB
2. 创建 ECS 集群

定义集群基础设施:

Resources:
  ECSCluster:
    Type: AWS::ECS::Cluster
    Properties:
      ClusterName: !Sub "${AWS::StackName}-cluster"
      ClusterSettings:
        - Name: containerInsights
          Value: enabled
      CapacityProviders:
        - FARGATE
        - FARGATE_SPOT
      DefaultCapacityProviderStrategy:
        - CapacityProvider: FARGATE
          Weight: 1
        - CapacityProvider: FARGATE_SPOT
          Weight: 0
3. 创建任务定义

定义容器配置:

Resources:
  TaskDefinition:
    Type: AWS::ECS::TaskDefinition
    Properties:
      Family: !Sub "${AWS::StackName}-task"
      NetworkMode: awsvpc
      RequiresCompatibilities:
        - FARGATE
      Cpu: !Ref TaskCPU
      Memory: !Ref TaskMemory
      ExecutionRoleArn: !Ref ExecutionRole
      TaskRoleArn: !Ref TaskRole
      ContainerDefinitions:
        - Name: application
          Image: !Ref ImageUrl
          PortMappings:
            - ContainerPort: !Ref ContainerPort
              Protocol: tcp
          Environment:
            - Name: LOG_LEVEL
              Value: INFO
          LogConfiguration:
            LogDriver: awslogs
            Options:
              awslogs-group: !Ref LogGroup
              awslogs-region: !Ref AWS::Region
              awslogs-stream-prefix: ecs
          Memory: !Ref TaskMemory

继续操作前,请验证任务定义语法:

aws cloudformation validate-template --template-body file://template.yaml
4. 配置执行角色

设置用于任务执行的 IAM 角色:

Resources:
  ExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: ecs-tasks.amazonaws.com
            Action: sts:AssumeRole
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy

  TaskRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: ecs-tasks.amazonaws.com
            Action: sts:AssumeRole
      Policies:
        - PolicyName: S3Access
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - s3:GetObject
                Resource: !Sub "${DataBucket.Arn}/*"
5. 创建 ECS 服务

定义服务配置:

Resources:
  ECSService:
    Type: AWS::ECS::Service
    Properties:
      ServiceName: !Sub "${AWS::StackName}-service"
      Cluster: !Ref ECSCluster
      TaskDefinition: !Ref TaskDefinition
      DesiredCount: 2
      LaunchType: FARGATE
      NetworkConfiguration:
        AwsvpcConfiguration:
          Subnets:
            - !Ref PrivateSubnet1
            - !Ref PrivateSubnet2
          SecurityGroups:
            - !Ref SecurityGroup
          AssignPublicIp: DISABLED
      LoadBalancers:
        - TargetGroupArn: !Ref TargetGroup
          ContainerName: application
          ContainerPort: !Ref ContainerPort
6. 配置负载均衡器

设置 ALB 以分配流量:

Resources:
  LoadBalancer:
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
    Properties:
      Name: !Sub "${AWS::StackName}-alb"
      Scheme: internet-facing
      Type: application
      Subnets:
        - !Ref PublicSubnet1
        - !Ref PublicSubnet2
      SecurityGroups:
        - !Ref ALBSecurityGroup

  TargetGroup:
    Type: AWS::ElasticLoadBalancingV2::TargetGroup
    Properties:
      Port: 80
      Protocol: HTTP
      VpcId: !Ref VPC
      TargetType: ip

  Listener:
    Type: AWS::ElasticLoadBalancingV2::Listener
    Properties:
      DefaultActions:
        - TargetGroupArn: !Ref TargetGroup
          Type: forward
      LoadBalancerArn: !Ref LoadBalancer
      Port: 80
      Protocol: HTTP
7. 实现自动扩缩

配置 Application Auto Scaling:

Resources:
  ScalableTarget:
    Type: AWS::ApplicationAutoScaling::ScalableTarget
    Properties:
      MaxCapacity: 10
      MinCapacity: 1
      ResourceId: !Sub "service/${ECSCluster}/${ECSService}"
      ScalableDimension: ecs:service:DesiredCount
      ServiceNamespace: ecs

  ScalingPolicy:
    Type: AWS::ApplicationAutoScaling::ScalingPolicy
    Properties:
      PolicyName: !Sub "${AWS::StackName}-scaling"
      PolicyType: TargetTrackingScaling
      ScalingTargetId: !Ref ScalableTarget
      TargetTrackingScalingPolicyConfiguration:
        TargetValue: 70.0
        PredefinedMetricSpecification:
          PredefinedMetricType: ECSServiceAverageCPUUtilization
8. 配置监控

启用 CloudWatch Container Insights:

Resources:
  LogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: !Sub "/ecs/${AWS::StackName}"
      RetentionInDays: 7

部署前: 创建变更集以预览更改:

aws cloudformation create-change-set \
  --stack-name my-ecs-stack \
  --template-body file://template.yaml \
  --change-set-type CREATE
aws cloudformation execute-change-set --change-set-name <arn>

最佳实践

任务定义
  • 使用 Family 命名,以便跟踪版本并进行不可变部署
  • 通过引用外部配置,将任务定义控制在 1 KB 以下(CloudFormation 限制)
  • 在容器定义中配置 HealthCheck,以便进行 ECS 健康监控
  • 对于 Fargate,在任务级别同时设置 Cpu 和 Memory
服务部署
  • 启用 DeploymentCircuitBreaker,以便在失败时自动回滚
  • 将 HealthCheckGracePeriodSeconds 设置为与应用启动时间相符
  • 将 MinimumHealthyPercent(100)和 MaximumPercent(200)设为适当值,以实现零停机更新
  • 仅通过逻辑 ID 引用任务定义——ECS 会自动使用最新修订版本
网络
  • 对于 Fargate,始终使用 awsvpc 网络模式
  • 将任务放置在配有 NAT 网关以提供出站访问的私有子网中
  • 配置安全组,仅允许必需的端口(而非 0.0.0.0/0)
扩缩
  • 使用 Fargate Spot,并将按需容量基数设为 1,以优化成本
  • 在容量提供程序策略上设置 MaxHealthyDuration,以处理 Spot 中断
  • 在 CloudWatch 中监控 STEADY_STATE 故障,以发现任务启动问题

限制和警告

资源限制
  • 使用 CloudFormation 时,任务定义大小限制为 1 KB(大型配置请使用 ParameterStore/Secrets Manager)
  • Fargate 中每个任务定义最多包含 10 个容器
  • 必须为 Fargate 任务指定 CPU(256-4096 单位,按 1024 递增)
  • 必须分配内存(根据 CPU 而定,为 512-30720 MB)
操作限制
  • ENI 限制按子网计算——请确保每个可用区中的每个任务至少有 1 个 ENI
  • Fargate Spot 任务会提前 2 分钟收到中断通知——请实现优雅关闭信号(SIGTERM)
  • 服务更新需要新的任务定义修订版本——无法修改现有版本
  • 部署期间更新 DesiredCount 可能与自动扩缩策略冲突
CloudFormation 专属事项
  • 在堆栈之间传递 VPC ID、Subnet ID 和 Security Group ID 时,必须使用跨堆栈引用
  • 在同一模板中引用堆栈输出时,请使用 !GetAtt
  • 确保 IAM 角色 ARN 使用包含堆栈名称的 Fn::Sub,以提高可移植性

示例

最简 Fargate 服务
AWSTemplateFormatVersion: "2010-09-09"
Description: Minimal ECS Fargate service

Resources:
  Cluster:
    Type: AWS::ECS::Cluster
    Properties:
      ClusterName: !Sub "${AWS::StackName}-cluster"

  TaskDefinition:
    Type: AWS::ECS::TaskDefinition
    Properties:
      Family: !Sub "${AWS::StackName}-task"
      NetworkMode: awsvpc
      RequiresCompatibilities: [FARGATE]
      Cpu: 256
      Memory: 512
      ContainerDefinitions:
        - Name: app
          Image: nginx:latest
          PortMappings:
            - ContainerPort: 80

  Service:
    Type: AWS::ECS::Service
    Properties:
      Cluster: !Ref Cluster
      ServiceName: !Sub "${AWS::StackName}-svc"
      TaskDefinition: !Ref TaskDefinition
      DesiredCount: 2
      LaunchType: FARGATE
      DeploymentCircuitBreaker:
        Enable: true
        Rollback: true
集成 ALB 的 ECS
Resources:
  Service:
    Type: AWS::ECS::Service
    Properties:
      Cluster: !Ref ECSCluster
      TaskDefinition: !Ref TaskDefinition
      DesiredCount: 2
      LaunchType: FARGATE
      HealthCheckGracePeriodSeconds: 30
      NetworkConfiguration:
        AwsvpcConfiguration:
          Subnets: [!Ref PrivateSubnet1, !Ref PrivateSubnet2]
          SecurityGroups: [!Ref TaskSecurityGroup]
      LoadBalancers:
        - TargetGroupArn: !Ref TargetGroup
          ContainerName: app
          ContainerPort: 8080

  TargetGroup:
    Type: AWS::ElasticLoadBalancingV2::TargetGroup
    Properties:
      Port: 80
      Protocol: HTTP
      VpcId: !Ref VPC
      TargetType: ip
      HealthCheckPath: /health

参考资料

如需详细的实施指导,请参阅:

  • constraints.md - 资源限制(任务定义大小、容器限制、内存限制、CPU 限制)、运行约束(服务更新、ENI 限制、任务启动时间、扩缩容延迟)、安全约束(IAM 角色、网络模式、安全组、密钥轮换)、成本考量(Fargate 定价、数据传输、ECR 存储、监控)、部署约束(蓝绿部署要求、CodeDeploy 集成、回滚、任务漂移)以及可用性约束(Fargate Spot、多可用区、运行状况检查、服务发现)

相关资源

评论

支持 Markdown