AWS CodeDeploy
User Guide (API 版本 2014-10-06)
AWS 文档中描述的 AWS 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 Amazon AWS 入门

AppSpec 的“hooks”部分

AppSpec file的“hooks”部分内容会随着部署的计算平台而改变。EC2/本地 部署的“hooks”部分包含将部署生命周期事件挂钩链接到一个或多个脚本的映射。Lambda 部署的“hooks”部分指定在部署生命周期事件期间运行的 Lambda 验证函数。如果某个事件的挂钩不存在,则不会对该事件执行任何操作。仅当您将在部署过程中运行脚本或 Lambda 验证函数时,才需要此部分。

用于 AWS Lambda 部署的 AppSpec 的“hooks”部分

用于 AWS Lambda 部署的生命周期事件挂钩的列表

AWS Lambda 挂钩是一个 Lambda 函数,该函数在生命周期事件名称之后的新行中使用字符串指定。对于每次部署,每个挂钩将执行一次。下面是适用于 AppSpec 文件的挂钩的描述。

  • BeforeAllowTraffic – 用于在将流量转移到部署的 Lambda 函数版本之前运行任务。

  • AfterAllowTraffic – 用于在将流量转移到部署的 Lambda 函数版本之后运行任务。

挂钩在 Lambda 函数版本部署中的运行顺序

在无服务器 Lambda 函数版本部署中,事件挂钩按以下顺序运行:

注意

部署中的 StartAllowTrafficEnd 事件无法脚本化,这就是为什么它们在此图中灰显。

“挂钩”部分的结构

以下示例说明了“hooks”部分的结构。

使用 YAML:

hooks: - BeforeAllowTraffic: BeforeAllowTrafficHookFunctionName - AfterAllowTraffic: AfterAllowTrafficHookFunctionName

使用 JSON:

"hooks": [{ "BeforeAllowTraffic": "BeforeAllowTrafficHookFunctionName" "AfterAllowTraffic": "AfterAllowTrafficHookFunctionName" }]

示例 Lambda“hooks”函数

使用“hooks”部分可以指定 AWS CodeDeploy 可调用以验证 Lambda 部署的 Lambda 函数。您可以为 BeforeAllowTrafficAfterAllowTraffic 部署生命周期事件使用相同或不同的函数。在完成验证测试后,Lambda 验证函数将回调 AWS CodeDeploy,并传输“成功”或“失败”结果。

重要

如果 AWS CodeDeploy 在一小时内未收到 Lambda 验证函数的通知,则假定部署失败。

在调用 Lambda 挂钩函数之前,必须向服务器通知部署 ID 和生命周期事件挂钩执行 ID:

aws deploy put-lifecycle-event-hook-execution-status --deployment-id <deployment-id> --status Succeeded --lifecycle-event-hook-execution-id <execution-id> --region <region>

下面是一个使用 Node.js 编写的 Lambda 挂钩函数示例。

'use strict'; const aws = require('aws-sdk'); const codedeploy = new aws.CodeDeploy({apiVersion: '2014-10-06'}); exports.handler = (event, context, callback) => { //Read the DeploymentId from the event payload. var deploymentId = event.DeploymentId; //Read the LifecycleEventHookExecutionId from the event payload var lifecycleEventHookExecutionId = event.LifecycleEventHookExecutionId; /* Enter validation tests here. */ // Prepare the validation test results with the deploymentId and // the lifecycleEventHookExecutionId for AWS CodeDeploy. var params = { deploymentId: deploymentId, lifecycleEventHookExecutionId: lifecycleEventHookExecutionId, status: 'Succeeded' // status can be 'Succeeded' or 'Failed' }; // Pass AWS CodeDeploy the prepared validation test results. codedeploy.putLifecycleEventHookExecutionStatus(params, function(err, data) { if (err) { // Validation failed. callback('Validation test failed'); } else { // Validation succeeded. callback(null, 'Validation test succeeded'); } }); };

用于 EC2/本地 部署的 AppSpec 的“hooks”部分

生命周期事件挂钩的列表

对于实例的每次部署,EC2/本地 部署挂钩执行一次。在一个挂钩中,可以指定运行一个或多个脚本。每个生命周期事件的挂钩是在单独的行中使用字符串指定的。下面是适用于 AppSpec 文件的挂钩的描述。

有关哪些生命周期事件挂钩对哪些部署和回滚类型有效的信息,请参阅生命周期事件挂钩可用性

  • ApplicationStop - 此部署生命周期事件发生在下载应用程序修订之前。您可以为此事件指定脚本以便从容地停止应用程序或删除部署准备过程中当前已安装的软件包。用于此部署生命周期事件的 AppSpec file和脚本来自于上一个成功部署的应用程序修订。

    注意

    在您部署实例之前,实例上不存在 AppSpec file。因此,ApplicationStop 挂钩在您首次部署到实例时不会运行。您可以在第二次部署到实例时使用 ApplicationStop 钩子。

    为确定上次成功部署的应用程序修订的位置,AWS CodeDeploy 代理会查看 deployment-group-id_last_successful_install 文件中列出的位置。此文件位于:

    /opt/codedeploy-agent/deployment-root/deployment-instructions 文件夹中 (在 Amazon Linux、Ubuntu Server 和 RHEL Amazon EC2 实例) 上。

    C:\ProgramData\Amazon\CodeDeploy\deployment-instructions 文件夹中 (在 Windows Server Amazon EC2 实例) 上。

    要对在 ApplicationStop 部署生命周期事件期间失败的部署进行故障排除,请参阅 对失败的 ApplicationStop、BeforeBlockTraffic 和 AfterBlockTraffic 部署生命周期事件进行故障排除

  • DownloadBundle - 在此部署生命周期事件期间,AWS CodeDeploy 代理会将应用程序修订文件复制到临时位置:

    /opt/codedeploy-agent/deployment-root/deployment-group-id/deployment-id/deployment-archive 文件夹中 (在 Amazon Linux、Ubuntu Server 和 RHEL Amazon EC2 实例) 上。

    C:\ProgramData\Amazon\CodeDeploy\deployment-group-id\deployment-id\deployment-archive 文件夹中 (在 Windows Server Amazon EC2 实例) 上。

    此事件是为 AWS CodeDeploy 代理预留的,不能用于运行脚本。

    要对在 DownloadBundle 部署生命周期事件期间失败的部署进行故障排除,请参阅 排查失败的 DownloadBundle 部署生命周期事件的问题,错误为“UnknownError: not opened for reading”

  • BeforeInstall - 您可以使用此部署生命周期事件执行预安装任务,例如解密文件和创建当前版本的备份。

  • Install - 在此部署生命周期事件期间,AWS CodeDeploy 代理会将修订文件从临时位置复制到最终目标文件夹中。此事件是为 AWS CodeDeploy 代理预留的,不能用于运行脚本。

  • AfterInstall - 您可以使用此部署生命周期事件执行配置应用程序或更改文件权限等任务。

  • ApplicationStart - 您通常使用此部署生命周期事件来重新启动在 ApplicationStop 期间停止的服务。

  • ValidateService - 这是最后的部署生命周期事件。它用于验证部署已成功完成。

  • BeforeBlockTraffic - 在从负载均衡器取消注册实例之前,您可以使用此部署生命周期事件在这些实例上运行任务。

    要对在 BeforeBlockTraffic 部署生命周期事件期间失败的部署进行故障排除,请参阅对失败的 ApplicationStop、BeforeBlockTraffic 和 AfterBlockTraffic 部署生命周期事件进行故障排除

  • BlockTraffic - 在此部署生命周期事件期间,阻止 Internet 流量访问当前正在处理流量的实例。此事件是为 AWS CodeDeploy 代理预留的,不能用于运行脚本。

  • AfterBlockTraffic - 在从负载均衡器取消注册实例之后,您可以使用此部署生命周期事件在这些实例上运行任务。

    要对在 AfterBlockTraffic 部署生命周期事件期间失败的部署进行故障排除,请参阅对失败的 ApplicationStop、BeforeBlockTraffic 和 AfterBlockTraffic 部署生命周期事件进行故障排除

  • BeforeAllowTraffic - 在将实例注册到负载均衡器之前,您可以使用此部署生命周期事件在这些实例上运行任务。

  • AllowTraffic - 在此部署生命周期事件期间,允许 Internet 流量在部署后访问实例。此事件是为 AWS CodeDeploy 代理预留的,不能用于运行脚本。

  • AfterAllowTraffic - 在将实例注册到负载均衡器之后,您可以使用此部署生命周期事件在这些实例上运行任务。

生命周期事件挂钩可用性

下表列出了适用于每个部署和回滚方案的生命周期事件挂钩。

生命周期事件名称 就地部署¹ 蓝/绿部署:原始实例 蓝/绿部署:替换实例 蓝/绿部署回滚:原始实例 蓝/绿部署回滚:替换实例
ApplicationStop
DownloadBundle²
BeforeInstall
安装²
AfterInstall
ApplicationStart
ValidateService
BeforeBlockTraffic
BlockTraffic²
AfterBlockTraffic
BeforeAllowTraffic
AllowTraffic²
AfterAllowTraffic

¹也适用于就地部署的回滚。

² 为 AWS CodeDeploy 操作预留。不能用于运行脚本。

挂钩在部署中的运行顺序

就地部署

在就地部署中 (包括就地部署的回滚),事件挂钩按以下顺序运行:

注意

对于就地部署,仅当您在部署组中通过 Elastic Load Balancing 指定 传统负载均衡器、应用程序负载均衡器 或 Network Load Balancer 时,与阻止及允许流量相关的六个挂钩才适用。

注意

部署中的 StartDownloadBundleInstallEnd 事件无法脚本化,这就是为什么它们在此图中灰显。不过,您可以编辑 AppSpec file的“files”部分,以指定在 Install 事件期间安装的内容。

蓝/绿部署

在蓝/绿部署中,事件挂钩按以下顺序运行:

注意

部署中的 StartDownloadBundleInstallBlockTrafficAllowTrafficEnd 事件无法脚本化,这就是它们在此图中灰显的原因。不过,您可以编辑 AppSpec file的“files”部分,以指定在 Install 事件期间安装的内容。

“挂钩”部分的结构

“hooks”部分具有以下结构:

hooks: deployment-lifecycle-event-name: - location: script-location timeout: timeout-in-seconds runas: user-name

可以在 hook 条目中的部署生命周期事件名称后包括以下元素:

位置

必需。修订的脚本文件包的位置。

timeout

可选。在脚本被视为失败之前允许其执行的秒数。默认值为 3600 秒(1 小时)。

注意

3600 秒(1 小时)是允许每个部署生命周期事件脚本执行的最长时间。如果脚本超过此限制,则部署将停止,并且部署到实例将失败。确保在 timeout 中为每个部署生命周期事件的所有脚本指定的总秒数不超过此限制。

runas

可选。运行脚本时要模拟的用户。默认情况下,这是在实例上运行的 AWS CodeDeploy 代理。AWS CodeDeploy 不存储密码,因此,如果 runas 用户需要密码,则无法模拟该默认用户。此元素仅适用于 Amazon Linux 和 Ubuntu Server 实例。

挂钩的环境变量可用性

在每个部署生命周期事件期间,挂钩脚本可以访问以下环境变量:

APPLICATION_NAME

AWS CodeDeploy 中属于当前部署的应用程序的名称 (例如 WordPress_App)。

DEPLOYMENT_ID

AWS CodeDeploy 已分配给当前部署的 ID(例如 d-AB1CDEF23)。

DEPLOYMENT_GROUP_NAME

AWS CodeDeploy 中属于当前部署的部署组的名称 (例如 WordPress_DepGroup)。

DEPLOYMENT_GROUP_ID

AWS CodeDeploy 中属于当前部署的部署组的 ID (例如 b1a2189b-dd90-4ef5-8f40-4c1c5EXAMPLE)。

LIFECYCLE_EVENT

当前部署生命周期事件的名称(例如 AfterInstall)。

这些是每个部署生命周期事件的本地环境变量。

如果 DEPLOYMENT_GROUP_NAME 的值等于 Staging,则以下脚本会将 Apache HTTP 服务器上的监听端口更改为 9090 而非 80。必须在 BeforeInstall 部署生命周期事件期间调用此脚本:

if [ "$DEPLOYMENT_GROUP_NAME" == "Staging" ] then sed -i -e 's/Listen 80/Listen 9090/g' /etc/httpd/conf/httpd.conf fi

如果 DEPLOYMENT_GROUP_NAME 环境变量的值等于 Staging,则以下脚本示例会将其错误日志中记录的消息的详细级别从警告更改为调试。必须在 BeforeInstall 部署生命周期事件期间调用此脚本:

if [ "$DEPLOYMENT_GROUP_NAME" == "Staging" ] then sed -i -e 's/LogLevel warn/LogLevel debug/g' /etc/httpd/conf/httpd.conf fi

以下脚本示例将指定网页中的文本替换为显示这些环境变量值的文本。必须在 AfterInstall 部署生命周期事件期间调用此脚本:

#!/usr/bin/python import os strToSearch="<h2>This application was deployed using AWS CodeDeploy.</h2>" strToReplace="<h2>This page for "+os.environ['APPLICATION_NAME']+" application and "+os.environ['DEPLOYMENT_GROUP_NAME']+" deployment group with "+os.environ['DEPLOYMENT_GROUP_ID']+" deployment group ID was generated by a "+os.environ['LIFECYCLE_EVENT']+" script during "+os.environ['DEPLOYMENT_ID']+" deployment.</h2>" fp=open("/var/www/html/index.html","r") buffer=fp.read() fp.close() fp=open("/var/www/html/index.html","w") fp.write(buffer.replace(strToSearch,strToReplace)) fp.close()

挂钩示例

以下是 hooks 条目的示例,该条目为 AfterInstall 生命周期事件指定两个挂钩:

hooks: AfterInstall: - location: Scripts/RunResourceTests.sh timeout: 180 - location: Scripts/PostDeploy.sh timeout: 180

Scripts/RunResourceTests.sh 脚本将在部署过程的 AfterInstall 阶段运行。如果该脚本的运行时间超过 180 秒 (3 分钟),则部署将失败。

您在“hooks”部分中指定的脚本的位置是应用程序修订包根目录的相对路径。在上述示例中,名为 RunResourceTests.sh 的文件位于名为 Scripts 的目录中。该 Scripts 目录位于包的根级别。有关更多信息,请参阅 计划 AWS CodeDeploy 的修订