本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
AppSpec'挂钩'部分
AppSpec文件'hooks'
部分中的内容会有所不同,具体取决于部署的计算平台。EC2/本地部署'hooks'
部分包含将部署生命周期事件挂钩链接到一个或多个脚本的映射。Lambda 或 Amazon ECS 部署'hooks'
部分指定了部署生命周期事件期间要运行的 Lambda 验证函数。如果某个事件的挂钩不存在,则不会对该事件执行任何操作。只有在部署过程中运行脚本或 Lambda 验证函数时,才需要此部分。
AppSpec亚马逊 ECS 部署的 “挂钩” 部分
亚马逊 ECS 部署的生命周期事件挂钩列表
AmazonLambda 挂钩是一个 Lambda 函数,在生命周期事件名称后的新行上使用字符串指定。对于每次部署,每个挂钩将执行一次。以下是生命周期事件的描述,您可以在 Amazon ECS 部署期间在这些事件中运行挂钩。
-
BeforeInstall
— 用于在创建替换任务集之前运行任务。一个目标组与原始任务集相关联。如果指定了可选的测试侦听器,则它与原始任务集相关联。此时,无法执行回滚。 -
AfterInstall
— 用于在创建替换任务集且其中一个目标组与之关联后运行任务。如果指定了可选的测试侦听器,则它与原始任务集相关联。在此生命周期事件时挂钩函数的运行结果可能会触发回滚。 -
AfterAllowTestTraffic
— 用于在测试侦听器向替换任务集提供流量后运行任务。此时挂钩函数的运行结果可能会触发回滚。 -
BeforeAllowTraffic
— 用于在第二个目标组与替换任务集关联之后但在将流量转移到替换任务集之前运行任务。在此生命周期事件时挂钩函数的运行结果可能会触发回滚。 -
AfterAllowTraffic
— 用于在第二个目标组向替换任务集提供流量后运行任务。在此生命周期事件时挂钩函数的运行结果可能会触发回滚。
有关更多信息,请参阅 Amazon ECS 部署期间会发生什么 和 教程:通过验证测试部署 Amazon ECS 服务。
在 Amazon ECS 部署中运行挂钩顺序
在 Amazon ECS 部署中,事件挂钩按以下顺序运行:

注意
无法为部署中的 “开始” TestTrafficAllowTraffic、“安装” 和 “结束” 事件编写脚本,这就是它们在此图中显示为灰色的原因。
“挂钩” 部分的结构
以下示例说明了 'hooks'
部分的结构。
使用 YAML:
Hooks: - BeforeInstall: "
BeforeInstallHookFunctionName
" - AfterInstall: "AfterInstallHookFunctionName
" - AfterAllowTestTraffic: "AfterAllowTestTrafficHookFunctionName
" - BeforeAllowTraffic: "BeforeAllowTrafficHookFunctionName
" - AfterAllowTraffic: "AfterAllowTrafficHookFunctionName
"
使用 JSON:
"Hooks": [ { "BeforeInstall": "
BeforeInstallHookFunctionName
" }, { "AfterInstall": "AfterInstallHookFunctionName
" }, { "AfterAllowTestTraffic": "AfterAllowTestTrafficHookFunctionName
" }, { "BeforeAllowTraffic": "BeforeAllowTrafficHookFunctionName
" }, { "AfterAllowTraffic": "AfterAllowTrafficHookFunctionName
" } ] }
Lambda “挂钩” 函数示例
使用该'hooks'
部分指定CodeDeploy可以调用以验证 Amazon ECS 部署的 Lambda 函数。对于 BeforeInstall
、AfterInstall
、AfterAllowTestTraffic
、BeforeAllowTraffic
和 AfterAllowTraffic
部署生命周期事件,您可以使用相同函数或不同函数。完成验证测试后,Lambda AfterAllowTraffic
函数会回调CodeDeploy并提供Succeeded
或Failed
的结果。
重要
如果 Lambda 验证函数未在一小时内通知,CodeDeploy则认为部署已失败。
在调用 Lambda 挂钩函数之前,必须使用命令将部署 ID 和生命周期事件挂钩执行 ID 通知服务器。putLifecycleEventHookExecutionStatus
以下是用 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 CodeDeploy. var params = { deploymentId: deploymentId, lifecycleEventHookExecutionId: lifecycleEventHookExecutionId, status: 'Succeeded' // status can be 'Succeeded' or 'Failed' }; // Pass 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'); } }); };
AppSpecAmazonLambda 部署的 “挂钩” 部分
AmazonLambda 部署的生命周期事件挂钩列表
AmazonLambda 挂钩是一个 Lambda 函数,在生命周期事件名称后的新行上使用字符串指定。对于每次部署,每个挂钩将执行一次。以下是AppSpec文件中可供使用的挂钩的描述。
-
BeforeAllowTraffic— 用于在流量转移到已部署的 Lambda 函数版本之前运行任务。
-
AfterAllowTraffic— 用于在所有流量转移到已部署的 Lambda 函数版本后运行任务。
在 Lambda 函数版本部署中运行挂钩顺序
在无服务器 Lambda 函数版本部署中,事件挂钩按以下顺序运行:

注意
无法为部署中的 “开始” 和 “结束” 事件编写脚本,这就是它们在此图中显示为灰色的原因。AllowTraffic
“挂钩” 部分的结构
以下示例说明了“hooks”部分的结构。
使用 YAML:
hooks: - BeforeAllowTraffic:
BeforeAllowTrafficHookFunctionName
- AfterAllowTraffic:AfterAllowTrafficHookFunctionName
使用 JSON:
"hooks": [{ "BeforeAllowTraffic": "
BeforeAllowTrafficHookFunctionName
" }, { "AfterAllowTraffic": "AfterAllowTrafficHookFunctionName
" }]
Lambda “挂钩” 函数示例
使用 “挂钩” 部分指定CodeDeploy可以调用以验证 Lambda 部署的 Lambda 函数。对于 BeforeAllowTraffic
和 AfterAllowTraffic
部署生命周期事件,您可以使用相同函数或不同函数。完成验证测试后,Lambda 验证函数会回调CodeDeploy并提供Succeeded
或Failed
的结果。
重要
如果 Lambda 验证函数未在一小时内通知,CodeDeploy则认为部署已失败。
在调用 Lambda 挂钩函数之前,必须使用命令将部署 ID 和生命周期事件挂钩执行 ID 通知服务器。putLifecycleEventHookExecutionStatus
以下是用 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 CodeDeploy. var params = { deploymentId: deploymentId, lifecycleEventHookExecutionId: lifecycleEventHookExecutionId, status: 'Succeeded' // status can be 'Succeeded' or 'Failed' }; // Pass 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'); } }); };
AppSpecEC2/本地部署的 “挂钩” 部分
生命周期事件挂钩列表
每次部署到一个实例,EC2/本地部署挂接都会执行一次。在一个挂钩中,可以指定运行一个或多个脚本。生命周期事件的每个挂钩在单独的行中使用字符串指定。以下是AppSpec文件中可供使用的挂钩的描述。
有关哪些生命周期事件挂钩对哪些部署和回滚类型有效的信息,请参阅生命周期事件挂钩可用性。
-
ApplicationStop
— 此部署生命周期事件甚至在下载应用程序修订版之前发生。您可以为此事件指定脚本,以便从容地停止应用程序或在部署准备过程中删除当前已安装的软件包。用于此部署生命周期事件AppSpec的文件和脚本来自先前成功部署的应用程序修订版。注意
在部署到实例之前,AppSpec文件在实例上不存在。因此,
ApplicationStop
挂钩在您首次部署到实例时不会运行。您可以在第二次部署到实例时使用ApplicationStop
挂钩。为确定上次成功部署的应用程序修订的位置,CodeDeploy 代理将查看
文件中列出的位置。此文件位于:deployment-group-id
_last_successful_install/opt/codedeploy-agent/deployment-root/deployment-instructions
亚马逊 Linux、Ubuntu 服务器和 RHEL 亚马逊 EC2 实例上的文件夹。C:\ProgramData\Amazon\CodeDeploy\deployment-instructions
Windows 服务器亚马逊 EC2 实例上的文件夹。要对在
ApplicationStop
部署生命周期事件期间失败的部署进行故障排除,请参阅 对失败ApplicationStop或AfterBlockTraffic部署生命周期事件进行故障排除 BeforeBlockTraffic。 -
DownloadBundle
— 在此部署生命周期事件中,CodeDeploy代理将应用程序修订文件复制到临时位置:/opt/codedeploy-agent/deployment-root/
亚马逊 Linux、Ubuntu 服务器和 RHEL 亚马逊 EC2 实例上的文件夹。deployment-group-id
/deployment-id
/deployment-archiveC:\ProgramData\Amazon\CodeDeploy\
Windows 服务器亚马逊 EC2 实例上的文件夹。deployment-group-id
\deployment-id
\deployment-archive此事件是为 CodeDeploy 代理预留的,不能用于运行脚本。
要对在
DownloadBundle
部署生命周期事件期间失败的部署进行故障排除,请参阅 对DownloadBundle部署生命周期失败事件进行故障排除UnknownError:未打开以供读取。 -
BeforeInstall
— 您可以将此部署生命周期事件用于预安装任务,例如解密文件和创建当前版本的备份。 -
Install
— 在此部署生命周期事件中,CodeDeploy代理将修订文件从临时位置复制到最终目标文件夹。此事件是为 CodeDeploy 代理预留的,不能用于运行脚本。 -
AfterInstall
— 您可以将此部署生命周期事件用于配置应用程序或更改文件权限等任务。 -
ApplicationStart
— 您通常使用此部署生命周期事件来重启在此期间停止的服务ApplicationStop
。 -
ValidateService
— 这是最后一次部署生命周期事件。它用于验证部署已成功完成。 -
BeforeBlockTraffic
— 在从负载均衡器注销实例之前,您可以使用此部署生命周期事件在实例上运行任务。要对在
BeforeBlockTraffic
部署生命周期事件期间失败的部署进行故障排除,请参阅 对失败ApplicationStop或AfterBlockTraffic部署生命周期事件进行故障排除 BeforeBlockTraffic。 -
BlockTraffic
— 在此部署生命周期事件中,互联网流量被阻止访问当前提供流量服务的实例。此事件是为 CodeDeploy 代理预留的,不能用于运行脚本。 -
AfterBlockTraffic
— 在实例从负载均衡器注销后,您可以使用此部署生命周期事件在实例上运行任务。要对在
AfterBlockTraffic
部署生命周期事件期间失败的部署进行故障排除,请参阅 对失败ApplicationStop或AfterBlockTraffic部署生命周期事件进行故障排除 BeforeBlockTraffic。 -
BeforeAllowTraffic
— 在实例向负载均衡器注册之前,您可以使用此部署生命周期事件在实例上运行任务。 -
AllowTraffic
— 在此部署生命周期事件中,允许互联网流量在部署后访问实例。此事件是为 CodeDeploy 代理预留的,不能用于运行脚本。 -
AfterAllowTraffic
— 在实例向负载均衡器注册后,您可以使用此部署生命周期事件在实例上运行任务。
生命周期事件挂钩可用性
下表列出了适用于每个部署和回滚方案的生命周期事件挂钩。
生命周期事件名称 | 就地部署¹ | 蓝/绿部署:原始实例 | 蓝/绿部署:替换实例 | 蓝/绿部署回滚:原始实例 | 蓝/绿部署回滚:替换实例 |
---|---|---|---|---|---|
ApplicationStop | ✓ | ✓ | |||
DownloadBundle² | ✓ | ✓ | |||
BeforeInstall | ✓ | ✓ | |||
安装 ² | ✓ | ✓ | |||
AfterInstall | ✓ | ✓ | |||
ApplicationStart | ✓ | ✓ | |||
ValidateService | ✓ | ✓ | |||
BeforeBlockTraffic | ✓ | ✓ | ✓ | ||
BlockTraffic² | ✓ | ✓ | ✓ | ||
AfterBlockTraffic | ✓ | ✓ | ✓ | ||
BeforeAllowTraffic | ✓ | ✓ | ✓ | ||
AllowTraffic² | ✓ | ✓ | ✓ | ||
AfterAllowTraffic | ✓ | ✓ | ✓ | ||
¹也适用于就地部署的回滚。 ² 预留用于CodeDeploy运营。不能用于运行脚本。 |
在部署中运行挂钩顺序
就地部署
在就地部署中 (包括就地部署的回滚),事件挂钩按以下顺序运行:
注意
对于就地部署,只有当您在部署组中指定了 Elastic Load Balancing 中的传统负载均衡器、应用程序负载均衡器或网络负载均衡器时,与阻止和允许流量相关的六个挂钩才适用。

注意
无法为部署中的 “开始”、“安装” 和 “结束” 事件编写脚本,这就是它们在此图中显示为灰色的原因。DownloadBundle但是,您可以编辑AppSpec文件的'files'
部分以指定在安装事件期间安装的内容。
蓝/绿部署
在蓝/绿部署中,事件挂钩按以下顺序运行:

注意
无法为部署中的 “开始” BlockTrafficAllowTraffic、“安装” 和 “结束” 事件编写脚本,这就是它们在此图中显示为灰色的原因。DownloadBundle但是,您可以编辑文件的 “文件” 部分,AppSpec以指定在安装事件期间安装的内容。
“挂钩” 部分的结构
'hooks'
部分具有以下结构:
hooks:
deployment-lifecycle-event-name
: - location:script-location
timeout:timeout-in-seconds
runas:user-name
可以在 hook 条目中的部署生命周期事件名称后包括以下元素:
- location
-
必需。修订的脚本文件包的位置。您
hooks
在本节中指定的脚本位置相对于应用程序修订包的根目录。有关更多信息,请参阅计划 CodeDeploy 的修订: - timeout
-
可选。在脚本被视为失败之前允许其执行的秒数。默认值为 3600 秒(1 小时)。
注意
3600 秒(1 小时)是允许每个部署生命周期事件脚本执行的最长时间。如果脚本超过此限制,则部署将停止,并且部署到实例将失败。确保在 timeout 中为每个部署生命周期事件的所有脚本指定的总秒数不超过此限制。
- runas
-
可选。运行脚本时要模拟的用户。默认情况下,这是在实例上运行的CodeDeploy代理。CodeDeploy不存储密码,因此如果 run as 用户需要密码,则无法模拟用户。此元素仅适用于亚马逊 Linux 和 Ubuntu 服务器实例。
挂钩的环境变量可用性
在每个部署生命周期事件期间,挂钩脚本可以访问以下环境变量:
- APPLICATION_NAME
-
CodeDeploy 中属于当前部署的应用程序的名称(例如,
WordPress_App
)。 - DEPLOYMENT_ID
-
CodeDeploy 已分配给当前部署的 ID(例如,
d-AB1CDEF23
)。 - DEPLOYMENT_GROUP_NAME
-
CodeDeploy 中属于当前部署的部署组的名称(例如,
WordPress_DepGroup
)。 - DEPLOYMENT_GROUP_ID
-
CodeDeploy 中属于当前部署的部署组的 ID(例如,
b1a2189b-dd90-4ef5-8f40-4c1c5EXAMPLE
)。 - LIFECYCLE_EVENT
-
当前部署生命周期事件的名称(例如
AfterInstall
)。
这些是每个部署生命周期事件的本地环境变量。
根据部署包的来源,还有其他环境变量可用于挂接脚本:
亚马逊 S3 的捆绑包
-
BUNDLE_B
从中下载部署包的 Amazon S3 存储桶的名称(例如,
my-s3-bucket
)。 -
捆绑密钥
在 Amazon S3 存储桶中下载的包的对象密钥(例如,
WordPress_App.zip
)。 -
捆绑版
包的对象版本(例如
3sL4kqtJlcpXroDTDmJ+rmSpXd3dIbrHY+MTRCxf3vjVBH40Nr8X8gdRQBpUMLUo
)。只有在 Amazon S3 存储桶启用了对象版本控制时,才会设置此变量。 -
BUNDLE_ETAG
捆绑包的对象 etag(例如
b10a8db164e0754105b7a99be72e3fe5-4
)。
捆绑来自 GitHub
-
捆绑提交
由 Git 生成的捆绑包的 SHA256 提交哈希(例如
d2a84f4b8b650937ec8f73cd8be2c74add5a911ba64df27458ed8229da804a26
)。
如果 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 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
目录位于包的根级别。有关更多信息,请参阅计划 CodeDeploy 的修订: