使用CLI发起CodeDeploy部署新的ECS版本

注:本实验针对已经在CodeDeploy图形界面上进行过部署的场景,因此CodeDeploy的Application、Deployment Group、Deployment configurations均为已经配置好的状态。本脚本目标是让整个流程通过CLI自动运行。

一、安装AWSCLI并配置Access Key为管理员权限

略。

二、构建版本文件Appspec.yml

1、查询ECS Task定义

执行如下命令。

aws ecs list-task-definitions

输出结果如下:

{
    "taskDefinitionArns": [
        "arn:aws-cn:ecs:cn-north-1:420029960748:task-definition/myphpdemo:1",
        "arn:aws-cn:ecs:cn-north-1:420029960748:task-definition/myphpdemo:2"
    ]
}

以上返回结果可以看到有2个任务定义,假设1是当前运行版本,2是要发布的新版本。复制下来版本2对应的整个ARN,后续查询会使用。

2、查询ContainerName

执行如下命令,将最后的ARN替换为上一步查询出来的ARN。

aws ecs describe-task-definition --task-definition arn:aws-cn:ecs:cn-north-1:420029960748:task-definition/myphpdemo:1 | jq -r '.taskDefinition.containerDefinitions[].name'

这个查询结果将返回ContainerName。

例如返回:

phpdocker

即可获得ContainerName。

3、构建appspec.yml文件

构建内容如下。请替换TaskDefinition、ContainerName为前两个步骤查询获得的结果。

version: 0.0
Resources:
  - TargetService:
      Type: AWS::ECS::Service
      Properties:
        TaskDefinition: "arn:aws-cn:ecs:cn-north-1:420029960748:task-definition/myphpdemo:2"
        LoadBalancerInfo:
          ContainerName: "phpdocker"
          ContainerPort: 80

将以上内容保存为appspec.yml,放在本地目录下。

将此文件上传到S3存储桶。注意S3存储桶必须与ECS和CodeDeploy在同一个区域。如果之前没有通过图形界面操作过CodeDeploy,那么需要全新创建一个S3存储桶。如果之前使用过图形界面的CodeDeploy,那么存储桶就继续使用相同的即可。

执行以下命令将配置文件复制到云上。

aws s3 cp appspec.yml s3://codedeploy-ecs-demo-bjs/

复制成功。

三、创建部署配置文件

1、查询applicationName

执行如下命令。

aws deploy list-applications

返回结果。

{
    "applications": [
        "AppECS-myecs-phpdocker"
    ]
}

其中AppECS-myecs-phpdocker就是applicationName。记录下来,后续命令还要使用。

2、查询deploymentGroupName

执行如下命令。请替换其中的applicationName为上一步查询出来的名字。

aws deploy list-deployment-groups --application-name AppECS-myecs-phpdocker

返回结果如下。

{
    "deploymentGroups": [
        "DgpECS-myecs-phpdocker"
    ]
}

其中的DgpECS-myecs-phpdocker就是deploymentGroups。记录下来,后续步骤将要使用。

3、查询deploymentConfigurations

执行如下命令。

aws deploy list-deployment-configs

返回结果如下。

{
    "deploymentConfigsList": [
        "2mins-half",
        "CodeDeployDefault.LambdaCanary10Percent30Minutes",
        "CodeDeployDefault.OneAtATime",
        "CodeDeployDefault.LambdaCanary10Percent10Minutes",
        "CodeDeployDefault.AllAtOnce",
        "CodeDeployDefault.LambdaLinear10PercentEvery10Minutes",
        "CodeDeployDefault.LambdaCanary10Percent15Minutes",
        "CodeDeployDefault.ECSCanary10Percent15Minutes",
        "CodeDeployDefault.ECSLinear10PercentEvery1Minutes",
        "CodeDeployDefault.ECSLinear10PercentEvery3Minutes",
        "CodeDeployDefault.ECSCanary10Percent5Minutes",
        "CodeDeployDefault.LambdaAllAtOnce",
        "CodeDeployDefault.LambdaLinear10PercentEvery2Minutes",
        "CodeDeployDefault.LambdaLinear10PercentEvery3Minutes",
        "CodeDeployDefault.LambdaLinear10PercentEvery1Minute",
        "CodeDeployDefault.ECSAllAtOnce",
        "CodeDeployDefault.HalfAtATime",
        "CodeDeployDefault.LambdaCanary10Percent5Minutes"
    ]
}

在以上返回结果中,名为2mins-half的是我们在图形界面的CodeDeploy实验中手工创建的,后续将使用这个作为部署配置。

4、构建部署配置文件

构建以下配置文件,将其中的配置参数都替换为上文查询获得的参数。

{
    "applicationName": "AppECS-myecs-phpdocker",
    "deploymentGroupName": "DgpECS-myecs-phpdocker",
    "deploymentConfigName": "2mins-half",
    "revision": {
        "revisionType": "S3",
        "s3Location": {
            "bucket": "codedeploy-ecs-demo-bjs",
            "key": "appspec.yml",
            "bundleType": "YAML"
        }
    }
}

将配置文件保存为执行CLI的本地,文件名叫做create-deployment.json

四、从CLI发起部署操作

1、发起部署

create-deployment.json文件所在的路径下,执行如下命令发起部署。

aws deploy create-deployment \
     --cli-input-json file://create-deployment.json

控制台返回结果如下。

{
    "deploymentId": "d-VBPR9D3D7"
}

请记住这个部署ID。

2、查看进度

执行如下命令,查询部署对应的目标。

aws deploy list-deployment-targets --deployment-id d-VBPR9D3D7

返回结果如下。

{
    "targetIds": [
        "myecs:phpdocker"
    ]
}

这里返回的就是targetId,请记录下来。

将上文的部署命令代入如下命令,发起进度查询。

aws deploy get-deployment-target \
     --deployment-id d-VBPR9D3D7 \
     --target-id myecs:phpdocker

返回结果如下。

{
    "deploymentTarget": {
        "deploymentTargetType": "ECSTarget",
        "ecsTarget": {
            "deploymentId": "d-VBPR9D3D7",
            "targetId": "myecs:phpdocker",
            "targetArn": "arn:aws-cn:ecs:cn-north-1:420029960748:service/myecs/phpdocker",
            "lastUpdatedAt": "2021-02-07T17:57:03.520000+08:00",
            "lifecycleEvents": [
                {
                    "lifecycleEventName": "BeforeInstall",
                    "startTime": "2021-02-07T17:56:00.845000+08:00",
                    "endTime": "2021-02-07T17:56:01.215000+08:00",
                    "status": "Succeeded"
                },
                {
                    "lifecycleEventName": "Install",
                    "startTime": "2021-02-07T17:56:01.409000+08:00",
                    "status": "InProgress"
                },
                {
                    "lifecycleEventName": "AfterInstall",
                    "status": "Pending"
                },
                {
                    "lifecycleEventName": "BeforeAllowTraffic",
                    "status": "Pending"
                },
                {
                    "lifecycleEventName": "AllowTraffic",
                    "status": "Pending"
                },
                {
                    "lifecycleEventName": "AfterAllowTraffic",
                    "status": "Pending"
                }
            ],
            "status": "InProgress",
            "taskSetsInfo": [
:

通过查看以上各阶段的进度,即可看到部署状态。也可以通过图形界面的CodeDeploy控制台看到状态。

五、自动发布

如果希望保留历史版本,那么每次发布需要修改的文件:

  • ECS任务定义中的容器名称
  • S3上的appspec.yml中调用的task名称

除此以外,其他配置文件不需要修改,直接运行CLI发起任务即可。

如果不需要保存历史版本,则可以在容器名称上使用latest标签,每次都发布最新版本。

将以上过程CLI脚本话,或者使用python通过boto3库调用API,通过Lambda执行,即可完成自动发布的全过程。