【问题标题】:Creating blue green deployment in Cloud Formation (One Load Balancer 2 target groups在 Cloud Formation 中创建蓝绿色部署(一个负载均衡器 2 个目标组
【发布时间】:2020-08-13 08:51:21
【问题描述】:

我正在尝试为应用程序创建一个 cloudformation IaC 以进行蓝绿色部署。它一直给我The target group with targetGroupArn arn:aws:elasticloadbalancing:ap-xxx-9:000:targetgroup/master-tg-2 does not have an associated load balancer

我想知道我哪里出错了。正如question 中所述,我添加了一个DependsOn masterLB 侦听器。我还在 MasterECSServices 中链接了两个目标组

以下是cloudformation模板

  MasterLBSG:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Access to the public facing load balancer
      VpcId:
        Fn::ImportValue: # TAS-dev:VPCId
          !Sub "${TasStackName}:VPCId"
      SecurityGroupIngress:
        - CidrIp: 0.0.0.0/0
          IpProtocol: tcp
          FromPort: 8000
          ToPort: 8000
  MasterLB:
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
    Properties:
      Name: Master-Dev-LB
      Scheme: internet-facing
      LoadBalancerAttributes:
      - Key: idle_timeout.timeout_seconds
        Value: '30'
      Subnets:
        - !Sub "${StackName}:PublicSubnetOne"
        - !Sub "${StackName}:PublicSubnetTwo"
      SecurityGroups: [!Ref 'MasterLBSG']
  MasterLBListener:
    Type: AWS::ElasticLoadBalancingV2::Listener
    DependsOn:
      - MasterLB
    Properties:
      DefaultActions:
        - TargetGroupArn: !Ref 'MasterTGOne'
          Type: 'forward'
      LoadBalancerArn: !Ref 'MasterLB'
      Port: 8000
      Protocol: HTTP
  MasterTGOne: # Means MasterTargetGroupOne
    Type: AWS::ElasticLoadBalancingV2::TargetGroup
    Properties:
      Name: master-tg-1
      Port: 8000
      Protocol: HTTP
      VpcId:"${TasStackName}:VPCId"
      TargetType: ip

  ## to be used as a spare TargetGroup for blue green deployment
  MasterTGTwo: # Means MasterTargetGroupOne
    Type: AWS::ElasticLoadBalancingV2::TargetGroup
    Properties:
      Name: master-tg-2
      Port: 8000
      Protocol: HTTP
      VpcId:"${TasStackName}:VPCId"
      TargetType: ip
  MasterECSServices:
    Type: AWS::ECS::Service
    DependsOn:
      - MasterLBListener
    Properties:
      Cluster:"${TasStackName}:ClusterName"
      DeploymentController:
        Type: CODE_DEPLOY
      DesiredCount: 1
      LaunchType: FARGATE
      LoadBalancers:
        - ContainerName: master-app
          ContainerPort: '8000'
          TargetGroupArn: !Ref 'MasterTGOne'
        - ContainerName: master-app
          ContainerPort: '8000'
          TargetGroupArn: !Ref 'MasterTGTwo'
      NetworkConfiguration:
        AwsvpcConfiguration:
          SecurityGroups:
            - !Ref MasterAppSG
          Subnets:
            - "${TasStackName}:PrivateSubnetOne"
            - "${TasStackName}:PrivateSubnetTwo"
      Role:"${TasStackName}:ECSRole"
      TaskDefinition: !Ref 'MasterTaskDef'

【问题讨论】:

  • 您的服务中应该只有一个 LoadBalancers: 的 LB。
  • 看起来 cloudformation 在 lambda 上只支持 ECS 蓝绿色 docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/…
  • 是的,但是您可以通过创建自定义资源来解决它,这将创建蓝/绿部署。
  • 什么意思?你能更清楚吗? @Marcin
  • 有什么例子吗?根据您给定的链接,我仍然无法弄清楚。

标签: amazon-cloudformation


【解决方案1】:

更新:

自 2020 年 5 月 19 日起AWS CloudFormation now supports blue/green deployments for Amazon ECS


之前

CloudFormation 中的 custom resource 示例,它为 ECS 进行蓝/绿部署。它使用crhelper

为 ECS 创建蓝/绿部署组的 Lambda(即您的自定义资源的逻辑)

import logging
import json
import boto3

from time import sleep

from crhelper import CfnResource


logger = logging.getLogger(__name__)

# Initialise the helper, all inputs are optional, 
# this example shows the defaults
helper = CfnResource(json_logging=False, 
                     log_level='DEBUG', 
                     boto_level='CRITICAL', 
                     sleep_on_delete=120)

try:
    ## Init code goes here
    cd = boto3.client('codedeploy')
    pass
except Exception as e:
    helper.init_failure(e)


@helper.create
def create(event, context):
    logger.info("Got Create")

    print(json.dumps(event))

    application_name = event['ResourceProperties']['ApplicationName']
    service_role_arn = event['ResourceProperties']['ServiceRoleArn']

    cluster_name = event['ResourceProperties']['ClusterName']
    service_name = event['ResourceProperties']['ServiceName']
    elb_name = event['ResourceProperties']['ELBName']
    tg1_name = event['ResourceProperties']['TG1Name']
    tg2_name = event['ResourceProperties']['TG2Name']    
    listener_arn = event['ResourceProperties']['ListenerArn']

    deployment_group_name = event['ResourceProperties']['GroupName']

    deployment_style=event['ResourceProperties'].get(
                              'DeploymentStyle', 'BLUE_GREEN')

    response = cd.create_deployment_group(
                    applicationName=application_name,
                    deploymentGroupName=deployment_group_name,
                    serviceRoleArn=service_role_arn,
                    autoRollbackConfiguration={
                        'enabled': True,
                        'events': ['DEPLOYMENT_FAILURE']
                    },
                    deploymentStyle={
                        'deploymentType': deployment_style,
                        'deploymentOption': 'WITH_TRAFFIC_CONTROL'
                    },
                    blueGreenDeploymentConfiguration={
                        "terminateBlueInstancesOnDeploymentSuccess": {
                            "action": "TERMINATE",
                            "terminationWaitTimeInMinutes": 0
                        },
                        "deploymentReadyOption": {
                            "actionOnTimeout": "CONTINUE_DEPLOYMENT",
                            "waitTimeInMinutes": 0
                        }
                    },      
                    loadBalancerInfo={
                        "targetGroupPairInfoList": [
                          {
                            "targetGroups": [
                                {"name": tg1_name},
                                {"name": tg2_name}
                            ],
                            "prodTrafficRoute": {
                                "listenerArns": [listener_arn]
                            }
                          }
                        ]                       
                    },
                    ecsServices=[
                        {
                          "serviceName": service_name,
                          "clusterName": cluster_name
                        }
                    ]      
                )


    print(response)

    helper.Data.update({"Name": deployment_group_name})

    cd_group_id = response['deploymentGroupId']        

    return cd_group_id  


@helper.delete
def delete(event, context):    
    # Delete never returns anything. Should not fail if the 
    # underlying resources are already deleted.
    # Desired state.  
    logger.info("Got Delete")    

    print(json.dumps(event))

    try:

      application_name = event['ResourceProperties']['ApplicationName']
      deployment_group_name = event['ResourceProperties']['GroupName']

      response = cd.delete_deployment_group(
        applicationName=application_name,
        deploymentGroupName=deployment_group_name
      )

      print(response)

    except Exception as e:
      print(str(e))



def handler(event, context):
    helper(event, context)

从 CloudFomration 执行 lambda

设置好 lambda 后,您可以在 CloudFormation 中将其用作任何其他“普通”资源:

  MyUseCustomLambda:
    Type: Custom::CodeDeployCustomGroup
    Version: "1.0"
    Properties:
      Name: UseCustomLambda
      ServiceToken: !Ref CustomLambdaArn      
      ApplicationName: !Ref ApplicationName         
      ServiceRoleArn: !Ref ServiceRoleArn     
      ELBName: !Ref ELBName         
      TG1Name: !Ref TG1Name
      TG2Name: !Ref TG2Name
      GroupName: !Ref GroupName
      ClusterName: !Ref ClusterName         
      ServiceName: !Ref ServiceName
      ListenerArn: !Ref ListenerArn      
      DeploymentStyle: !Ref DeploymentStyle

【讨论】:

  • GroupName 指的是什么?安全组? @Marcin
  • @MosesLiaoGZ 它的deployment_group_name
  • @MosesLiaoGZ 它是一个自定义资源。您可以预先定义它的功能、它创建的资源、它期望创建的资源。我只是提供了一个例子。在此示例中,CodeDeploy 应用程序是预先创建的,并使用 ApplicationName 参数作为参数传递给自定义资源。
  • 我仍然遇到问题。 ECS 部署控制器我应该将其设置为 ECS 还是外部?
  • @MosesLiaoGZ CODE_DEPLOY.在蓝色/绿色上查看ecs tutorial
猜你喜欢
  • 2020-11-21
  • 1970-01-01
  • 1970-01-01
  • 2020-07-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-29
相关资源
最近更新 更多