aws-cloudformation-ecs
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseAWS CloudFormation ECS
AWS CloudFormation ECS
Create production-ready container infrastructure using AWS CloudFormation templates. This skill covers ECS clusters, services, task definitions, container configurations, scaling, service discovery, load balancing, and blue/green deployments with CodeDeploy.
使用AWS CloudFormation模板创建可用于生产环境的容器基础设施。本内容涵盖ECS集群、服务、任务定义、容器配置、扩缩容、服务发现、负载均衡,以及结合CodeDeploy的蓝绿部署。
When to Use
适用场景
Use this skill when:
- Creating new ECS clusters with CloudFormation
- Defining task definitions for container workloads
- Configuring ECS services with deployment strategies
- Integrating ECS with Application Load Balancer
- Implementing auto scaling for ECS services
- Configuring service discovery with Cloud Map
- Implementing blue/green deployments with CodeDeploy
- Organizing templates with Parameters, Outputs, Mappings, Conditions
- Implementing cross-stack references with export/import
- Using Transform for macro and reuse
在以下场景中使用本内容:
- 使用CloudFormation创建新的ECS集群
- 为容器工作负载定义任务定义
- 为ECS服务配置部署策略
- 将ECS与应用负载均衡器(Application Load Balancer)集成
- 为ECS服务实现自动扩缩容
- 结合Cloud Map配置服务发现
- 结合CodeDeploy实现蓝绿部署
- 使用Parameters、Outputs、Mappings、Conditions组织模板
- 通过导出/导入实现跨栈引用
- 使用Transform实现宏与复用
Template Structure
模板结构
Base Template with Standard Format
标准格式的基础模板
yaml
AWSTemplateFormatVersion: 2010-09-09
Description: ECS cluster with service and load balancer
Metadata:
AWS::CloudFormation::Interface:
ParameterGroups:
- Label:
default: Cluster Configuration
Parameters:
- ClusterName
- InstanceType
- DesiredCapacity
- Label:
default: Container Configuration
Parameters:
- ContainerName
- ContainerImage
- ContainerPort
Parameters:
ClusterName:
Type: String
Default: production-ecs-cluster
Description: Name of the ECS cluster
InstanceType:
Type: String
Default: t3.medium
AllowedValues:
- t3.small
- t3.medium
- t3.large
- m5.large
DesiredCapacity:
Type: Number
Default: 2
MinValue: 1
MaxValue: 20
Description: Initial number of EC2 instances
ContainerName:
Type: String
Default: web-app
Description: Name of the container
ContainerImage:
Type: String
Default: nginx:latest
Description: Docker image for the container
ContainerPort:
Type: Number
Default: 80
Description: Port the container listens on
Mappings:
EnvironmentConfig:
dev:
InstanceType: t3.small
DesiredCapacity: 1
ContainerMemoryHardLimit: 256
ContainerMemorySoftLimit: 128
staging:
InstanceType: t3.medium
DesiredCapacity: 2
ContainerMemoryHardLimit: 512
ContainerMemorySoftLimit: 256
production:
InstanceType: t3.large
DesiredCapacity: 3
ContainerMemoryHardLimit: 1024
ContainerMemorySoftLimit: 512
Conditions:
IsProduction: !Equals [!Ref Environment, production]
UseSpotInstances: !Equals [!Ref SpotInstances, true]
Transform:
- AWS::Serverless-2016-10-31
Resources:
# ECS Cluster
ECSCluster:
Type: AWS::ECS::Cluster
Properties:
ClusterName: !Ref ClusterName
ClusterSettings:
- Name: containerInsights
Value: enabled
# EC2 Instance Configuration
InstanceCapacity:
Type: AWS::AutoScaling::LaunchConfiguration
Properties:
ImageId: !Ref AmiId
InstanceType: !Ref InstanceType
IamInstanceProfile: !Ref EcsInstanceProfile
SecurityGroups:
- !Ref EcsSecurityGroup
UserData:
Fn::Base64: !Sub |
#!/bin/bash
echo "ECS_CLUSTER=${ECSCluster.Name}" >> /etc/ecs/ecs.config
echo "ECS_BACKEND_HOST=${ECSBackendHost}" >> /etc/ecs/ecs.config
BlockDeviceMappings:
- DeviceName: /dev/xvda
Ebs:
VolumeSize: 30
VolumeType: gp3
AutoScalingGroup:
Type: AWS::AutoScaling::AutoScalingGroup
Properties:
AutoScalingGroupName: !Sub "${ClusterName}-asg"
LaunchConfigurationName: !Ref InstanceCapacity
MinSize: !Ref DesiredCapacity
MaxSize: !Ref MaxCapacity
DesiredCapacity: !Ref DesiredCapacity
VPCZoneIdentifier: !Ref SubnetIds
Tags:
- Key: Name
Value: !Sub "${ClusterName}-instance"
PropagateAtLaunch: true
- Key: Environment
Value: !Ref Environment
PropagateAtLaunch: true
Outputs:
ClusterName:
Description: Name of the ECS cluster
Value: !Ref ECSCluster
Export:
Name: !Sub "${AWS::StackName}-ClusterName"
ClusterArn:
Description: ARN of the ECS cluster
Value: !GetAtt ECSCluster.Arn
Export:
Name: !Sub "${AWS::StackName}-ClusterArn"yaml
AWSTemplateFormatVersion: 2010-09-09
Description: ECS cluster with service and load balancer
Metadata:
AWS::CloudFormation::Interface:
ParameterGroups:
- Label:
default: Cluster Configuration
Parameters:
- ClusterName
- InstanceType
- DesiredCapacity
- Label:
default: Container Configuration
Parameters:
- ContainerName
- ContainerImage
- ContainerPort
Parameters:
ClusterName:
Type: String
Default: production-ecs-cluster
Description: Name of the ECS cluster
InstanceType:
Type: String
Default: t3.medium
AllowedValues:
- t3.small
- t3.medium
- t3.large
- m5.large
DesiredCapacity:
Type: Number
Default: 2
MinValue: 1
MaxValue: 20
Description: Initial number of EC2 instances
ContainerName:
Type: String
Default: web-app
Description: Name of the container
ContainerImage:
Type: String
Default: nginx:latest
Description: Docker image for the container
ContainerPort:
Type: Number
Default: 80
Description: Port the container listens on
Mappings:
EnvironmentConfig:
dev:
InstanceType: t3.small
DesiredCapacity: 1
ContainerMemoryHardLimit: 256
ContainerMemorySoftLimit: 128
staging:
InstanceType: t3.medium
DesiredCapacity: 2
ContainerMemoryHardLimit: 512
ContainerMemorySoftLimit: 256
production:
InstanceType: t3.large
DesiredCapacity: 3
ContainerMemoryHardLimit: 1024
ContainerMemorySoftLimit: 512
Conditions:
IsProduction: !Equals [!Ref Environment, production]
UseSpotInstances: !Equals [!Ref SpotInstances, true]
Transform:
- AWS::Serverless-2016-10-31
Resources:
# ECS Cluster
ECSCluster:
Type: AWS::ECS::Cluster
Properties:
ClusterName: !Ref ClusterName
ClusterSettings:
- Name: containerInsights
Value: enabled
# EC2 Instance Configuration
InstanceCapacity:
Type: AWS::AutoScaling::LaunchConfiguration
Properties:
ImageId: !Ref AmiId
InstanceType: !Ref InstanceType
IamInstanceProfile: !Ref EcsInstanceProfile
SecurityGroups:
- !Ref EcsSecurityGroup
UserData:
Fn::Base64: !Sub |
#!/bin/bash
echo "ECS_CLUSTER=${ECSCluster.Name}" >> /etc/ecs/ecs.config
echo "ECS_BACKEND_HOST=${ECSBackendHost}" >> /etc/ecs/ecs.config
BlockDeviceMappings:
- DeviceName: /dev/xvda
Ebs:
VolumeSize: 30
VolumeType: gp3
AutoScalingGroup:
Type: AWS::AutoScaling::AutoScalingGroup
Properties:
AutoScalingGroupName: !Sub "${ClusterName}-asg"
LaunchConfigurationName: !Ref InstanceCapacity
MinSize: !Ref DesiredCapacity
MaxSize: !Ref MaxCapacity
DesiredCapacity: !Ref DesiredCapacity
VPCZoneIdentifier: !Ref SubnetIds
Tags:
- Key: Name
Value: !Sub "${ClusterName}-instance"
PropagateAtLaunch: true
- Key: Environment
Value: !Ref Environment
PropagateAtLaunch: true
Outputs:
ClusterName:
Description: Name of the ECS cluster
Value: !Ref ECSCluster
Export:
Name: !Sub "${AWS::StackName}-ClusterName"
ClusterArn:
Description: ARN of the ECS cluster
Value: !GetAtt ECSCluster.Arn
Export:
Name: !Sub "${AWS::StackName}-ClusterArn"Parameters Best Practices
参数最佳实践
AWS-Specific Parameter Types
AWS特定参数类型
yaml
Parameters:
# AWS-specific types for validation
VpcId:
Type: AWS::EC2::VPC::Id
Description: VPC where ECS cluster will be created
SubnetIds:
Type: List<AWS::EC2::Subnet::Id>
Description: Subnets for ECS instances
SecurityGroupIds:
Type: List<AWS::EC2::SecurityGroup::Id>
Description: Security groups for ECS service
ClusterArn:
Type: AWS::ECS::Cluster::Arn
Description: ARN of existing ECS cluster
TaskDefinitionArn:
Type: AWS::ECS::TaskDefinition::Arn
Description: ARN of ECS task definition
ServiceArn:
Type: AWS::ECS::Service::Arn
Description: ARN of ECS service
LoadBalancerArn:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer::Arn
Description: ARN of Application Load Balancer
TargetGroupArn:
Type: AWS::ElasticLoadBalancingV2::TargetGroup::Arn
Description: ARN of Target Groupyaml
Parameters:
# AWS-specific types for validation
VpcId:
Type: AWS::EC2::VPC::Id
Description: VPC where ECS cluster will be created
SubnetIds:
Type: List<AWS::EC2::Subnet::Id>
Description: Subnets for ECS instances
SecurityGroupIds:
Type: List<AWS::EC2::SecurityGroup::Id>
Description: Security groups for ECS service
ClusterArn:
Type: AWS::ECS::Cluster::Arn
Description: ARN of existing ECS cluster
TaskDefinitionArn:
Type: AWS::ECS::TaskDefinition::Arn
Description: ARN of ECS task definition
ServiceArn:
Type: AWS::ECS::Service::Arn
Description: ARN of ECS service
LoadBalancerArn:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer::Arn
Description: ARN of Application Load Balancer
TargetGroupArn:
Type: AWS::ElasticLoadBalancingV2::TargetGroup::Arn
Description: ARN of Target GroupParameter Constraints
参数约束
yaml
Parameters:
ContainerName:
Type: String
Default: web-app
Description: Container name
ConstraintDescription: Must be 1-256 characters, alphanumeric and hyphens
MinLength: 1
MaxLength: 256
AllowedPattern: "[a-zA-Z0-9-]+"
DesiredCount:
Type: Number
Default: 2
Description: Desired number of tasks
MinValue: 0
MaxValue: 1000
ConstraintDescription: Must be between 0 and 1000
Cpu:
Type: String
Default: 256
Description: CPU units for container
AllowedValues:
- 128
- 256
- 512
- 1024
- 2048
- 4096
ConstraintDescription: Must be a valid CPU value
Memory:
Type: Number
Default: 512
Description: Memory limit in MiB
MinValue: 4
MaxValue: 15000
ConstraintDescription: Must be between 4 and 15000 MiByaml
Parameters:
ContainerName:
Type: String
Default: web-app
Description: Container name
ConstraintDescription: Must be 1-256 characters, alphanumeric and hyphens
MinLength: 1
MaxLength: 256
AllowedPattern: "[a-zA-Z0-9-]+"
DesiredCount:
Type: Number
Default: 2
Description: Desired number of tasks
MinValue: 0
MaxValue: 1000
ConstraintDescription: Must be between 0 and 1000
Cpu:
Type: String
Default: 256
Description: CPU units for container
AllowedValues:
- 128
- 256
- 512
- 1024
- 2048
- 4096
ConstraintDescription: Must be a valid CPU value
Memory:
Type: Number
Default: 512
Description: Memory limit in MiB
MinValue: 4
MaxValue: 15000
ConstraintDescription: Must be between 4 and 15000 MiBSSM Parameter References
SSM参数引用
yaml
Parameters:
ContainerImage:
Type: AWS::SSM::Parameter::Value<String>
Default: /ecs/app/container-image
Description: Container image from SSM Parameter Store
DatabaseConnectionString:
Type: AWS::SSM::Parameter::Value<SecureString>
Default: /ecs/app/database/connection
Description: Database connection from SSMyaml
Parameters:
ContainerImage:
Type: AWS::SSM::Parameter::Value<String>
Default: /ecs/app/container-image
Description: Container image from SSM Parameter Store
DatabaseConnectionString:
Type: AWS::SSM::Parameter::Value<SecureString>
Default: /ecs/app/database/connection
Description: Database connection from SSMOutputs and Cross-Stack References
输出与跨栈引用
Export/Import Patterns
导出/导入模式
yaml
undefinedyaml
undefinedStack A - Network Stack
Stack A - Network Stack
AWSTemplateFormatVersion: 2010-09-09
Description: Network infrastructure stack for ECS
Resources:
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/16
EnableDnsHostnames: true
EnableDnsSupport: true
Tags:
- Key: Name
Value: !Sub "${AWS::StackName}-vpc"
PublicSubnets:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
AvailabilityZone: !Select [0, !GetAZs ""]
CidrBlock: 10.0.1.0/24
MapPublicIpOnLaunch: true
PrivateSubnets:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
AvailabilityZone: !Select [0, !GetAZs ""]
CidrBlock: 10.0.2.0/24
Outputs:
VpcId:
Description: VPC ID
Value: !Ref VPC
Export:
Name: !Sub "${AWS::StackName}-VpcId"
PublicSubnetIds:
Description: Public subnet IDs
Value: !Join [",", [!Ref PublicSubnet1, !Ref PublicSubnet2]]
Export:
Name: !Sub "${AWS::StackName}-PublicSubnetIds"
PrivateSubnetIds:
Description: Private subnet IDs
Value: !Join [",", [!Ref PrivateSubnet1, !Ref PrivateSubnet2]]
Export:
Name: !Sub "${AWS::StackName}-PrivateSubnetIds"
EcsSecurityGroupId:
Description: Security group ID for ECS
Value: !Ref EcsSecurityGroup
Export:
Name: !Sub "${AWS::StackName}-EcsSecurityGroupId"
```yamlAWSTemplateFormatVersion: 2010-09-09
Description: Network infrastructure stack for ECS
Resources:
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/16
EnableDnsHostnames: true
EnableDnsSupport: true
Tags:
- Key: Name
Value: !Sub "${AWS::StackName}-vpc"
PublicSubnets:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
AvailabilityZone: !Select [0, !GetAZs ""]
CidrBlock: 10.0.1.0/24
MapPublicIpOnLaunch: true
PrivateSubnets:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
AvailabilityZone: !Select [0, !GetAZs ""]
CidrBlock: 10.0.2.0/24
Outputs:
VpcId:
Description: VPC ID
Value: !Ref VPC
Export:
Name: !Sub "${AWS::StackName}-VpcId"
PublicSubnetIds:
Description: Public subnet IDs
Value: !Join [",", [!Ref PublicSubnet1, !Ref PublicSubnet2]]
Export:
Name: !Sub "${AWS::StackName}-PublicSubnetIds"
PrivateSubnetIds:
Description: Private subnet IDs
Value: !Join [",", [!Ref PrivateSubnet1, !Ref PrivateSubnet2]]
Export:
Name: !Sub "${AWS::StackName}-PrivateSubnetIds"
EcsSecurityGroupId:
Description: Security group ID for ECS
Value: !Ref EcsSecurityGroup
Export:
Name: !Sub "${AWS::StackName}-EcsSecurityGroupId"
```yamlStack B - ECS Stack (imports from Stack A)
Stack B - ECS Stack (imports from Stack A)
AWSTemplateFormatVersion: 2010-09-09
Description: ECS application stack
Parameters:
NetworkStackName:
Type: String
Default: network-stack
Description: Name of the network stack
Resources:
ECSService:
Type: AWS::ECS::Service
Properties:
ServiceName: !Sub "${AWS::StackName}-service"
Cluster: !ImportValue
!Sub "${NetworkStackName}-ClusterArn"
TaskDefinition: !Ref TaskDefinition
DesiredCount: 2
LaunchType: EC2
NetworkConfiguration:
AwsvpcConfiguration:
AssignPublicIp: DISABLED
SecurityGroups:
- !ImportValue
!Sub "${NetworkStackName}-EcsSecurityGroupId"
Subnets:
- !Select [0, !Split [",", !ImportValue !Sub "${NetworkStackName}-PrivateSubnetIds"]]
- !Select [1, !Split [",", !ImportValue !Sub "${NetworkStackName}-PrivateSubnetIds"]]
undefinedAWSTemplateFormatVersion: 2010-09-09
Description: ECS application stack
Parameters:
NetworkStackName:
Type: String
Default: network-stack
Description: Name of the network stack
Resources:
ECSService:
Type: AWS::ECS::Service
Properties:
ServiceName: !Sub "${AWS::StackName}-service"
Cluster: !ImportValue
!Sub "${NetworkStackName}-ClusterArn"
TaskDefinition: !Ref TaskDefinition
DesiredCount: 2
LaunchType: EC2
NetworkConfiguration:
AwsvpcConfiguration:
AssignPublicIp: DISABLED
SecurityGroups:
- !ImportValue
!Sub "${NetworkStackName}-EcsSecurityGroupId"
Subnets:
- !Select [0, !Split [",", !ImportValue !Sub "${NetworkStackName}-PrivateSubnetIds"]]
- !Select [1, !Split [",", !ImportValue !Sub "${NetworkStackName}-PrivateSubnetIds"]]
undefinedNested Stacks for Modularity
嵌套栈实现模块化
yaml
AWSTemplateFormatVersion: 2010-09-09
Description: Main stack with nested ECS stacks
Resources:
# Nested stack for cluster
ClusterStack:
Type: AWS::CloudFormation::Stack
Properties:
TemplateURL: https://s3.amazonaws.com/bucket/ecs-cluster.yaml
TimeoutInMinutes: 30
Parameters:
ClusterName: !Ref ClusterName
Environment: !Ref Environment
# Nested stack for services
ServicesStack:
Type: AWS::CloudFormation::Stack
Properties:
TemplateURL: https://s3.amazonaws.com/bucket/ecs-services.yaml
TimeoutInMinutes: 30
Parameters:
ClusterArn: !GetAtt ClusterStack.Outputs.ClusterArn
Environment: !Ref Environment
# Nested stack for load balancer
LoadBalancerStack:
Type: AWS::CloudFormation::Stack
Properties:
TemplateURL: https://s3.amazonaws.com/bucket/ecs-alb.yaml
TimeoutInMinutes: 30
Parameters:
VpcId: !Ref VpcId
Subnets: !Ref Subnetsyaml
AWSTemplateFormatVersion: 2010-09-09
Description: Main stack with nested ECS stacks
Resources:
# Nested stack for cluster
ClusterStack:
Type: AWS::CloudFormation::Stack
Properties:
TemplateURL: https://s3.amazonaws.com/bucket/ecs-cluster.yaml
TimeoutInMinutes: 30
Parameters:
ClusterName: !Ref ClusterName
Environment: !Ref Environment
# Nested stack for services
ServicesStack:
Type: AWS::CloudFormation::Stack
Properties:
TemplateURL: https://s3.amazonaws.com/bucket/ecs-services.yaml
TimeoutInMinutes: 30
Parameters:
ClusterArn: !GetAtt ClusterStack.Outputs.ClusterArn
Environment: !Ref Environment
# Nested stack for load balancer
LoadBalancerStack:
Type: AWS::CloudFormation::Stack
Properties:
TemplateURL: https://s3.amazonaws.com/bucket/ecs-alb.yaml
TimeoutInMinutes: 30
Parameters:
VpcId: !Ref VpcId
Subnets: !Ref SubnetsECS Task Definitions
ECS任务定义
Basic Task Definition
基础任务定义
yaml
AWSTemplateFormatVersion: 2010-09-09
Description: ECS task definition
Resources:
TaskDefinition:
Type: AWS::ECS::TaskDefinition
Properties:
Family: web-app-task
Cpu: "512"
Memory: "1024"
NetworkMode: awsvpc
RequiresCompatibilities:
- EC2
- FARGATE
ExecutionRoleArn: !Ref TaskExecutionRole
TaskRoleArn: !Ref TaskRole
ContainerDefinitions:
- Name: web-app
Image: !Ref ContainerImage
Cpu: 256
Memory: 512
PortMappings:
- ContainerPort: !Ref ContainerPort
Protocol: tcp
Environment:
- Name: ENVIRONMENT
Value: !Ref Environment
- Name: LOG_LEVEL
Value: INFO
Secrets:
- Name: DATABASE_URL
ValueFrom: !Ref DatabaseSecretArn
LogConfiguration:
LogDriver: awslogs
Options:
awslogs-group: !Ref LogGroup
awslogs-region: !Ref AWS::Region
awslogs-stream-prefix: ecs
HealthCheck:
Command:
- CMD-SHELL
- curl -f http://localhost:8080/health || exit 1
Interval: 30
Timeout: 5
Retries: 3
StartPeriod: 60
TaskExecutionRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Sub "${AWS::StackName}-task-execution-role"
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
Policies:
- PolicyName: EcsSecretsPolicy
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action:
- secretsmanager:GetSecretValue
Resource: !Ref DatabaseSecretArn
- PolicyName: EcsLogsPolicy
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action:
- logs:CreateLogStream
- logs:PutLogEvents
Resource: !GetAtt LogGroup.Arn
LogGroup:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: !Sub "/ecs/${AWS::StackName}"
RetentionInDays: 30yaml
AWSTemplateFormatVersion: 2010-09-09
Description: ECS task definition
Resources:
TaskDefinition:
Type: AWS::ECS::TaskDefinition
Properties:
Family: web-app-task
Cpu: "512"
Memory: "1024"
NetworkMode: awsvpc
RequiresCompatibilities:
- EC2
- FARGATE
ExecutionRoleArn: !Ref TaskExecutionRole
TaskRoleArn: !Ref TaskRole
ContainerDefinitions:
- Name: web-app
Image: !Ref ContainerImage
Cpu: 256
Memory: 512
PortMappings:
- ContainerPort: !Ref ContainerPort
Protocol: tcp
Environment:
- Name: ENVIRONMENT
Value: !Ref Environment
- Name: LOG_LEVEL
Value: INFO
Secrets:
- Name: DATABASE_URL
ValueFrom: !Ref DatabaseSecretArn
LogConfiguration:
LogDriver: awslogs
Options:
awslogs-group: !Ref LogGroup
awslogs-region: !Ref AWS::Region
awslogs-stream-prefix: ecs
HealthCheck:
Command:
- CMD-SHELL
- curl -f http://localhost:8080/health || exit 1
Interval: 30
Timeout: 5
Retries: 3
StartPeriod: 60
TaskExecutionRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Sub "${AWS::StackName}-task-execution-role"
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
Policies:
- PolicyName: EcsSecretsPolicy
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action:
- secretsmanager:GetSecretValue
Resource: !Ref DatabaseSecretArn
- PolicyName: EcsLogsPolicy
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action:
- logs:CreateLogStream
- logs:PutLogEvents
Resource: !GetAtt LogGroup.Arn
LogGroup:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: !Sub "/ecs/${AWS::StackName}"
RetentionInDays: 30Multi-Container Task Definition
多容器任务定义
yaml
Resources:
TaskDefinition:
Type: AWS::ECS::TaskDefinition
Properties:
Family: multi-container-task
Cpu: "1024"
Memory: "2048"
NetworkMode: awsvpc
ContainerDefinitions:
- Name: web
Image: nginx:latest
Cpu: 256
Memory: 512
PortMappings:
- ContainerPort: 80
Protocol: tcp
DependsOn:
- ContainerName: app
Condition: HEALTHY
Environment:
- Name: BACKEND_URL
Value: !Sub "http://localhost:${AppPort}"
LogConfiguration:
LogDriver: awslogs
Options:
awslogs-group: !Ref LogGroup
awslogs-region: !Ref AWS::Region
awslogs-stream-prefix: web
- Name: app
Image: !Ref AppImage
Cpu: 512
Memory: 1024
PortMappings:
- ContainerPort: !Ref AppPort
Protocol: tcp
Environment:
- Name: DATABASE_URL
ValueFrom: !Ref DatabaseSecretArn
- Name: REDIS_URL
ValueFrom: !Ref RedisSecretArn
LogConfiguration:
LogDriver: awslogs
Options:
awslogs-group: !Ref LogGroup
awslogs-region: !Ref AWS::Region
awslogs-stream-prefix: app
- Name: redis
Image: redis:alpine
Cpu: 128
Memory: 256
PortMappings:
- ContainerPort: 6379
Protocol: tcp
HealthCheck:
Command:
- CMD-SHELL
- redis-cli ping | grep -q PONG
Interval: 10
Timeout: 5
Retries: 3yaml
Resources:
TaskDefinition:
Type: AWS::ECS::TaskDefinition
Properties:
Family: multi-container-task
Cpu: "1024"
Memory: "2048"
NetworkMode: awsvpc
ContainerDefinitions:
- Name: web
Image: nginx:latest
Cpu: 256
Memory: 512
PortMappings:
- ContainerPort: 80
Protocol: tcp
DependsOn:
- ContainerName: app
Condition: HEALTHY
Environment:
- Name: BACKEND_URL
Value: !Sub "http://localhost:${AppPort}"
LogConfiguration:
LogDriver: awslogs
Options:
awslogs-group: !Ref LogGroup
awslogs-region: !Ref AWS::Region
awslogs-stream-prefix: web
- Name: app
Image: !Ref AppImage
Cpu: 512
Memory: 1024
PortMappings:
- ContainerPort: !Ref AppPort
Protocol: tcp
Environment:
- Name: DATABASE_URL
ValueFrom: !Ref DatabaseSecretArn
- Name: REDIS_URL
ValueFrom: !Ref RedisSecretArn
LogConfiguration:
LogDriver: awslogs
Options:
awslogs-group: !Ref LogGroup
awslogs-region: !Ref AWS::Region
awslogs-stream-prefix: app
- Name: redis
Image: redis:alpine
Cpu: 128
Memory: 256
PortMappings:
- ContainerPort: 6379
Protocol: tcp
HealthCheck:
Command:
- CMD-SHELL
- redis-cli ping | grep -q PONG
Interval: 10
Timeout: 5
Retries: 3ECS Services
ECS服务
Service with Application Load Balancer
结合应用负载均衡器的服务
yaml
AWSTemplateFormatVersion: 2010-09-09
Description: ECS service with ALB
Resources:
# Application Load Balancer
ApplicationLoadBalancer:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
Name: !Sub "${AWS::StackName}-alb"
Scheme: internet-facing
SecurityGroups:
- !Ref AlbSecurityGroup
Subnets: !Ref PublicSubnets
Type: application
AlbSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: !Sub "${AWS::StackName}-alb-sg"
GroupDescription: Security group for ALB
VpcId: !Ref VpcId
SecurityGroupIngress:
# HTTP from anywhere - public-facing ALB requires this
# For production, use AWS WAF or restrict to known CIDR ranges
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
Description: HTTP for public web traffic
# HTTPS from anywhere - public-facing ALB requires this
# For production, use AWS WAF or restrict to known CIDR ranges
- IpProtocol: tcp
FromPort: 443
ToPort: 443
CidrIp: 0.0.0.0/0
Description: HTTPS for secure public web traffic
# Target Groups
BlueTargetGroup:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
Name: !Sub "${AWS::StackName}-blue-tg"
Port: 80
Protocol: HTTP
VpcId: !Ref VpcId
Matcher:
HttpCode: 200-499
HealthCheckPath: /health
HealthCheckIntervalSeconds: 30
HealthCheckTimeoutSeconds: 5
HealthyThresholdCount: 2
UnhealthyThresholdCount: 3
TargetType: ip
IpAddressType: ipv4
GreenTargetGroup:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
Name: !Sub "${AWS::StackName}-green-tg"
Port: 80
Protocol: HTTP
VpcId: !Ref VpcId
Matcher:
HttpCode: 200-499
HealthCheckPath: /health
HealthCheckIntervalSeconds: 30
HealthCheckTimeoutSeconds: 5
HealthyThresholdCount: 2
UnhealthyThresholdCount: 3
TargetType: ip
IpAddressType: ipv4
# Listener
AlbListener:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
DefaultActions:
- Type: forward
ForwardConfig:
TargetGroupStickinessConfig:
Enabled: false
DurationSeconds: 3600
TargetGroups:
- TargetGroupArn: !Ref BlueTargetGroup
Weight: 100
LoadBalancerArn: !Ref ApplicationLoadBalancer
Port: 80
Protocol: HTTP
# ECS Service
EcsService:
Type: AWS::ECS::Service
DependsOn: AlbListener
Properties:
ServiceName: !Sub "${AWS::StackName}-service"
Cluster: !Ref ECSClusterArn
TaskDefinition: !Ref TaskDefinitionArn
DesiredCount: 2
LaunchType: FARGATE
DeploymentConfiguration:
MaximumPercent: 200
MinimumHealthyPercent: 50
DeploymentCircuitBreaker:
Enable: true
Rollback: true
NetworkConfiguration:
AwsvpcConfiguration:
AssignPublicIp: DISABLED
SecurityGroups:
- !Ref EcsSecurityGroup
Subnets: !Ref PrivateSubnets
LoadBalancers:
- ContainerName: web
ContainerPort: 80
TargetGroupArn: !Ref BlueTargetGroup
PropagateTags: SERVICE
ServiceRegistries:
- RegistryArn: !GetAtt ServiceDiscoveryService.Arn
EcsSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: !Sub "${AWS::StackName}-ecs-sg"
GroupDescription: Security group for ECS service
VpcId: !Ref VpcId
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
SourceSecurityGroupId: !Ref AlbSecurityGroup
# Service Discovery
ServiceDiscoveryService:
Type: AWS::ServiceDiscovery::Service
Properties:
Name: web-app
DnsConfig:
NamespaceId: !Ref ServiceDiscoveryNamespace
DnsRecords:
- Type: A
TTL: 60
HealthCheckConfig:
Type: HTTP
ResourcePath: /health
ServiceDiscoveryNamespace:
Type: AWS::ServiceDiscovery::PrivateDnsNamespace
Properties:
Name: !Sub "${Environment}.internal"
VpcId: !Ref VpcIdyaml
AWSTemplateFormatVersion: 2010-09-09
Description: ECS service with ALB
Resources:
# Application Load Balancer
ApplicationLoadBalancer:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
Name: !Sub "${AWS::StackName}-alb"
Scheme: internet-facing
SecurityGroups:
- !Ref AlbSecurityGroup
Subnets: !Ref PublicSubnets
Type: application
AlbSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: !Sub "${AWS::StackName}-alb-sg"
GroupDescription: Security group for ALB
VpcId: !Ref VpcId
SecurityGroupIngress:
# HTTP from anywhere - public-facing ALB requires this
# For production, use AWS WAF or restrict to known CIDR ranges
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
Description: HTTP for public web traffic
# HTTPS from anywhere - public-facing ALB requires this
# For production, use AWS WAF or restrict to known CIDR ranges
- IpProtocol: tcp
FromPort: 443
ToPort: 443
CidrIp: 0.0.0.0/0
Description: HTTPS for secure public web traffic
# Target Groups
BlueTargetGroup:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
Name: !Sub "${AWS::StackName}-blue-tg"
Port: 80
Protocol: HTTP
VpcId: !Ref VpcId
Matcher:
HttpCode: 200-499
HealthCheckPath: /health
HealthCheckIntervalSeconds: 30
HealthCheckTimeoutSeconds: 5
HealthyThresholdCount: 2
UnhealthyThresholdCount: 3
TargetType: ip
IpAddressType: ipv4
GreenTargetGroup:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
Name: !Sub "${AWS::StackName}-green-tg"
Port: 80
Protocol: HTTP
VpcId: !Ref VpcId
Matcher:
HttpCode: 200-499
HealthCheckPath: /health
HealthCheckIntervalSeconds: 30
HealthCheckTimeoutSeconds: 5
HealthyThresholdCount: 2
UnhealthyThresholdCount: 3
TargetType: ip
IpAddressType: ipv4
# Listener
AlbListener:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
DefaultActions:
- Type: forward
ForwardConfig:
TargetGroupStickinessConfig:
Enabled: false
DurationSeconds: 3600
TargetGroups:
- TargetGroupArn: !Ref BlueTargetGroup
Weight: 100
LoadBalancerArn: !Ref ApplicationLoadBalancer
Port: 80
Protocol: HTTP
# ECS Service
EcsService:
Type: AWS::ECS::Service
DependsOn: AlbListener
Properties:
ServiceName: !Sub "${AWS::StackName}-service"
Cluster: !Ref ECSClusterArn
TaskDefinition: !Ref TaskDefinitionArn
DesiredCount: 2
LaunchType: FARGATE
DeploymentConfiguration:
MaximumPercent: 200
MinimumHealthyPercent: 50
DeploymentCircuitBreaker:
Enable: true
Rollback: true
NetworkConfiguration:
AwsvpcConfiguration:
AssignPublicIp: DISABLED
SecurityGroups:
- !Ref EcsSecurityGroup
Subnets: !Ref PrivateSubnets
LoadBalancers:
- ContainerName: web
ContainerPort: 80
TargetGroupArn: !Ref BlueTargetGroup
PropagateTags: SERVICE
ServiceRegistries:
- RegistryArn: !GetAtt ServiceDiscoveryService.Arn
EcsSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: !Sub "${AWS::StackName}-ecs-sg"
GroupDescription: Security group for ECS service
VpcId: !Ref VpcId
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
SourceSecurityGroupId: !Ref AlbSecurityGroup
# Service Discovery
ServiceDiscoveryService:
Type: AWS::ServiceDiscovery::Service
Properties:
Name: web-app
DnsConfig:
NamespaceId: !Ref ServiceDiscoveryNamespace
DnsRecords:
- Type: A
TTL: 60
HealthCheckConfig:
Type: HTTP
ResourcePath: /health
ServiceDiscoveryNamespace:
Type: AWS::ServiceDiscovery::PrivateDnsNamespace
Properties:
Name: !Sub "${Environment}.internal"
VpcId: !Ref VpcIdAuto Scaling
自动扩缩容
Service Auto Scaling
服务自动扩缩容
yaml
AWSTemplateFormatVersion: 2010-09-09
Description: ECS service with auto scaling
Resources:
# Scalable Target
ScalableTarget:
Type: AWS::ApplicationAutoScaling::ScalableTarget
Properties:
MaxCapacity: 10
MinCapacity: 2
ResourceId: !Sub "service/${ECSClusterName}/${ECSServiceName}"
RoleARN: !Ref AutoScalingRoleArn
ScalableDimension: ecs:service:DesiredCount
ServiceNamespace: ecs
# Scaling Policy - CPU Utilization
CpuScalingPolicy:
Type: AWS::ApplicationAutoScaling::ScalingPolicy
Properties:
PolicyName: !Sub "${AWS::StackName}-cpu-scaling"
PolicyType: TargetTrackingScaling
ScalingTargetId: !Ref ScalableTarget
TargetTrackingScalingPolicyConfiguration:
PredefinedMetricSpecification:
PredefinedMetricType: ECSServiceAverageCPUUtilization
TargetValue: 70
ScaleInCooldown: 300
ScaleOutCooldown: 60
# Scaling Policy - Memory Utilization
MemoryScalingPolicy:
Type: AWS::ApplicationAutoScaling::ScalingPolicy
Properties:
PolicyName: !Sub "${AWS::StackName}-memory-scaling"
PolicyType: TargetTrackingScaling
ScalingTargetId: !Ref ScalableTarget
TargetTrackingScalingPolicyConfiguration:
PredefinedMetricSpecification:
PredefinedMetricType: ECSServiceAverageMemoryUtilization
TargetValue: 80
ScaleInCooldown: 300
ScaleOutCooldown: 60
# Step Scaling Policy
RequestCountScalingPolicy:
Type: AWS::ApplicationAutoScaling::ScalingPolicy
Properties:
PolicyName: !Sub "${AWS::StackName}-request-scaling"
PolicyType: StepScaling
ScalingTargetId: !Ref ScalableTarget
StepScalingPolicyConfiguration:
AdjustmentType: ChangeInCapacity
Cooldown: 60
MetricAggregationType: Average
StepAdjustments:
- MetricIntervalLowerBound: 0
ScalingAdjustment: 1
- MetricIntervalLowerBound: 1000
ScalingAdjustment: 2
- MetricIntervalLowerBound: 5000
ScalingAdjustment: 4
# CloudWatch Alarm
HighCpuAlarm:
Type: AWS::CloudWatch::Alarm
Properties:
AlarmName: !Sub "${AWS::StackName}-high-cpu"
AlarmDescription: CPU utilization above threshold
MetricName: CPUUtilization
Namespace: AWS/ECS
Dimensions:
- Name: ClusterName
Value: !Ref ECSClusterName
- Name: ServiceName
Value: !Ref ECSServiceName
Statistic: Average
Period: 60
EvaluationPeriods: 2
Threshold: 80
ComparisonOperator: GreaterThanThreshold
AlarmActions:
- !Ref RequestCountScalingPolicy
AutoScalingRoleArn:
Type: AWS::IAM::Role
Properties:
RoleName: !Sub "${AWS::StackName}-autoscaling-role"
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service: application-autoscaling.amazonaws.com
Action: sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceAutoscaleRoleyaml
AWSTemplateFormatVersion: 2010-09-09
Description: ECS service with auto scaling
Resources:
# Scalable Target
ScalableTarget:
Type: AWS::ApplicationAutoScaling::ScalableTarget
Properties:
MaxCapacity: 10
MinCapacity: 2
ResourceId: !Sub "service/${ECSClusterName}/${ECSServiceName}"
RoleARN: !Ref AutoScalingRoleArn
ScalableDimension: ecs:service:DesiredCount
ServiceNamespace: ecs
# Scaling Policy - CPU Utilization
CpuScalingPolicy:
Type: AWS::ApplicationAutoScaling::ScalingPolicy
Properties:
PolicyName: !Sub "${AWS::StackName}-cpu-scaling"
PolicyType: TargetTrackingScaling
ScalingTargetId: !Ref ScalableTarget
TargetTrackingScalingPolicyConfiguration:
PredefinedMetricSpecification:
PredefinedMetricType: ECSServiceAverageCPUUtilization
TargetValue: 70
ScaleInCooldown: 300
ScaleOutCooldown: 60
# Scaling Policy - Memory Utilization
MemoryScalingPolicy:
Type: AWS::ApplicationAutoScaling::ScalingPolicy
Properties:
PolicyName: !Sub "${AWS::StackName}-memory-scaling"
PolicyType: TargetTrackingScaling
ScalingTargetId: !Ref ScalableTarget
TargetTrackingScalingPolicyConfiguration:
PredefinedMetricSpecification:
PredefinedMetricType: ECSServiceAverageMemoryUtilization
TargetValue: 80
ScaleInCooldown: 300
ScaleOutCooldown: 60
# Step Scaling Policy
RequestCountScalingPolicy:
Type: AWS::ApplicationAutoScaling::ScalingPolicy
Properties:
PolicyName: !Sub "${AWS::StackName}-request-scaling"
PolicyType: StepScaling
ScalingTargetId: !Ref ScalableTarget
StepScalingPolicyConfiguration:
AdjustmentType: ChangeInCapacity
Cooldown: 60
MetricAggregationType: Average
StepAdjustments:
- MetricIntervalLowerBound: 0
ScalingAdjustment: 1
- MetricIntervalLowerBound: 1000
ScalingAdjustment: 2
- MetricIntervalLowerBound: 5000
ScalingAdjustment: 4
# CloudWatch Alarm
HighCpuAlarm:
Type: AWS::CloudWatch::Alarm
Properties:
AlarmName: !Sub "${AWS::StackName}-high-cpu"
AlarmDescription: CPU utilization above threshold
MetricName: CPUUtilization
Namespace: AWS/ECS
Dimensions:
- Name: ClusterName
Value: !Ref ECSClusterName
- Name: ServiceName
Value: !Ref ECSServiceName
Statistic: Average
Period: 60
EvaluationPeriods: 2
Threshold: 80
ComparisonOperator: GreaterThanThreshold
AlarmActions:
- !Ref RequestCountScalingPolicy
AutoScalingRoleArn:
Type: AWS::IAM::Role
Properties:
RoleName: !Sub "${AWS::StackName}-autoscaling-role"
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service: application-autoscaling.amazonaws.com
Action: sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceAutoscaleRoleBlue/Green Deployments with CodeDeploy
结合CodeDeploy的蓝绿部署
yaml
AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::CodeDeployBlueGreen
Description: ECS blue/green deployment with CodeDeploy
Parameters:
Environment:
Type: String
Default: production
AllowedValues:
- staging
- production
Resources:
# ECS Cluster
ECSCluster:
Type: AWS::ECS::Cluster
Properties:
ClusterName: !Sub "${AWS::StackName}-cluster"
# Task Definition (Blue)
TaskDefinitionBlue:
Type: AWS::ECS::TaskDefinition
Properties:
Family: blue-task
Cpu: "512"
Memory: "1024"
NetworkMode: awsvpc
RequiresCompatibilities:
- FARGATE
ContainerDefinitions:
- Name: web
Image: !Ref BlueImage
Cpu: 256
Memory: 512
PortMappings:
- ContainerPort: 80
LogConfiguration:
LogDriver: awslogs
Options:
awslogs-group: !Ref LogGroup
awslogs-region: !Ref AWS::Region
awslogs-stream-prefix: blue
# Task Definition (Green)
TaskDefinitionGreen:
Type: AWS::ECS::TaskDefinition
Properties:
Family: green-task
Cpu: "512"
Memory: "1024"
NetworkMode: awsvpc
RequiresCompatibilities:
- FARGATE
ContainerDefinitions:
- Name: web
Image: !Ref GreenImage
Cpu: 256
Memory: 512
PortMappings:
- ContainerPort: 80
LogConfiguration:
LogDriver: awslogs
Options:
awslogs-group: !Ref LogGroup
awslogs-region: !Ref AWS::Region
awslogs-stream-prefix: green
# Task Set (Blue)
TaskSetBlue:
Type: AWS::ECS::TaskSet
Properties:
Cluster: !Ref ECSCluster
Service: !Ref ECSService
TaskDefinition: !Ref TaskDefinitionBlue
Scale:
Unit: PERCENT
Value: 100
# Task Set (Green)
TaskSetGreen:
Type: AWS::ECS::TaskSet
Properties:
Cluster: !Ref ECSCluster
Service: !Ref ECSService
TaskDefinition: !Ref TaskDefinitionGreen
Scale:
Unit: PERCENT
Value: 0
# ECS Service
ECSService:
Type: AWS::ECS::Service
Properties:
ServiceName: !Sub "${AWS::StackName}-service"
Cluster: !Ref ECSCluster
TaskDefinition: !Ref TaskDefinitionBlue
DesiredCount: 2
LaunchType: FARGATE
LoadBalancers:
- ContainerName: web
ContainerPort: 80
TargetGroupArn: !Ref BlueTargetGroup
# Target Groups
BlueTargetGroup:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
Name: !Sub "${AWS::StackName}-blue-tg"
Port: 80
Protocol: HTTP
VpcId: !Ref VpcId
HealthCheckPath: /health
TargetType: ip
GreenTargetGroup:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
Name: !Sub "${AWS::StackName}-green-tg"
Port: 80
Protocol: HTTP
VpcId: !Ref VpcId
HealthCheckPath: /health
TargetType: ip
# Listener
ProductionListener:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
DefaultActions:
- Type: forward
TargetGroupArn: !Ref BlueTargetGroup
LoadBalancerArn: !Ref ApplicationLoadBalancer
Port: 80
Protocol: HTTP
TestListener:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
DefaultActions:
- Type: forward
TargetGroupArn: !Ref BlueTargetGroup
LoadBalancerArn: !Ref ApplicationLoadBalancer
Port: 8080
Protocol: HTTP
ApplicationLoadBalancer:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
Name: !Sub "${AWS::StackName}-alb"
Scheme: internet-facing
Subnets: !Ref PublicSubnets
SecurityGroups:
- !Ref AlbSecurityGroup
AlbSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: !Sub "${AWS::StackName}-alb-sg"
GroupDescription: ALB security group
VpcId: !Ref VpcId
SecurityGroupIngress:
# HTTP from anywhere - public-facing ALB requires this
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
Description: HTTP for public web traffic
# Test traffic from internal network only
- IpProtocol: tcp
FromPort: 8080
ToPort: 8080
CidrIp: 10.0.0.0/16
Description: Test traffic from internal VPC
LogGroup:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: !Sub "/ecs/${AWS::StackName}"
RetentionInDays: 30
Hooks:
BlueGreenHook:
Type: AWS::CodeDeploy::BlueGreen
Properties:
TrafficRoutingConfig:
Type: TimeBasedCanary
TimeBasedCanary:
StepPercentage: 15
BakeTimeMins: 5
AdditionalOptions:
TerminationWaitTimeInMinutes: 5
ServiceRole: !Ref CodeDeployRoleArn
Applications:
- Target:
Type: AWS::ECS::Service
LogicalID: ECSService
ECSAttributes:
TaskDefinitions:
- TaskDefinitionBlue
- TaskDefinitionGreen
TaskSets:
- TaskSetBlue
- TaskSetGreen
TrafficRouting:
ProdTrafficRoute:
Type: AWS::ElasticLoadBalancingV2::Listener
LogicalID: ProductionListener
TestTrafficRoute:
Type: AWS::ElasticLoadBalancingV2::Listener
LogicalID: TestListener
TargetGroups:
- BlueTargetGroup
- GreenTargetGroup
CodeDeployRoleArn:
Value: !Sub "arn:aws:iam::${AWS::AccountId}:role/service-role/AmazonCodeDeployRoleForECS"yaml
AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::CodeDeployBlueGreen
Description: ECS blue/green deployment with CodeDeploy
Parameters:
Environment:
Type: String
Default: production
AllowedValues:
- staging
- production
Resources:
# ECS Cluster
ECSCluster:
Type: AWS::ECS::Cluster
Properties:
ClusterName: !Sub "${AWS::StackName}-cluster"
# Task Definition (Blue)
TaskDefinitionBlue:
Type: AWS::ECS::TaskDefinition
Properties:
Family: blue-task
Cpu: "512"
Memory: "1024"
NetworkMode: awsvpc
RequiresCompatibilities:
- FARGATE
ContainerDefinitions:
- Name: web
Image: !Ref BlueImage
Cpu: 256
Memory: 512
PortMappings:
- ContainerPort: 80
LogConfiguration:
LogDriver: awslogs
Options:
awslogs-group: !Ref LogGroup
awslogs-region: !Ref AWS::Region
awslogs-stream-prefix: blue
# Task Definition (Green)
TaskDefinitionGreen:
Type: AWS::ECS::TaskDefinition
Properties:
Family: green-task
Cpu: "512"
Memory: "1024"
NetworkMode: awsvpc
RequiresCompatibilities:
- FARGATE
ContainerDefinitions:
- Name: web
Image: !Ref GreenImage
Cpu: 256
Memory: 512
PortMappings:
- ContainerPort: 80
LogConfiguration:
LogDriver: awslogs
Options:
awslogs-group: !Ref LogGroup
awslogs-region: !Ref AWS::Region
awslogs-stream-prefix: green
# Task Set (Blue)
TaskSetBlue:
Type: AWS::ECS::TaskSet
Properties:
Cluster: !Ref ECSCluster
Service: !Ref ECSService
TaskDefinition: !Ref TaskDefinitionBlue
Scale:
Unit: PERCENT
Value: 100
# Task Set (Green)
TaskSetGreen:
Type: AWS::ECS::TaskSet
Properties:
Cluster: !Ref ECSCluster
Service: !Ref ECSService
TaskDefinition: !Ref TaskDefinitionGreen
Scale:
Unit: PERCENT
Value: 0
# ECS Service
ECSService:
Type: AWS::ECS::Service
Properties:
ServiceName: !Sub "${AWS::StackName}-service"
Cluster: !Ref ECSCluster
TaskDefinition: !Ref TaskDefinitionBlue
DesiredCount: 2
LaunchType: FARGATE
LoadBalancers:
- ContainerName: web
ContainerPort: 80
TargetGroupArn: !Ref BlueTargetGroup
# Target Groups
BlueTargetGroup:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
Name: !Sub "${AWS::StackName}-blue-tg"
Port: 80
Protocol: HTTP
VpcId: !Ref VpcId
HealthCheckPath: /health
TargetType: ip
GreenTargetGroup:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
Name: !Sub "${AWS::StackName}-green-tg"
Port: 80
Protocol: HTTP
VpcId: !Ref VpcId
HealthCheckPath: /health
TargetType: ip
# Listener
ProductionListener:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
DefaultActions:
- Type: forward
TargetGroupArn: !Ref BlueTargetGroup
LoadBalancerArn: !Ref ApplicationLoadBalancer
Port: 80
Protocol: HTTP
TestListener:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
DefaultActions:
- Type: forward
TargetGroupArn: !Ref BlueTargetGroup
LoadBalancerArn: !Ref ApplicationLoadBalancer
Port: 8080
Protocol: HTTP
ApplicationLoadBalancer:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
Name: !Sub "${AWS::StackName}-alb"
Scheme: internet-facing
Subnets: !Ref PublicSubnets
SecurityGroups:
- !Ref AlbSecurityGroup
AlbSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: !Sub "${AWS::StackName}-alb-sg"
GroupDescription: ALB security group
VpcId: !Ref VpcId
SecurityGroupIngress:
# HTTP from anywhere - public-facing ALB requires this
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
Description: HTTP for public web traffic
# Test traffic from internal network only
- IpProtocol: tcp
FromPort: 8080
ToPort: 8080
CidrIp: 10.0.0.0/16
Description: Test traffic from internal VPC
LogGroup:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: !Sub "/ecs/${AWS::StackName}"
RetentionInDays: 30
Hooks:
BlueGreenHook:
Type: AWS::CodeDeploy::BlueGreen
Properties:
TrafficRoutingConfig:
Type: TimeBasedCanary
TimeBasedCanary:
StepPercentage: 15
BakeTimeMins: 5
AdditionalOptions:
TerminationWaitTimeInMinutes: 5
ServiceRole: !Ref CodeDeployRoleArn
Applications:
- Target:
Type: AWS::ECS::Service
LogicalID: ECSService
ECSAttributes:
TaskDefinitions:
- TaskDefinitionBlue
- TaskDefinitionGreen
TaskSets:
- TaskSetBlue
- TaskSetGreen
TrafficRouting:
ProdTrafficRoute:
Type: AWS::ElasticLoadBalancingV2::Listener
LogicalID: ProductionListener
TestTrafficRoute:
Type: AWS::ElasticLoadBalancingV2::Listener
LogicalID: TestListener
TargetGroups:
- BlueTargetGroup
- GreenTargetGroup
CodeDeployRoleArn:
Value: !Sub "arn:aws:iam::${AWS::AccountId}:role/service-role/AmazonCodeDeployRoleForECS"Conditions and Transforms
条件与转换
Conditions for Environment-Specific Resources
针对特定环境资源的条件
yaml
AWSTemplateFormatVersion: 2010-09-09
Description: ECS with conditional resources
Parameters:
Environment:
Type: String
Default: dev
AllowedValues:
- dev
- staging
- production
EnableServiceDiscovery:
Type: String
Default: true
AllowedValues:
- true
- false
EnableSpotInstances:
Type: String
Default: false
AllowedValues:
- true
- false
Conditions:
IsProduction: !Equals [!Ref Environment, production]
IsStaging: !Equals [!Ref Environment, staging]
UseServiceDiscovery: !Equals [!Ref EnableServiceDiscovery, true]
UseSpotInstances: !And
- !Equals [!Ref EnableSpotInstances, true]
- !Not [!Equals [!Ref Environment, production]]
Resources:
# Always created
ECSCluster:
Type: AWS::ECS::Cluster
Properties:
ClusterName: !Sub "${AWS::StackName}-${Environment}"
# Conditionally created service discovery
ServiceDiscoveryNamespace:
Type: AWS::ServiceDiscovery::PrivateDnsNamespace
Condition: UseServiceDiscovery
Properties:
Name: !Sub "${Environment}.internal"
VpcId: !Ref VpcId
# Conditionally created DLQ
DeadLetterQueue:
Type: AWS::SQS::Queue
Condition: IsProduction
Properties:
QueueName: !Sub "${AWS::StackName}-dlq"yaml
AWSTemplateFormatVersion: 2010-09-09
Description: ECS with conditional resources
Parameters:
Environment:
Type: String
Default: dev
AllowedValues:
- dev
- staging
- production
EnableServiceDiscovery:
Type: String
Default: true
AllowedValues:
- true
- false
EnableSpotInstances:
Type: String
Default: false
AllowedValues:
- true
- false
Conditions:
IsProduction: !Equals [!Ref Environment, production]
IsStaging: !Equals [!Ref Environment, staging]
UseServiceDiscovery: !Equals [!Ref EnableServiceDiscovery, true]
UseSpotInstances: !And
- !Equals [!Ref EnableSpotInstances, true]
- !Not [!Equals [!Ref Environment, production]]
Resources:
# Always created
ECSCluster:
Type: AWS::ECS::Cluster
Properties:
ClusterName: !Sub "${AWS::StackName}-${Environment}"
# Conditionally created service discovery
ServiceDiscoveryNamespace:
Type: AWS::ServiceDiscovery::PrivateDnsNamespace
Condition: UseServiceDiscovery
Properties:
Name: !Sub "${Environment}.internal"
VpcId: !Ref VpcId
# Conditionally created DLQ
DeadLetterQueue:
Type: AWS::SQS::Queue
Condition: IsProduction
Properties:
QueueName: !Sub "${AWS::StackName}-dlq"Transforms for Code Reuse
用于代码复用的转换
yaml
AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::Serverless-2016-10-31
Description: Using SAM Transform for ECS
Globals:
Function:
Timeout: 30
Runtime: python3.11
Tracing: Active
Resources:
TaskFunction:
Type: AWS::Serverless::Function
Properties:
FunctionName: !Sub "${AWS::StackName}-task-processor"
Handler: task_handler.handler
Policies:
- ECSFullAccess
Events:
TaskQueue:
Type: SQS
Properties:
Queue: !GetAtt TaskQueue.Arn
BatchSize: 10
TaskQueue:
Type: AWS::SQS::Queue
Properties:
QueueName: !Sub "${AWS::StackName}-tasks"
VisibilityTimeout: 360yaml
AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::Serverless-2016-10-31
Description: Using SAM Transform for ECS
Globals:
Function:
Timeout: 30
Runtime: python3.11
Tracing: Active
Resources:
TaskFunction:
Type: AWS::Serverless::Function
Properties:
FunctionName: !Sub "${AWS::StackName}-task-processor"
Handler: task_handler.handler
Policies:
- ECSFullAccess
Events:
TaskQueue:
Type: SQS
Properties:
Queue: !GetAtt TaskQueue.Arn
BatchSize: 10
TaskQueue:
Type: AWS::SQS::Queue
Properties:
QueueName: !Sub "${AWS::StackName}-tasks"
VisibilityTimeout: 360CloudFormation Best Practices
CloudFormation最佳实践
Stack Policies
栈策略
Stack Policies prevent accidental updates to critical infrastructure resources. Use them to protect ECS clusters, task definitions, and production services from unintended modifications.
yaml
AWSTemplateFormatVersion: 2010-09-09
Description: ECS stack with protective policy
Resources:
ECSCluster:
Type: AWS::ECS::Cluster
Properties:
ClusterName: !Sub "${AWS::StackName}-cluster"
EcsService:
Type: AWS::ECS::Service
Properties:
ServiceName: !Sub "${AWS::StackName}-service"
Cluster: !Ref ECSCluster
TaskDefinition: !Ref TaskDefinition
DesiredCount: 2
TaskDefinition:
Type: AWS::ECS::TaskDefinition
Properties:
Family: web-app-task
Cpu: "512"
Memory: "1024"
NetworkMode: awsvpc
RequiresCompatibilities:
- FARGATE
ContainerDefinitions:
- Name: web
Image: !Ref ContainerImage
Cpu: 256
Memory: 512
PortMappings:
- ContainerPort: 80栈策略可防止意外更新关键基础设施资源。使用栈策略保护ECS集群、任务定义和生产环境服务免受非预期修改。
yaml
AWSTemplateFormatVersion: 2010-09-09
Description: ECS stack with protective policy
Resources:
ECSCluster:
Type: AWS::ECS::Cluster
Properties:
ClusterName: !Sub "${AWS::StackName}-cluster"
EcsService:
Type: AWS::ECS::Service
Properties:
ServiceName: !Sub "${AWS::StackName}-service"
Cluster: !Ref ECSCluster
TaskDefinition: !Ref TaskDefinition
DesiredCount: 2
TaskDefinition:
Type: AWS::ECS::TaskDefinition
Properties:
Family: web-app-task
Cpu: "512"
Memory: "1024"
NetworkMode: awsvpc
RequiresCompatibilities:
- FARGATE
ContainerDefinitions:
- Name: web
Image: !Ref ContainerImage
Cpu: 256
Memory: 512
PortMappings:
- ContainerPort: 80Stack Policy JSON (apply via AWS Console or CLI)
Stack Policy JSON (apply via AWS Console or CLI)
StackPolicy:
Statement:
# Allow all updates to task definitions (needed for deployments)
- Effect: Allow
Action: Update:Modify
Resource: "*"
# Prevent modifications to the ECS cluster
- Effect: Deny
Action:
- Update:Modify
- Update:Replace
- Delete
Resource: "*"
Condition:
StringEquals:
ResourceType:
- AWS::ECS::Cluster
# Prevent deletion of the ECS service in production
- Effect: Deny
Action: Delete
Resource: "*"
Condition:
StringEquals:
ResourceType:
- AWS::ECS::Service
StringEqualsIfExists:
Environment: production
Apply stack policy using CLI:
```bash
aws cloudformation set-stack-policy \
--stack-name my-ecs-stack \
--stack-policy-body file://stack-policy.jsonStackPolicy:
Statement:
# Allow all updates to task definitions (needed for deployments)
- Effect: Allow
Action: Update:Modify
Resource: "*"
# Prevent modifications to the ECS cluster
- Effect: Deny
Action:
- Update:Modify
- Update:Replace
- Delete
Resource: "*"
Condition:
StringEquals:
ResourceType:
- AWS::ECS::Cluster
# Prevent deletion of the ECS service in production
- Effect: Deny
Action: Delete
Resource: "*"
Condition:
StringEquals:
ResourceType:
- AWS::ECS::Service
StringEqualsIfExists:
Environment: production
通过CLI应用栈策略:
```bash
aws cloudformation set-stack-policy \
--stack-name my-ecs-stack \
--stack-policy-body file://stack-policy.jsonTermination Protection
终止保护
Enable termination protection to prevent accidental deletion of production stacks. This is critical for ECS infrastructure that handles production workloads.
bash
undefined启用终止保护可防止意外删除生产环境栈。这对于处理生产工作负载的ECS基础设施至关重要。
bash
undefinedEnable termination protection when creating a stack
Enable termination protection when creating a stack
aws cloudformation create-stack
--stack-name production-ecs
--template-body file://ecs-template.yaml
--enable-termination-protection
--stack-name production-ecs
--template-body file://ecs-template.yaml
--enable-termination-protection
aws cloudformation create-stack
--stack-name production-ecs
--template-body file://ecs-template.yaml
--enable-termination-protection
--stack-name production-ecs
--template-body file://ecs-template.yaml
--enable-termination-protection
Enable termination protection on existing stack
Enable termination protection on existing stack
aws cloudformation update-termination-protection
--stack-name production-ecs
--enable-termination-protection
--stack-name production-ecs
--enable-termination-protection
aws cloudformation update-termination-protection
--stack-name production-ecs
--enable-termination-protection
--stack-name production-ecs
--enable-termination-protection
Disable termination protection (requires explicit confirmation)
Disable termination protection (requires explicit confirmation)
aws cloudformation update-termination-protection
--stack-name production-ecs
--no-enable-termination-protection
--stack-name production-ecs
--no-enable-termination-protection
In templates, add to resources that should be preserved:
```yaml
Resources:
ProductionECSService:
Type: AWS::ECS::Service
DeletionPolicy: Retain
UpdateReplacePolicy: Retain
Properties:
# ... service configurationaws cloudformation update-termination-protection
--stack-name production-ecs
--no-enable-termination-protection
--stack-name production-ecs
--no-enable-termination-protection
在模板中,为需要保留的资源添加以下配置:
```yaml
Resources:
ProductionECSService:
Type: AWS::ECS::Service
DeletionPolicy: Retain
UpdateReplacePolicy: Retain
Properties:
# ... service configurationDrift Detection
漂移检测
CloudFormation drift detection identifies when infrastructure has been modified outside of CloudFormation. Regular drift checks ensure your ECS infrastructure remains consistent with your templates.
bash
undefinedCloudFormation漂移检测可识别基础设施在CloudFormation之外被修改的情况。定期进行漂移检查可确保您的ECS基础设施与模板保持一致。
bash
undefinedDetect drift on a stack
Detect drift on a stack
aws cloudformation detect-stack-drift
--stack-name my-ecs-stack
--stack-name my-ecs-stack
aws cloudformation detect-stack-drift
--stack-name my-ecs-stack
--stack-name my-ecs-stack
Get drift detection status
Get drift detection status
aws cloudformation describe-stack-drift-detection-status
--stack-drift-detection-id <detection-id>
--stack-drift-detection-id <detection-id>
aws cloudformation describe-stack-drift-detection-status
--stack-drift-detection-id <detection-id>
--stack-drift-detection-id <detection-id>
Get stack resources with drift status
Get stack resources with drift status
aws cloudformation describe-stack-resource-drifts
--stack-name my-ecs-stack
--stack-name my-ecs-stack
aws cloudformation describe-stack-resource-drifts
--stack-name my-ecs-stack
--stack-name my-ecs-stack
Check specific resource drift
Check specific resource drift
aws cloudformation detect-stack-resource-drift
--stack-name my-ecs-stack
--logical-resource-id EcsService
--stack-name my-ecs-stack
--logical-resource-id EcsService
Drift status values:
- **IN_SYNC**: Resource matches template
- **MODIFIED**: Resource has been changed outside CloudFormation
- **DELETED**: Resource exists in template but not in AWS
- **NOT_CHECKED**: Resource not included in drift detection
Automated drift detection schedule:
```yamlaws cloudformation detect-stack-resource-drift
--stack-name my-ecs-stack
--logical-resource-id EcsService
--stack-name my-ecs-stack
--logical-resource-id EcsService
漂移状态值:
- **IN_SYNC**:资源与模板一致
- **MODIFIED**:资源已在CloudFormation之外被修改
- **DELETED**:资源存在于模板中但在AWS中已被删除
- **NOT_CHECKED**:未对资源进行漂移检测
自动化漂移检测计划:
```yamlUse AWS Config rules for continuous drift monitoring
Use AWS Config rules for continuous drift monitoring
Resources:
CloudFormationStackDriftDetectionConfigRule:
Type: AWS::Config::ConfigRule
Properties:
ConfigRuleName: cf-drift-detection
Description: Detect CloudFormation stack drift
Source:
Owner: AWS
SourceIdentifier: CFN_STACK_DRIFT_DETECTION_CHECK
Scope:
ComplianceResourceTypes:
- AWS::CloudFormation::Stack
undefinedResources:
CloudFormationStackDriftDetectionConfigRule:
Type: AWS::Config::ConfigRule
Properties:
ConfigRuleName: cf-drift-detection
Description: Detect CloudFormation stack drift
Source:
Owner: AWS
SourceIdentifier: CFN_STACK_DRIFT_DETECTION_CHECK
Scope:
ComplianceResourceTypes:
- AWS::CloudFormation::Stack
undefinedChange Sets
变更集
Change Sets provide a preview of stack changes before execution. Always use change sets for production deployments to review and validate modifications.
bash
undefined变更集可在执行前预览栈变更。在生产环境部署时,请始终使用变更集来审查和验证修改内容。
bash
undefined1. Create a change set (dry-run)
1. Create a change set (dry-run)
aws cloudformation create-change-set
--stack-name production-ecs
--template-body file://ecs-template.yaml
--change-set-name production-ecs-changeset
--capabilities CAPABILITY_IAM
--parameters ParameterKey=Environment,ParameterValue=production
--stack-name production-ecs
--template-body file://ecs-template.yaml
--change-set-name production-ecs-changeset
--capabilities CAPABILITY_IAM
--parameters ParameterKey=Environment,ParameterValue=production
aws cloudformation create-change-set
--stack-name production-ecs
--template-body file://ecs-template.yaml
--change-set-name production-ecs-changeset
--capabilities CAPABILITY_IAM
--parameters ParameterKey=Environment,ParameterValue=production
--stack-name production-ecs
--template-body file://ecs-template.yaml
--change-set-name production-ecs-changeset
--capabilities CAPABILITY_IAM
--parameters ParameterKey=Environment,ParameterValue=production
2. Wait for change set creation
2. Wait for change set creation
aws cloudformation wait change-set-create-complete
--stack-name production-ecs
--change-set-name production-ecs-changeset
--stack-name production-ecs
--change-set-name production-ecs-changeset
aws cloudformation wait change-set-create-complete
--stack-name production-ecs
--change-set-name production-ecs-changeset
--stack-name production-ecs
--change-set-name production-ecs-changeset
3. View change set (review changes)
3. View change set (review changes)
aws cloudformation describe-change-set
--stack-name production-ecs
--change-set-name production-ecs-changeset
--output table
--stack-name production-ecs
--change-set-name production-ecs-changeset
--output table
aws cloudformation describe-change-set
--stack-name production-ecs
--change-set-name production-ecs-changeset
--output table
--stack-name production-ecs
--change-set-name production-ecs-changeset
--output table
4. Execute change set (if changes are correct)
4. Execute change set (if changes are correct)
aws cloudformation execute-change-set
--stack-name production-ecs
--change-set-name production-ecs-changeset
--stack-name production-ecs
--change-set-name production-ecs-changeset
aws cloudformation execute-change-set
--stack-name production-ecs
--change-set-name production-ecs-changeset
--stack-name production-ecs
--change-set-name production-ecs-changeset
5. Delete change set (if not executing)
5. Delete change set (if not executing)
aws cloudformation delete-change-set
--stack-name production-ecs
--change-set-name production-ecs-changeset
--stack-name production-ecs
--change-set-name production-ecs-changeset
Change Set for nested stacks:
```bash
aws cloudformation create-change-set \
--stack-name parent-stack \
--template-body file://parent-template.yaml \
--change-set-name parent-changeset \
--nested-stack-resolution TEMPLATEaws cloudformation delete-change-set
--stack-name production-ecs
--change-set-name production-ecs-changeset
--stack-name production-ecs
--change-set-name production-ecs-changeset
嵌套栈的变更集:
```bash
aws cloudformation create-change-set \
--stack-name parent-stack \
--template-body file://parent-template.yaml \
--change-set-name parent-changeset \
--nested-stack-resolution TEMPLATEChange Set Template Review
变更集模板审查
When reviewing change sets, examine:
- Resource modifications: Changes to ECS services may cause service disruptions
- Deletions: Ensure no critical resources are marked for deletion
- IAM changes: New or modified roles require manual approval
- Parameter changes: Verify parameter overrides are correct
- Replace operations: Resources marked for replacement may cause downtime
审查变更集时,请检查以下内容:
- 资源修改:对ECS服务的修改可能导致服务中断
- 删除操作:确保没有关键资源被标记为删除
- IAM变更:新的或修改的角色需要手动审批
- 参数变更:验证参数覆盖是否正确
- 替换操作:被标记为替换的资源可能导致停机
Security Best Practices
安全最佳实践
Security
安全
- Use IAM roles with minimum required permissions (Task Execution Role, Task Role)
- Encrypt container images with ECR
- Use Secrets Manager for sensitive data (passwords, API keys)
- Configure security groups with restrictive rules
- Use private subnets for ECS services
- Enable Container Insights for monitoring
- Implement task execution role with specific permissions
- 使用具有最小必要权限的IAM角色(任务执行角色、任务角色)
- 使用ECR加密容器镜像
- 使用Secrets Manager存储敏感数据(密码、API密钥)
- 配置具有严格规则的安全组
- 为ECS服务使用私有子网
- 启用Container Insights进行监控
- 为任务执行角色配置特定权限
Security Group Best Practices
安全组最佳实践
For public-facing ALBs, HTTP/HTTPS from 0.0.0.0/0 is often necessary. However, enhance security with:
yaml
AlbSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: !Sub "${AWS::StackName}-alb-sg"
GroupDescription: ALB security group - restrict in production
VpcId: !Ref VpcId
SecurityGroupIngress:
# HTTP from anywhere - required for public ALB
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
Description: HTTP for public web traffic
# HTTPS from anywhere - required for public ALB
- IpProtocol: tcp
FromPort: 443
ToPort: 443
CidrIp: 0.0.0.0/0
Description: HTTPS for secure public web traffic对于面向公网的ALB,通常需要允许来自0.0.0.0/0的HTTP/HTTPS流量。但可通过以下方式增强安全性:
yaml
AlbSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: !Sub "${AWS::StackName}-alb-sg"
GroupDescription: ALB security group - restrict in production
VpcId: !Ref VpcId
SecurityGroupIngress:
# HTTP from anywhere - required for public ALB
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
Description: HTTP for public web traffic
# HTTPS from anywhere - required for public ALB
- IpProtocol: tcp
FromPort: 443
ToPort: 443
CidrIp: 0.0.0.0/0
Description: HTTPS for secure public web trafficSecurity enhancements for production:
Security enhancements for production:
1. Use AWS WAF to filter malicious traffic
1. Use AWS WAF to filter malicious traffic
2. Place ALB behind CloudFront for additional protection
2. Place ALB behind CloudFront for additional protection
3. Use AWS Shield for DDoS protection
3. Use AWS Shield for DDoS protection
4. Implement rate limiting
4. Implement rate limiting
5. Use AWS Network Firewall for advanced filtering
5. Use AWS Network Firewall for advanced filtering
undefinedundefinedPerformance
性能
- Choose CPU and memory based on container profiling
- Use right-sizing for EC2 instances or Fargate
- Implement auto scaling based on metrics (CPU, Memory, Request count)
- Optimize container startup with appropriate health checks
- Use task placement strategies for optimization
- Consider Spot instances for non-critical workloads
- 根据容器分析结果选择CPU和内存配置
- 为EC2实例或Fargate选择合适的规格
- 基于指标(CPU、内存、请求数)实现自动扩缩容
- 通过适当的健康检查优化容器启动
- 使用任务放置策略进行优化
- 对非关键工作负载考虑使用Spot实例
Monitoring
监控
- Enable Container Insights for detailed metrics
- Configure CloudWatch alarms for CPU, memory, and error rates
- Implement structured logging with awslogs driver
- Use X-Ray for distributed tracing
- Configure task-level monitoring
- 启用Container Insights获取详细指标
- 为CPU、内存和错误率配置CloudWatch告警
- 使用awslogs驱动实现结构化日志
- 使用X-Ray进行分布式追踪
- 配置任务级监控
Deployment
部署
- Use blue/green deployments with CodeDeploy for production
- Implement deployment circuit breaker
- Use change sets before deployment
- Organize stacks by lifecycle and ownership
- Test task definitions locally before deployment
- 为生产环境使用结合CodeDeploy的蓝绿部署
- 实现部署熔断机制
- 在部署前使用变更集
- 按生命周期和归属组织栈
- 在部署前在本地测试任务定义
Related Resources
相关资源
Additional Files
附加文件
For complete details on resources and their properties, see:
- REFERENCE.md - Detailed reference guide for all CloudFormation resources
- EXAMPLES.md - Complete production-ready examples
如需了解资源及其属性的完整详情,请查看:
- REFERENCE.md - 所有CloudFormation资源的详细参考指南
- EXAMPLES.md - 完整的生产环境可用示例