AppSpec 「掛鉤」區段 - AWS CodeDeploy

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

AppSpec 「掛鉤」區段

AppSpec 檔案 'hooks'區段中的內容會因部署的運算平台而異。EC2/內部部署的 'hooks'區段包含將部署生命週期事件掛鉤連結至一或多個指令碼的映射。Lambda 或 Amazon ECS 部署的 'hooks'區段指定要在部署生命週期事件期間執行的 Lambda 驗證函數。如果事件勾點不存在,則不會為該事件執行任何操作。只有在您作為部署的一部分執行指令碼或 Lambda 驗證函數時,才需要本節。

AppSpec Amazon ECS 部署的 'hooks' 區段

Amazon ECS 部署的生命週期事件掛鉤清單

AWS Lambda 掛鉤是 Lambda 函數,指定的字串位於生命週期事件名稱後面的新行上。每個部署執行每個勾點一次。以下是生命週期事件的說明,您可以在 Amazon ECS 部署期間執行掛鉤。

  • BeforeInstall – 用於在建立替換任務集之前執行任務。單一目標群組與原始任務設定相關。如果指定了選用測試接聽程式,則和原始任務設定相關。目前無法轉返。

  • AfterInstall – 用於在建立取代任務集後執行任務,且其中一個目標群組與其相關聯。如果指定了選用測試接聽程式,則和原始任務設定相關。此生命週期事件上的勾點函數結果可以觸發轉返。

  • AfterAllowTestTraffic – 在測試接聽程式將流量提供給替代任務集之後,使用 執行任務。目前的勾點函數結果可以觸發轉返。

  • BeforeAllowTraffic – 用於在第二個目標群組與替代任務集建立關聯之後,但在流量轉移到替代任務集之前執行任務。此生命週期事件上的勾點函數結果可以觸發轉返。

  • AfterAllowTraffic – 用於在第二個目標群組將流量提供給替代任務集之後執行任務。此生命週期事件上的勾點函數結果可以觸發轉返。

如需詳細資訊,請參閱 Amazon ECS 部署期間會發生什麼教學課程:使用驗證測試部署 Amazon ECS服務

在 Amazon ECS 部署中執行掛鉤順序。

在 Amazon ECS 部署中,事件掛鉤會以下列順序執行:

Amazon ECS 部署中的事件掛鉤順序。
注意

部署中的開始 安裝 AllowTraffic、、 TestTraffic結束事件無法指令碼編寫,這就是為什麼它們在此圖表中以灰色顯示的原因。

「掛鉤」區段的結構

下列為 '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' 函數範例

使用 'hooks'區段指定 CodeDeploy 可呼叫的 Lambda 函數,以驗證 Amazon ECS 部署。您可以針對 BeforeInstallAfterInstallBeforeAllowTrafficAfterAllowTestTrafficAfterAllowTraffic 部署生命週期事件使用相同的函數或不同的函數。完成驗證測試後,Lambda AfterAllowTraffic函數會回 CodeDeploy呼並交付 Succeeded或 的結果Failed

重要

如果 Lambda 驗證函數在一小時內 CodeDeploy 未通知部署,則此部署會被視為失敗。

叫用 Lambda 掛鉤函數之前,必須使用 putLifecycleEventHookExecutionStatus命令通知伺服器部署 ID 和生命週期事件掛鉤執行 ID。

以下是以 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'); } }); };

AppSpec AWS Lambda 部署的 'hooks' 區段

AWS Lambda 部署的生命週期事件掛鉤清單

AWS Lambda 掛鉤是 Lambda 函數,指定的字串位於生命週期事件名稱後面的新行上。每個部署執行每個勾點一次。以下是 AppSpec 檔案中可用掛鉤的說明。

  • BeforeAllowTraffic – 使用 在流量轉換為部署的 Lambda 函數版本之前執行任務。

  • AfterAllowTraffic – 用於在所有流量移至部署的 Lambda 函數版本後執行任務。

在 Lambda 函數版本部署中執行掛鉤順序

在無伺服器 Lambda 函數版本部署中,事件掛鉤會以下列順序執行:

Lambda 部署中的事件掛鉤順序。
注意

部署中的開始 AllowTraffic結束事件無法指令碼處理,這就是為什麼它們在此圖表中以灰色顯示的原因。

「掛鉤」區段的結構

下列為 'hooks' 部分的結構範例。

使用 YAML:

hooks: - BeforeAllowTraffic: BeforeAllowTrafficHookFunctionName - AfterAllowTraffic: AfterAllowTrafficHookFunctionName

使用 JSON:

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

Lambda 'hooks' 函數範例

使用 'hooks' 區段指定 CodeDeploy 可呼叫的 Lambda 函數,以驗證 Lambda 部署。對於 BeforeAllowTrafficAfterAllowTraffic 部署生命週期事件,您可以使用相同的函數或不同的函數。完成驗證測試後,Lambda 驗證函數會回呼 CodeDeploy 並交付 Succeeded或 的結果Failed

重要

如果 Lambda 驗證函數在一小時內 CodeDeploy 未通知部署,則此部署會被視為失敗。

叫用 Lambda 掛鉤函數之前,必須使用 putLifecycleEventHookExecutionStatus命令通知伺服器部署 ID 和生命週期事件掛鉤執行 ID。

以下是以 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'); } }); };

AppSpec EC2/內部部署的「掛鉤」區段

生命週期事件掛鉤清單

EC2/內部部署掛鉤會在每次部署至執行個體時執行一次。您可以指定一或多個指令碼以在勾點中執行。生命週期事件的每個勾點是在不同行上以字串指定。以下是 AppSpec 檔案中可用掛鉤的說明。

如需有關哪些生命週期事件勾點對於哪些部署和復原類型有效的詳細資訊,請參閱生命週期事件掛鉤可用性

  • ApplicationStop – 即使下載應用程式修訂版之前,也會發生此部署生命週期事件。在準備部署時,您可以指定這個事件的指令碼從容地停止應用程式,或移除目前已安裝的套件。用於此部署生命週期事件 AppSpec 的檔案和指令碼來自先前成功部署的應用程式修訂版。

    注意

    在部署到執行個體之前,執行個體上不存在 AppSpec 檔案。因此,ApplicationStop 勾點不會在您第一次部署到執行個體時執行。您可以在第二次部署到執行個體時使用 ApplicationStop 勾點。

    若要判斷上次成功部署的應用程式修訂版的位置, 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 – 在此部署生命週期事件期間, 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執行個體上的 資料夾。

    此事件已預留給 CodeDeploy 代理程式,且無法用於執行指令碼。

    若要排除部署在 DownloadBundle 部署生命週期事件期間失敗的問題,請參閱使用 對失敗的 DownloadBundle 部署生命週期事件進行故障診斷 UnknownError:未開啟供讀取

  • BeforeInstall – 您可以將此部署生命週期事件用於預先安裝任務,例如解密檔案和建立目前版本的備份。

  • Install – 在此部署生命週期事件期間, CodeDeploy客服人員會將修訂檔案從暫時位置複製到最終目的地資料夾。此事件已保留給 CodeDeploy 代理程式,且無法用於執行指令碼。

  • AfterInstall – 您可以將此部署生命週期事件用於任務,例如設定應用程式或變更檔案許可。

  • ApplicationStart – 您通常會使用此部署生命週期事件來重新啟動在 期間停止的服務ApplicationStop

  • ValidateService – 這是最後一個部署生命週期事件。這用於驗證部署已順利完成。

  • BeforeBlockTraffic – 您可以在執行個體從負載平衡器取消註冊之前,使用此部署生命週期事件在執行個體上執行任務。

    若要排除部署在 BeforeBlockTraffic 部署生命週期事件期間失敗的問題,請參閱故障診斷失敗的 ApplicationStop BeforeBlockTraffic、 或 AfterBlockTraffic 部署生命週期事件

  • BlockTraffic – 在此部署生命週期事件期間,會封鎖網際網路流量,無法存取目前正在服務流量的執行個體。此事件已保留給 CodeDeploy 代理程式,且無法用於執行指令碼。

  • AfterBlockTraffic – 在從各自的負載平衡器取消註冊執行個體之後,您可以使用此部署生命週期事件在執行個體上執行任務。

    若要排除部署在 AfterBlockTraffic 部署生命週期事件期間失敗的問題,請參閱故障診斷失敗的 ApplicationStop BeforeBlockTraffic、 或 AfterBlockTraffic 部署生命週期事件

  • BeforeAllowTraffic – 您可以在執行個體註冊負載平衡器之前,使用此部署生命週期事件在執行個體上執行任務。

  • AllowTraffic – 在此部署生命週期事件期間,允許網際網路流量在部署後存取執行個體。此事件已保留給 CodeDeploy 代理程式,且無法用於執行指令碼。

  • AfterAllowTraffic – 在執行個體向負載平衡器註冊後,您可以使用此部署生命週期事件在執行個體上執行任務。

生命週期事件掛鉤可用性

下表列出生命週期事件勾點可用於每一個部署及復原案例。

生命週期事件名稱 Auto Scaling 啟動部署1 Auto Scaling 終止部署1 就地部署2 藍/綠部署:原始執行個體 藍/綠部署:取代執行個體 藍/綠部署復原:原始執行個體 藍/綠部署復原:取代執行個體
ApplicationStop
DownloadBundle3
BeforeInstall
安裝 3
AfterInstall
ApplicationStart
ValidateService
BeforeBlockTraffic
BlockTraffic3
AfterBlockTraffic
BeforeAllowTraffic
AllowTraffic3
AfterAllowTraffic

1 如需 Amazon EC2 Auto Scaling 部署的相關資訊,請參閱 亞馬遜 EC2 Auto Scaling 如何與 CodeDeploy

2 也適用於就地部署的復原。

3 預留用於 CodeDeploy 操作。無法用於執行指令碼。

在部署中執行掛鉤順序

Auto Scaling 啟動部署

在 Auto Scaling 啟動部署期間, 會以下列順序 CodeDeploy 執行事件掛鉤。

如需 Auto Scaling 啟動部署的詳細資訊,請參閱 亞馬遜 EC2 Auto Scaling 如何與 CodeDeploy

Auto Scaling 啟動部署期間的事件掛鉤順序。
注意

部署中的開始 DownloadBundle安裝 AllowTraffic、 和結束事件無法編寫指令碼,這就是為什麼它們在此圖表中以灰色顯示的原因。不過,您可以編輯 AppSpec 檔案的 'files'區段,以指定在安裝事件期間安裝的項目。

Auto Scaling 終止部署

在 Auto Scaling 終止部署期間, 會以下列順序 CodeDeploy 執行事件掛鉤。

如需 Auto Scaling 終止部署的詳細資訊,請參閱 在 Auto Scaling 擴充事件期間啟用終止部署

Auto Scaling 終止部署期間的事件掛鉤順序。
注意

部署中的開始 BlockTraffic結束 事件無法指令碼處理,這就是為什麼它們在此圖表中以灰色顯示的原因。

就地部署

在就地部署中,包括就地部署的復原,事件勾點以下列順序執行:

注意

對於就地部署,只有在部署群組中指定來自 Elastic Load Balancing 的 Classic Load Balancer、Application Load Balancer 或 Network Load Balancer 時,才會套用與封鎖和允許流量相關的六個掛鉤。

在現場部署復原期間的事件掛鉤順序。
注意

部署中的開始、DownloadBundle安裝 結束事件無法指令碼編寫,這就是為什麼它們在此圖表中以灰色顯示的原因。不過,您可以編輯 AppSpec 檔案的 'files'區段,以指定在安裝事件期間安裝的項目。

藍/綠部署

在藍/綠部署中,事件勾點以下列順序執行:

藍色/綠色部署中的事件掛鉤順序。
注意

部署中的開始、DownloadBundle安裝AllowTrafficBlockTraffic結束事件無法指令碼編寫,這就是為什麼它們在此圖表中以灰色顯示的原因。不過,您可以編輯 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 不會儲存密碼,因此如果 Runas 使用者需要密碼,就無法模擬使用者。此元素僅適用於 Amazon Linux 和 Ubuntu Server 執行個體。

參考掛鉤指令碼中的檔案

如果您要將指令碼掛鉤至 中所述的 CodeDeploy 生命週期事件AppSpec 「掛鉤」區段,而且想要參考指令碼中的檔案 (例如 helper.sh),則需要helper.sh使用下列方式指定 :

使用絕對路徑

若要使用檔案的絕對路徑來參考檔案,您可以:

部署封存位置

DownloadBundle生命週期事件期間, CodeDeploy 代理程式會將部署的修訂版本擷取到具有下列格式的目錄:

root-directory/deployment-group-id/deployment-id/deployment-archive

所以此 root-directory 路徑的 部分一律設定為下表所示的預設值,或由 :root_dir 組態設定控制。如需組態設定的詳細資訊,請參閱 CodeDeploy 用戶端組態參考

客服人員平台 預設根目錄
Linux – 所有 rpm 分佈 /opt/codedeploy-agent/deployment-root
Ubuntu 伺服器 – 所有 bb 分佈 /opt/codedeploy-agent/deployment-root
Windows Server %ProgramData%\Amazon\CodeDeploy

從掛鉤指令碼中,您可以使用根目錄路徑和 DEPLOYMENT_IDDEPLOYMENT_GROUP_ID環境變數來存取目前的部署封存。如需有關您可以使用之變數的詳細資訊,請參閱 勾點的環境變數可用性

例如,以下是您可以存取 Linux 修訂版根目錄data.json的檔案的方式:

#!/bin/bash rootDirectory="/opt/codedeploy-agent/deployment-root" # note: this will be different if you # customize the :root_dir configuration dataFile="$rootDirectory/$DEPLOYMENT_GROUP_ID/$DEPLOYMENT_ID/deployment-archive/data.json" data=$(cat dataFile)

作為另一個範例,以下是如何在 Windows 上使用 Powershell 存取位於修訂根data.json目錄的檔案:

$rootDirectory="$env:ProgramData\Amazon\CodeDeploy" # note: this will be different if you # customize the :root_dir configuration $dataFile="$rootDirectory\$env:DEPLOYMENT_GROUP_ID\$env:DEPLOYMENT_ID\deployment-archive\data.json" $data=(Get-Content $dataFile)

使用相對路徑

若要使用檔案的相對路徑來參考檔案,您需要知道 CodeDeploy 客服人員的工作目錄。檔案路徑與此目錄相關。

下表顯示 CodeDeploy 代理程式每個支援平台的工作目錄。

客服人員平台 程序管理方法 生命週期事件指令碼的工作目錄
Linux – 所有 rpm 分佈 系統化 (預設) /
init.d – 進一步了解 /opt/codedeploy-agent
Ubuntu Server – 所有 Debian 分佈 全部 /opt/codedeploy-agent
Windows Server 不適用 C:\Windows\System32

勾點的環境變數可用性

在每個部署生命週期事件期間,勾點指令碼能存取以下環境變數:

APPLICATION_NAME

中 CodeDeploy 屬於目前部署一部分的應用程式名稱 (例如 WordPress_App)。

DEPLOYMENT_ID

ID CodeDeploy 已指派給目前的部署 (例如 d-AB1CDEF23)。

DEPLOYMENT_GROUP_NAME

中 CodeDeploy 屬於目前部署一部分的部署群組名稱 (例如 WordPress_DepGroup)。

DEPLOYMENT_GROUP_ID

中 CodeDeploy 屬於目前部署一部分的部署群組 ID (例如 b1a2189b-dd90-4ef5-8f40-4c1c5EXAMPLE)。

LIFECYCLE_EVENT

目前部署生命週期事件的名稱 (例如,AfterInstall)。

這些環境變數在每個部署生命週期事件的本機。

根據部署套件的來源,還有其他環境變數可用於掛鉤指令碼:

Amazon S3 的套件

  • BUNDLE_BUCKET

    下載部署套件的 Amazon S3 儲存貯體名稱 (例如 my-s3-bucket)。

  • BUNDLE_KEY

    Amazon S3 儲存貯體中下載套件的物件金鑰 (例如 WordPress_App.zip)。

  • BUNDLE_VERSION

    套件的物件版本 (例如 3sL4kqtJlcpXroDTDmJ+rmSpXd3dIbrHY+MTRCxf3vjVBH40Nr8X8gdRQBpUMLUo)。只有在 Amazon S3 儲存貯體已啟用物件版本控制時,才會設定此變數。

  • BUNDLE_ETAG

    套件的物件標籤 (例如 b10a8db164e0754105b7a99be72e3fe5-4)。

來自 的套件 GitHub

  • BUNDLE_COMMIT

    Git 產生的套件SHA256遞交雜湊 (例如 d2a84f4b8b650937ec8f73cd8be2c74add5a911ba64df27458ed8229da804a26)。

如果 DEPLOYMENT_GROUP_NAME 的值等於 ,則下列指令碼會將 Apache HTTP伺服器上的接聽連接埠變更為 9090,而不是 80Staging。這個指令碼必須在 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