AWS CICD Step Function 下篇  邮件审批_资源下载



简介


在“AWS CICD 之 CodeCommit/Build/Deploy 下篇”文章中,我们利用 Lamdba 函数,把 Code Commit/Build/Deploy 连接起来,形成一个完整的 CICD 流水线。

图 52AWS CICD Step Function 下篇  邮件审批_elastic_02

在“AWS CICD Step Function 上篇 邮件审批”文章中,我们介绍了如何用 Step Funcion 实现邮件审批。

图 28AWS CICD Step Function 下篇  邮件审批_elastic_03

本文中,我们把 Step Function 加入 CICD 流水线,实现带邮件审批的 CICD 部署流水线,如下图。

图 1AWS CICD Step Function 下篇  邮件审批_资源下载_04

目录

- 环境(配置)

- 实战步骤

  1. 创建 Cloudwatch rule

     - 新建 IAM Role

     - 新建 Rule/Trigger

  2. 修改 Step Function

     - 增加调用 Lambda 权限

     - 修改 Step Function 定义

  3. 测试带邮件审批的 CICD 流程

- 总结

- 引申

- 资源下载

- 后记

环境(配置)


  • AWS 中国或 Global 帐号,可在官网申请,一年内使用指定资源免费
  • AWS cli,Win10 + terminal
  • 公网邮箱

实战步骤

1. 创建 Cloudwatch rule

我们将新建一个 Cloudwatch Rule。当 Codebuild 成功完成时,通过 Rule 触发 Step Function 的审批邮件功能。

新建 IAM Role

首先,我们建一个 IAM Role,这个 Role 赋予 Cloudwatch event 运行 Step Function 的权限。

在 IAM 界面选择“Roles”,点击“Create role”

图 10-13AWS CICD Step Function 下篇  邮件审批_资源下载_05

依次选择“AWS Service”,“Elastic Container Service”,“Elastic Container Service Task”后,点击“Next:Permissions”

注意:我们的 Role 是给 events 用的,即 trusted entity 是 events,但选项中并没有 events 选项,我们先选择 ECS,最后会把 trusted entity 改为 events

图 10-14AWS CICD Step Function 下篇  邮件审批_代码仓库_06

在搜索框中输入“step”,然后选中“AWSStepFunctionsFullAccess”,点击“Next:Tags”

图 4AWS CICD Step Function 下篇  邮件审批_代码仓库_07

点击“Next:Review”,添加 Role 名称“tsEventforTriggerSF”后,点击“Create Role”。

建好 Role 后,选择“Trust relationships”后,点击“Edit trust relationship”

图 5AWS CICD Step Function 下篇  邮件审批_资源下载_08

粘贴以下内容,把 trusted entity 改成 events

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Service": "events.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

图 6AWS CICD Step Function 下篇  邮件审批_elastic_09

更改 trusted entity 完成

图 7AWS CICD Step Function 下篇  邮件审批_代码仓库_10

新建 Rule/Trigger

在中国区的 Cloudwatch Rule 的界面上,当把 Trigger 选择成 Step Function 时,我们找不到任何 SF。

图 8AWS CICD Step Function 下篇  邮件审批_elastic_11

所以这里我们用 AWS cli 创建新的 Cloudwatch Rule/Trigger,当 CodeBuild 成功完成时触发 Step Function。

在安装有 AWS Cli 的环境中运行以下命令

aws events put-rule --name "tsCodeBuildTriggerSF" --event-pattern "{\"source\":[\"aws.codebuild\"],\"detail-type\":[\"CodeBuild Build Phase Change\"],\"detail\":{\"completed-phase\":[\"POST_BUILD\"],\"completed-phase-status\":[\"SUCCEEDED\"],\"project-name\":[\"tstestCodeCommit\"]}}" --description "codebuild trigger Step machine"

说明:


  • name Rule 的名称
  • event-pattern codebuild 的事件 pattern,与“AWS CICD 之 CodeCommit/Build/Deploy 下篇”文章中 Rule “tsCodeDeploytrigger”中的 event pattern 相同
  • description rule 的描述信息

event pattern 内容如下

{
  "source": [
    "aws.codebuild"
  ],
  "detail-type": [
    "CodeBuild Build Phase Change"
  ],
  "detail": {
    "completed-phase": [
      "POST_BUILD"
    ],
    "completed-phase-status": [
      "SUCCEEDED"
    ],
    "project-name": [
      "tstestCodeCommit"
    ]
  }
}

运行结果,创建 Cloudwatch Rule 成功返回 Rule 的 ARN

图 2AWS CICD Step Function 下篇  邮件审批_代码仓库_12

接下来运行以下命令,建 Rule 中的 Trigger,用来触发 Step Function

aws events put-targets --rule tsCodeBuildTriggerSF --targets "Id"="Target1","Arn"="arn:aws-cn:states:cn-north-1:XXXX:stateMachine:tsSFcallBack","RoleArn"="arn:aws-cn:iam::XXXX:role/tsEventforTriggerSF"

说明:


  • rule 上面创建的 Rule 的名称
  • targets SF 的 ARN 和上面创建的 Event Role 信息,这里也可以注册多个 Targets

运行结果,创建 Trigger 成功

图 3AWS CICD Step Function 下篇  邮件审批_资源下载_13

现在可以在 Cloudwatch 的 Rule 中看到新建的 Rule

图 9AWS CICD Step Function 下篇  邮件审批_elastic_14

新 Rule 建好后,我们把原来 CICD 中直接触发 CodeDeploy 的 Rule “tsCodeDeploytrigger”停掉。

运行以下命令

aws events disable-rule --name tsCodeDeploytrigger --no-verify-ssl

灰色表示 disable

图 10AWS CICD Step Function 下篇  邮件审批_代码仓库_15

2. 修改 Step Function

增加调用 Lambda 权限

在之前的 CICD 中,Lambda 函数“tsCodeBuildTriggerDeploy”用来启动 Codedeploy 的部署,本文中继续用这个函数来启动部署。

我们需要给 SF 的 role 添加调用此 Lambda 函数的权限,在 SF 界面选择“tsSFcallBack”,点击“IAM role ARN”部分,打开 IAM Role 界面

图 14-19AWS CICD Step Function 下篇  邮件审批_代码仓库_16

展开上篇文章中创建的 Policy“tslambda-policy”,点击“Edit policy”

图 11AWS CICD Step Function 下篇  邮件审批_代码仓库_17

选择 JSON,粘贴以下内容

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "lambda:InvokeFunction"
            ],
            "Resource": [
                "arn:aws-cn:lambda:cn-north-1:YOUR_AWS_ACCOUNT:function:tsSendMailforSF:*",
                "arn:aws-cn:lambda:cn-north-1:YOUR_AWS_ACCOUNT:function:tsCodeBuildTriggerDeploy:*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "lambda:InvokeFunction"
            ],
            "Resource": [
                "arn:aws-cn:lambda:cn-north-1:YOUR_AWS_ACCOUNT:function:tsSendMailforSF",
                "arn:aws-cn:lambda:cn-north-1:YOUR_AWS_ACCOUNT:function:tsCodeBuildTriggerDeploy"
            ]
        }
    ]
}

说明:其中增加了 SF 对 Lambda 函数“tsCodeBuildTriggerDeploy”的调用权限

点击“Review policy”,再点击“Save Changes”保存更改

图 12AWS CICD Step Function 下篇  邮件审批_资源下载_18

修改 Step Function 定义

下面我们修改 SF “tsSFcallBack”,在 Approve 分支增加调用 Lambda 函数“tsCodeBuildTriggerDeploy”的功能。

在 Step Function 界面,选择“State machines”,选择“tsSFcallBack”,点击“Edit”

图 13AWS CICD Step Function 下篇  邮件审批_代码仓库_19

在 Definition 部分,粘贴资源下载中 sf.json 文件中的内容。

主要修改部分是 ApprovedPassState 这部分,增加了调用 Lambda 函数

  ...
    "ApprovedPassState":  {
      "Type": "Task",
      "Resource": "arn:aws-cn:states:::lambda:invoke",
      "Parameters": {
        "FunctionName": "arn:aws-cn:lambda:cn-north-1:XXXX:function:tsCodeBuildTriggerDeploy"
      },
      "End": true
    },
  ...

然后点击“Save”保存

图 14AWS CICD Step Function 下篇  邮件审批_代码仓库_20

3. 测试带邮件审批的 CICD 流程

在本地 Git Repo 中 touch file,然后 push 代码,启动 CICD 流水线

图 15AWS CICD Step Function 下篇  邮件审批_elastic_21

在 CodeBuild 中观察到 Build 项目启动

图 16AWS CICD Step Function 下篇  邮件审批_资源下载_22

图 17AWS CICD Step Function 下篇  邮件审批_资源下载_23

Build 项目成功结束

图 20AWS CICD Step Function 下篇  邮件审批_代码仓库_24

这时在 SF 界面,可以看到 SF 运行到“Lambda CallBack”的状态。这时正在等待邮件审批结果(callback)

图 21AWS CICD Step Function 下篇  邮件审批_代码仓库_25

过 1-2 分钟,收到审批邮件后,点击“Approve”下面的链接

图 18AWS CICD Step Function 下篇  邮件审批_资源下载_26

在 CodeDeploy 界面可以看到部署开始了,而这时 SF 已经成功结束了

图 22AWS CICD Step Function 下篇  邮件审批_资源下载_27

图 19AWS CICD Step Function 下篇  邮件审批_代码仓库_28

过一段时间,CodeDeploy 会部署完成。Fargate 的部署 Task 过程就不截图了,和直接用 CodeDeploy 部署没差别了

总结

我们再把整个 CICD 流程梳理一下

图 1AWS CICD Step Function 下篇  邮件审批_资源下载_04图 28AWS CICD Step Function 下篇  邮件审批_elastic_03


  1. 用户在客户端用 Git 命令 Push 代码到 CodeCommit 的代码仓库中
  2. CloudWatch 通过设置的 Rule 触发 CodeBuild 构建项目
  3. 构建项目启动后,从代码仓库中拉到代码,生成镜像,然后把镜像推送至 ECR
  4. 在构建项目 POST_BUILD 成功后,CloudWatch 通过设置的 Rule 触发 Step Function
  5. Step Function 触发 sendmail Lambda 函数,生成含有 taskToken 的 approve/reject 链接,并通过 SNS 发送邮件给客户
  6. 客户点击邮件中 approve/reject 链接,把请求发送至 ALB。
  7. ALB 把请求转发给 apporve Lambda 函数,apporve 函数把审批结果返回给 Step Function
  8. Step Function 根据 callBack 的结果选择 approve 或 reject 分支
  9. 如果选择 approve 分支,则 Step Function 触发部署 CodeDeploy 的 Lambda 函数,函数启动 CodeDeploy 后终于,SF 终止
  10. 如果选择 reject 分支,则 SF 终止

引申

如果 push 两次的时间很近,Codebuild 会按先后顺序同时开始 Build,同时 SF 也会被调用两次,发两次邮件。

如果两次邮件都点 Approve,第二个 SF 会报错停止。

Error

DeploymentLimitExceededException
{
  "errorMessage": "An error occurred (DeploymentLimitExceededException) when calling the CreateDeployment operation: The Deployment Group 'tstestDGrp' already has an active Deployment 'd-FLZE9E3H8'",
  "errorType": "DeploymentLimitExceededException",

图 23AWS CICD Step Function 下篇  邮件审批_代码仓库_31

原因在于 CodeDeploy 每个 Deploy Group 只能同时运行一个部署


Feature

Limit

Maximum number of concurrent deployments to a deployment group¹

1

​https://docs.aws.amazon.com/codedeploy/latest/userguide/limits.html#limits-deployments​

资源下载

相关 policy 文件可在下列链接中下载https://github.com/tansong0091/realCrapForAWS/tree/main/StepFunction2

后记

CICD 部署流水线,没有固定的工具和方法。只要实现了自动化,不管是用 AWS 提供的服务也好,还是自己写的 shell 脚本,效果都是一样的。

本文的例子用到了多个 AWS 服务,但这只是 CICD 实现的一种具体方式。如果有朋友还有更好的方法,可以私信我一起研究学习。



喜欢请点赞,欢迎转发

微信公众号“全是 AWS 干货”

AWS CICD Step Function 下篇  邮件审批_elastic_32