Cloudformation蓝色/绿色部署HealthCheckGracePeriodSeconds

时间:2020-11-12 14:28:01

标签: amazon-web-services amazon-cloudformation amazon-ecs aws-code-deploy

我正在尝试使用Cloudformation Codedeploy蓝色/绿色部署功能,因此需要一个如下所示的任务集。

TaskSet:
  Type: AWS::ECS::TaskSet
  Properties:
    Cluster: 
      Fn::ImportValue: !Sub "${ClusterStackName}-ClusterID"
    LaunchType: FARGATE
    NetworkConfiguration:
      AwsVpcConfiguration:
        AssignPublicIp: ENABLED
        SecurityGroups: 
          - !Ref FargateSecurityGroup
        Subnets: 
          - Fn::ImportValue: !Sub "${ClusterStackName}-SUBNET1ID"
          - Fn::ImportValue: !Sub "${ClusterStackName}-SUBNET2ID"
    PlatformVersion: 1.3.0
    Scale:
      Unit: PERCENT
      Value: 1
    Service: !Ref ECSService
    TaskDefinition: !Ref TaskDefinition
    LoadBalancers: 
      - ContainerName: !Ref ServiceName
        ContainerPort: !Ref ContainerPort
        TargetGroupArn: !Ref TargetGroup

我的ECS服务定义如下

ECSService:
  Type: AWS::ECS::Service
  DependsOn: HTTPSListener
  Properties: 
    ServiceName: !Sub "${ServiceName}-service"
    Cluster: 
      Fn::ImportValue: !Sub "${ClusterStackName}-ClusterID"
    DeploymentController: 
      Type: EXTERNAL
    DesiredCount: 4
    EnableECSManagedTags: true
    HealthCheckGracePeriodSeconds: 30
    SchedulingStrategy: REPLICA

这会导致Cloudformation中出现以下错误

Invalid request provided: CreateService error: Health check grace period is only valid for services configured to use load balancers 

但是省略HealthCheckGracePeriodSeconds会使我的任务在启动时无法通过运行状况检查。我已经检查了文档,似乎没有选择将HealthCheckGracePeriodSeconds添加到TaskSet的定义中。

如何在运行状况检查宽限期内将Cloudformation蓝色/绿色部署用于ECS?

完整示例

这是我希望可以使用的完整模板,但不能使用。

AWSTemplateFormatVersion: 2010-09-09
Parameters: 
  Image: 
    Type: String
  Vpc:
    Type: 'AWS::EC2::VPC::Id'
  Subnet1:
    Type: 'AWS::EC2::Subnet::Id'
  Subnet2:
    Type: 'AWS::EC2::Subnet::Id'

Transform:
  - AWS::CodeDeployBlueGreen

Hooks:
  CodeDeployBlueGreenHook:
    Type: AWS::CodeDeploy::BlueGreen
    Properties:
      TrafficRoutingConfig:
        Type: AllAtOnce
      Applications:
        - Target:
            Type: AWS::ECS::Service
            LogicalID: ECSService
          ECSAttributes:
            TaskDefinitions:
              - TaskDefinition
              - GreenTaskDefinition
            TaskSets:
              - TaskSet
              - GreenTaskSet
            TrafficRouting:
              ProdTrafficRoute:
                Type: AWS::ElasticLoadBalancingV2::Listener
                LogicalID: HTTPListener
              TargetGroups:
                - TargetGroup
                - TargetGroupGreen
    
Resources: 
  ALBSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Allow HTTP to load balancer
      VpcId: !Ref Vpc
      SecurityGroupIngress:
      - IpProtocol: tcp
        FromPort: 80
        ToPort: 80
        CidrIp: 0.0.0.0/0
      SecurityGroupEgress:
      - IpProtocol: -1
        CidrIp: 0.0.0.0/0

  FargateSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Allow port 80 to service
      VpcId: !Ref Vpc
      SecurityGroupIngress:
      - IpProtocol: tcp
        FromPort: 80
        ToPort: 80
        SourceSecurityGroupId: !Ref ALBSecurityGroup
      SecurityGroupEgress:
      - IpProtocol: -1
        CidrIp: 0.0.0.0/0

  LoadBalancer:
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
    Properties:
      Name: load-balancer
      Type: application
      IpAddressType: ipv4
      Scheme: internet-facing
      SecurityGroups: [!Ref ALBSecurityGroup]
      Subnets: [!Ref Subnet1, !Ref Subnet2]

  HTTPListener:
    Type: AWS::ElasticLoadBalancingV2::Listener
    Properties:
      DefaultActions:
        - TargetGroupArn: !Ref TargetGroup
          Type: forward
      LoadBalancerArn: !Ref LoadBalancer
      Port: 80
      Protocol: HTTP

  TargetGroup:
    Type: AWS::ElasticLoadBalancingV2::TargetGroup
    Properties:
      HealthCheckEnabled: true
      HealthCheckIntervalSeconds: 30
      HealthCheckPath: "/"
      HealthCheckTimeoutSeconds: 10
      HealthyThresholdCount: 5
      Name: targetgroup-blue
      Port: 80
      Protocol: HTTP
      TargetType: ip
      UnhealthyThresholdCount: 10
      VpcId: !Ref Vpc

  TargetGroupGreen:
    Type: AWS::ElasticLoadBalancingV2::TargetGroup
    Properties:
      HealthCheckEnabled: true
      HealthCheckIntervalSeconds: 30
      HealthCheckPath: "/"
      HealthCheckTimeoutSeconds: 10
      HealthyThresholdCount: 5
      Name: targetgroup-green
      Port: 80
      Protocol: HTTP
      TargetType: ip
      UnhealthyThresholdCount: 10
      VpcId: !Ref Vpc
      
  TaskDefinition:
    Type: AWS::ECS::TaskDefinition
    Properties:
      Family: "task-family-name"
      NetworkMode: awsvpc
      RequiresCompatibilities: [FARGATE]
      Cpu: 512
      Memory: 1024
      ContainerDefinitions:
        - Name: Container
          Essential: true
          Image: !Ref Image
          PortMappings:
            - ContainerPort: 80

  TaskSet:
    Type: AWS::ECS::TaskSet
    Properties:
      Cluster: !Ref ECSCluster
      LaunchType: FARGATE
      NetworkConfiguration:
        AwsVpcConfiguration:
          AssignPublicIp: ENABLED
          SecurityGroups: [!Ref FargateSecurityGroup]
          Subnets: [!Ref Subnet1, !Ref Subnet2]
      Scale:
        Unit: PERCENT
        Value: 100
      Service: !Ref ECSService
      TaskDefinition: !Ref TaskDefinition
      PlatformVersion: LATEST
      LoadBalancers: 
        - ContainerName: Container
          ContainerPort: 80
          TargetGroupArn: !Ref TargetGroup

  ECSService:
    Type: AWS::ECS::Service
    DependsOn: HTTPListener
    Properties: 
      ServiceName: "service"
      Cluster: !Ref ECSCluster
      DeploymentController: 
        Type: EXTERNAL
      DesiredCount: 4
      EnableECSManagedTags: true
      HealthCheckGracePeriodSeconds: 30
      SchedulingStrategy: REPLICA
    
  PrimaryTaskSet:
    Type: 'AWS::ECS::PrimaryTaskSet'
    Properties:
      Cluster: !Ref ECSCluster
      Service: !Ref ECSService
      TaskSetId: !GetAtt 'TaskSet.Id'

  ECSCluster:
    Type: AWS::ECS::Cluster
    Properties:
      ClusterName: Cluster
      CapacityProviders:
        - FARGATE
      DefaultCapacityProviderStrategy:
        - CapacityProvider: FARGATE
          Weight: 1

1 个答案:

答案 0 :(得分:0)

该错误是正确的,Service级的运行状况检查将需要Load Balancer。但是,您可以在任务级别定义运行状况检查:

  EscTaskDef:
    Type: 'AWS::ECS::TaskDefinition'
    Properties:
...
      ContainerDefinitions:
        - Name: !Ref AWS::StackName
          Image: !Ref Image
          PortMappings:
            - ContainerPort: 80

          HealthCheck:
            Command: [ "CMD-SHELL", "curl -f http://localhost:80/api/healthcheck/ping || exit 1" ]
            StartPeriod: 200

Here是使用带有Cloudformation的这种类型的运行状况检查的回滚示例的示例。