AWS CloudFormation 无法使用 CodeDeploy blue/green 部署创建 Stack
AWS CloudFormation cannot create Stack using CodeDeploy blue/green deployments
我正在尝试使用 CloudFormation 和 ECS 服务部署新堆栈,使用 CodeDeploy 启动类型启用 blue/green 部署。
在通过 CloudFormation 执行 blue/green 部署的 User Guide 中,他们声明如下:
To enable CloudFormation to perform blue/green deployments on a Stack, include the following information in its stack template:
At least one of the ECS resources that will trigger a blue/green deployment if replaced during a stack update. Currently, those resources are AWS::ECS::TaskDefinition and AWS::ECS::TaskSet.
当我排除 AWS::ECS::TaskSet
时,堆栈创建失败并且我收到以下错误:
Transform AWS::CodeDeployBlueGreen failed with: Failed to transform template.
ECSAttributes must include TaskSets in AWS::CodeDeploy::BlueGreen Hook
如果我添加 AWS::ECS::TaskSet
,堆栈将无法创建并出现以下错误:
Resource handler returned message:
"Invalid request provided: Amazon ECS does not support task set management on services where deployments
are controlled by AWS CodeDeploy.
(Service: AmazonECS; Status Code: 400; Error Code: InvalidParameterException;
Request ID: 61b8c146-3ae9-4bc2-ac5c-08a11e194f06; Proxy: null)"
(RequestToken: 86a8a3a5-fe89-9939-15c2-45b08b28c3f3, HandlerErrorCode: InvalidRequest)
这些是我的堆栈模板的相关部分:
Transform:
- AWS::CodeDeployBlueGreen
Hooks:
CodeDeployBlueGreenHook:
Type: AWS::CodeDeploy::BlueGreen
Properties:
ServiceRole: BlueGreenDeploymentRole
Applications:
- Target:
Type: AWS::ECS::Service
LogicalID: EcsService
ECSAttributes:
TaskDefinitions:
- TaskDefinitionBlue
- TaskDefinitionGreen
TaskSets:
- TaskSetBlue
- TaskSetGreen
TrafficRouting:
ProdTrafficRoute:
Type: AWS::ElasticLoadBalancingV2::Listener
LogicalID: LoadBalancerListener
TargetGroups:
- TargetGroupBlue
- TargetGroupGreen
TrafficRoutingConfig:
Type: TimeBasedLinear
TimeBasedLinear:
StepPercentage: 20
BakeTimeMins: 10
AdditionalOptions:
TerminationWaitTimeInMinutes: 60
Resources:
# IAM Role for blue/green deployments
BlueGreenDeploymentRole:
Type: AWS::IAM::Role
Properties:
RoleName: blue-green-deployment-role
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Principal:
Service: codedeploy.amazonaws.com
Action: sts:AssumeRole
Policies:
- PolicyName: BlueGreenDeploymentPolicy
PolicyDocument:
Statement:
- Effect: Allow
Action:
- codedeploy:Get*
- codedeploy:CreateCloudFormationDeployment
Resource: '*'
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AWSCodeDeployRoleForECS
#########################
# Load Balancer
#########################
# Application Load Balancer
LoadBalancer:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
IpAddressType: ipv4
Name: service-alb
Scheme: internal
Subnets:
- !Ref SubnetOne
- !Ref SubnetTwo
SecurityGroups:
- !Ref SecurityGroup
# Load Balancer Listener
LoadBalancerListener:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
DefaultActions:
- Type: forward
ForwardConfig:
TargetGroups:
- TargetGroupArn: !Ref TargetGroupBlue
Weight: 1
- TargetGroupArn: !Ref TargetGroupGreen
Weight: 1
LoadBalancerArn: !Ref LoadBalancer
Port: 8080
Protocol: HTTP
# Load Balancer Target Groups
TargetGroupBlue:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
Name: !Sub ${ServiceName}-blue
TargetType: ip
VpcId: !Ref Vpc
Port: 8080
Protocol: HTTP
HealthCheckPort: 8080
HealthCheckPath: /actuator/health
TargetGroupGreen:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
Name: !Sub ${ServiceName}-green
TargetType: ip
VpcId: !Ref Vpc
Port: 8080
Protocol: HTTP
HealthCheckPort: 8080
HealthCheckPath: /actuator/health
#########################
# ECS
#########################
# ECS Cluster
Cluster:
Type: AWS::ECS::Cluster
Properties:
ClusterName: !Ref ServiceName
# ECS Service
EcsService:
Type: AWS::ECS::Service
DependsOn: LoadBalancerListener
Properties:
ServiceName: !Ref ServiceName
Cluster: !Ref Cluster
TaskDefinition: !Ref TaskDefinitionBlue
DeploymentController:
Type: CODE_DEPLOY
DesiredCount: 0
LaunchType: FARGATE
LoadBalancers:
- ContainerName: !Sub ${ServiceName}-container
ContainerPort: 8080
TargetGroupArn: !Ref TargetGroupBlue
- ContainerName: !Sub ${ServiceName}-container
ContainerPort: 8080
TargetGroupArn: !Ref TargetGroupGreen
NetworkConfiguration:
AwsvpcConfiguration:
Subnets:
- !Ref SubnetOne
- !Ref SubnetTwo
SecurityGroups:
- !Ref SecurityGroup
SchedulingStrategy: REPLICA
# Task Definitions
TaskDefinitionBlue:
Type: AWS::ECS::TaskDefinition
Properties:
ContainerDefinitions:
- Name: !Sub ${ServiceName}-container
Image: !Sub ${ImageRepository.RepositoryUri}:latest
LogConfiguration:
LogDriver: awslogs
Options:
awslogs-group: !Ref LogGroup
awslogs-region: !Ref AWS::Region
awslogs-stream-prefix: payments
PortMappings:
- ContainerPort: 8080
Cpu: 256
Memory: 512
NetworkMode: awsvpc
Family: !Sub ${ServiceName}
ExecutionRoleArn: !Ref TaskExecutionRole
RequiresCompatibilities:
- FARGATE
TaskDefinitionGreen:
Type: AWS::ECS::TaskDefinition
Properties:
ContainerDefinitions:
- Name: !Sub ${ServiceName}-container
Image: !Sub ${ImageRepository.RepositoryUri}:latest
LogConfiguration:
LogDriver: awslogs
Options:
awslogs-group: !Ref LogGroup
awslogs-region: !Ref AWS::Region
awslogs-stream-prefix: payments
PortMappings:
- ContainerPort: 8080
Cpu: 256
Memory: 512
NetworkMode: awsvpc
Family: !Sub ${ServiceName}
ExecutionRoleArn: !Ref TaskExecutionRole
RequiresCompatibilities:
- FARGATE
# Image Repository
ImageRepository:
Type: AWS::ECR::Repository
Properties:
RepositoryName: !Sub ${ServiceName}
LifecyclePolicy:
LifecyclePolicyText: |
{
"rules": [
{
"rulePriority": 1,
"description": "Maintain at most 25 images",
"selection": {
"tagStatus": "untagged",
"countType": "imageCountMoreThan",
"countNumber": 25
},
"action": {
"type": "expire"
}
}
]
}
TaskSetBlue:
Type: AWS::ECS::TaskSet
Properties:
Cluster: !Ref Cluster
LaunchType: FARGATE
Service: !Ref EcsService
TaskDefinition: !Ref TaskDefinitionBlue
NetworkConfiguration:
AwsVpcConfiguration:
Subnets:
- !Ref SubnetOne
- !Ref SubnetTwo
SecurityGroups:
- !Ref SecurityGroup
LoadBalancers:
- ContainerName: !Sub ${ServiceName}-container
ContainerPort: 8080
TargetGroupArn: !Ref TargetGroupBlue
如何更新我的模板以允许通过 CodeDeploy blue/green 部署策略?
G/B 使用 CFN 的部署是 EXTERNAL
,不是 CODE_DEPLOY
。您的模板可能还有许多其他问题,但您当前的错误与使用错误 DeploymentController
有关。请研究 AWS 文档和示例:
确切地说,AWS 不支持 EC2/ASG 上的蓝绿部署...!
我刚刚发现的最简单的方法是使用 In-Place 方法创建部署组 && 然后手动将部署组配置从 In-place 更改为 Blue Green
或者您可以使用 lambda 函数,但自定义它有点困难
希望这对你有所帮助
我正在尝试使用 CloudFormation 和 ECS 服务部署新堆栈,使用 CodeDeploy 启动类型启用 blue/green 部署。
在通过 CloudFormation 执行 blue/green 部署的 User Guide 中,他们声明如下:
To enable CloudFormation to perform blue/green deployments on a Stack, include the following information in its stack template:
At least one of the ECS resources that will trigger a blue/green deployment if replaced during a stack update. Currently, those resources are AWS::ECS::TaskDefinition and AWS::ECS::TaskSet.
当我排除 AWS::ECS::TaskSet
时,堆栈创建失败并且我收到以下错误:
Transform AWS::CodeDeployBlueGreen failed with: Failed to transform template.
ECSAttributes must include TaskSets in AWS::CodeDeploy::BlueGreen Hook
如果我添加 AWS::ECS::TaskSet
,堆栈将无法创建并出现以下错误:
Resource handler returned message:
"Invalid request provided: Amazon ECS does not support task set management on services where deployments
are controlled by AWS CodeDeploy.
(Service: AmazonECS; Status Code: 400; Error Code: InvalidParameterException;
Request ID: 61b8c146-3ae9-4bc2-ac5c-08a11e194f06; Proxy: null)"
(RequestToken: 86a8a3a5-fe89-9939-15c2-45b08b28c3f3, HandlerErrorCode: InvalidRequest)
这些是我的堆栈模板的相关部分:
Transform:
- AWS::CodeDeployBlueGreen
Hooks:
CodeDeployBlueGreenHook:
Type: AWS::CodeDeploy::BlueGreen
Properties:
ServiceRole: BlueGreenDeploymentRole
Applications:
- Target:
Type: AWS::ECS::Service
LogicalID: EcsService
ECSAttributes:
TaskDefinitions:
- TaskDefinitionBlue
- TaskDefinitionGreen
TaskSets:
- TaskSetBlue
- TaskSetGreen
TrafficRouting:
ProdTrafficRoute:
Type: AWS::ElasticLoadBalancingV2::Listener
LogicalID: LoadBalancerListener
TargetGroups:
- TargetGroupBlue
- TargetGroupGreen
TrafficRoutingConfig:
Type: TimeBasedLinear
TimeBasedLinear:
StepPercentage: 20
BakeTimeMins: 10
AdditionalOptions:
TerminationWaitTimeInMinutes: 60
Resources:
# IAM Role for blue/green deployments
BlueGreenDeploymentRole:
Type: AWS::IAM::Role
Properties:
RoleName: blue-green-deployment-role
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Principal:
Service: codedeploy.amazonaws.com
Action: sts:AssumeRole
Policies:
- PolicyName: BlueGreenDeploymentPolicy
PolicyDocument:
Statement:
- Effect: Allow
Action:
- codedeploy:Get*
- codedeploy:CreateCloudFormationDeployment
Resource: '*'
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AWSCodeDeployRoleForECS
#########################
# Load Balancer
#########################
# Application Load Balancer
LoadBalancer:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
IpAddressType: ipv4
Name: service-alb
Scheme: internal
Subnets:
- !Ref SubnetOne
- !Ref SubnetTwo
SecurityGroups:
- !Ref SecurityGroup
# Load Balancer Listener
LoadBalancerListener:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
DefaultActions:
- Type: forward
ForwardConfig:
TargetGroups:
- TargetGroupArn: !Ref TargetGroupBlue
Weight: 1
- TargetGroupArn: !Ref TargetGroupGreen
Weight: 1
LoadBalancerArn: !Ref LoadBalancer
Port: 8080
Protocol: HTTP
# Load Balancer Target Groups
TargetGroupBlue:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
Name: !Sub ${ServiceName}-blue
TargetType: ip
VpcId: !Ref Vpc
Port: 8080
Protocol: HTTP
HealthCheckPort: 8080
HealthCheckPath: /actuator/health
TargetGroupGreen:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
Name: !Sub ${ServiceName}-green
TargetType: ip
VpcId: !Ref Vpc
Port: 8080
Protocol: HTTP
HealthCheckPort: 8080
HealthCheckPath: /actuator/health
#########################
# ECS
#########################
# ECS Cluster
Cluster:
Type: AWS::ECS::Cluster
Properties:
ClusterName: !Ref ServiceName
# ECS Service
EcsService:
Type: AWS::ECS::Service
DependsOn: LoadBalancerListener
Properties:
ServiceName: !Ref ServiceName
Cluster: !Ref Cluster
TaskDefinition: !Ref TaskDefinitionBlue
DeploymentController:
Type: CODE_DEPLOY
DesiredCount: 0
LaunchType: FARGATE
LoadBalancers:
- ContainerName: !Sub ${ServiceName}-container
ContainerPort: 8080
TargetGroupArn: !Ref TargetGroupBlue
- ContainerName: !Sub ${ServiceName}-container
ContainerPort: 8080
TargetGroupArn: !Ref TargetGroupGreen
NetworkConfiguration:
AwsvpcConfiguration:
Subnets:
- !Ref SubnetOne
- !Ref SubnetTwo
SecurityGroups:
- !Ref SecurityGroup
SchedulingStrategy: REPLICA
# Task Definitions
TaskDefinitionBlue:
Type: AWS::ECS::TaskDefinition
Properties:
ContainerDefinitions:
- Name: !Sub ${ServiceName}-container
Image: !Sub ${ImageRepository.RepositoryUri}:latest
LogConfiguration:
LogDriver: awslogs
Options:
awslogs-group: !Ref LogGroup
awslogs-region: !Ref AWS::Region
awslogs-stream-prefix: payments
PortMappings:
- ContainerPort: 8080
Cpu: 256
Memory: 512
NetworkMode: awsvpc
Family: !Sub ${ServiceName}
ExecutionRoleArn: !Ref TaskExecutionRole
RequiresCompatibilities:
- FARGATE
TaskDefinitionGreen:
Type: AWS::ECS::TaskDefinition
Properties:
ContainerDefinitions:
- Name: !Sub ${ServiceName}-container
Image: !Sub ${ImageRepository.RepositoryUri}:latest
LogConfiguration:
LogDriver: awslogs
Options:
awslogs-group: !Ref LogGroup
awslogs-region: !Ref AWS::Region
awslogs-stream-prefix: payments
PortMappings:
- ContainerPort: 8080
Cpu: 256
Memory: 512
NetworkMode: awsvpc
Family: !Sub ${ServiceName}
ExecutionRoleArn: !Ref TaskExecutionRole
RequiresCompatibilities:
- FARGATE
# Image Repository
ImageRepository:
Type: AWS::ECR::Repository
Properties:
RepositoryName: !Sub ${ServiceName}
LifecyclePolicy:
LifecyclePolicyText: |
{
"rules": [
{
"rulePriority": 1,
"description": "Maintain at most 25 images",
"selection": {
"tagStatus": "untagged",
"countType": "imageCountMoreThan",
"countNumber": 25
},
"action": {
"type": "expire"
}
}
]
}
TaskSetBlue:
Type: AWS::ECS::TaskSet
Properties:
Cluster: !Ref Cluster
LaunchType: FARGATE
Service: !Ref EcsService
TaskDefinition: !Ref TaskDefinitionBlue
NetworkConfiguration:
AwsVpcConfiguration:
Subnets:
- !Ref SubnetOne
- !Ref SubnetTwo
SecurityGroups:
- !Ref SecurityGroup
LoadBalancers:
- ContainerName: !Sub ${ServiceName}-container
ContainerPort: 8080
TargetGroupArn: !Ref TargetGroupBlue
如何更新我的模板以允许通过 CodeDeploy blue/green 部署策略?
G/B 使用 CFN 的部署是 EXTERNAL
,不是 CODE_DEPLOY
。您的模板可能还有许多其他问题,但您当前的错误与使用错误 DeploymentController
有关。请研究 AWS 文档和示例:
确切地说,AWS 不支持 EC2/ASG 上的蓝绿部署...! 我刚刚发现的最简单的方法是使用 In-Place 方法创建部署组 && 然后手动将部署组配置从 In-place 更改为 Blue Green
或者您可以使用 lambda 函数,但自定义它有点困难
希望这对你有所帮助