本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
建立 Lambda 函數來評估 Lambda Hooks 的資源
CloudFormation Lambda Hooks 可讓您針對自己的自訂程式碼評估 CloudFormation 和 AWS 雲端控制 API 操作。您的勾點可以封鎖操作以繼續,或向發起人發出警告,並允許操作繼續。當您建立 Lambda Hook 時,您可以將其設定為攔截和評估下列 CloudFormation 操作:
-
資源操作
-
堆疊操作
-
變更集操作
開發 Lambda 勾點
當 Hooks 調用 Lambda 時,Lambda 最多會等待 30 秒來評估輸入。Lambda 將傳回 JSON 回應,指出勾點是否成功或失敗。
請求輸入
傳遞至 Lambda 函數的輸入取決於勾點目標操作 (範例:堆疊、資源或變更集)。
回應輸入
為了在請求成功或失敗時與 Hooks 通訊,您的 Lambda 函數需要傳回 JSON 回應。
以下是 Hooks 預期回應的範例形狀:
{ "hookStatus": "SUCCESS" or "FAILED" or "IN_PROGRESS", "errorCode": "NonCompliant" or "InternalFailure" "message": String, "clientRequestToken": String, "callbackContext": None, "callbackDelaySeconds": Integer, "註釋": [ { "annotationName": String, "status": "PASSED" or "FAILED" or "SKIPPED", "statusMessage": String, "remediationMessage": String, "remediationLink": String, "severityLevel": "INFORMATIONAL" or "LOW" or "MEDIUM" or "HIGH" or "CRITICAL" } ] }
- hookStatus
-
勾點的狀態。此為必要欄位。
有效值: (
SUCCESS|FAILED|IN_PROGRESS)注意
勾點可以傳回
IN_PROGRESS3 次。如果未傳回任何結果,勾點將會失敗。對於 Lambda 勾點,這表示您的 Lambda 函數最多可叫用 3 次。 - errorCode
-
顯示操作是否已評估並判斷為無效,或者如果勾點內發生錯誤,則阻止評估。如果勾點失敗,則此欄位為必要欄位。
有效值:(
NonCompliant|InternalFailure) - message
-
給發起人的訊息,說明勾點成功或失敗的原因。
注意
評估 CloudFormation 操作時,此欄位會截斷為 4096 個字元。
評估 Cloud Control API 操作時,此欄位會截斷為 1024 個字元。
- clientRequestToken
-
做為 Hook 請求輸入而提供的請求字符。此為必要欄位。
- callbackContext
-
如果您指出
hookStatus是IN_PROGRESS,則會傳遞在叫用 Lambda 函數時作為輸入提供的額外內容。 - callbackDelaySeconds
-
Hooks 應等待多久才再次叫用此 Hook。
- 註釋
-
註釋物件陣列,可提供進一步的詳細資訊和修補指引。
- annotationName
-
註釋的識別符。
- status
-
勾點調用狀態。當註釋代表具有類似 Guard 規則的通過/失敗評估的邏輯時,這很有幫助。
有效值: (
PASSED|FAILED|SKIPPED) - StatusMessage
-
特定狀態的說明。
- remediationMessage
-
修正
FAILED狀態的建議。例如,如果資源缺少加密,您可以陳述如何將加密新增至資源組態。 - remediationLink
-
用於其他修補指導的 HTTP URL。
- severityLevel
-
定義與此類型的任何違規相關的相對風險。將嚴重性等級指派給 Hook 調用結果時,您可以參考 AWS Security Hub 嚴重性架構做為如何建構有意義的嚴重性類別的範例。
有效值: (
INFORMATIONAL|LOW|MEDIUM|HIGH|CRITICAL)
範例
以下是成功回應的範例:
{ "hookStatus": "SUCCESS", "message": "compliant", "clientRequestToken": "123avjdjk31" }
以下是失敗回應的範例:
{ "hookStatus": "FAILED", "errorCode": "NonCompliant", "message": "S3 Bucket Versioning must be enabled.", "clientRequestToken": "123avjdjk31" }
使用 Lambda Hooks 評估資源操作
每當您建立、更新或刪除資源時,即視為資源操作。例如,如果您執行更新建立新資源的 CloudFormation 堆疊,表示您已完成資源操作。當您使用 Cloud Control API 建立、更新或刪除資源時,這也被視為資源操作。您可以將 CloudFormation Lambda Hook 設定為 Hook TargetOperations組態中的目標RESOURCE和CLOUD_CONTROL操作。
注意
只有在使用來自 Cloud Control API delete-resource或 CloudFormation 的操作觸發程序刪除資源時,才會叫用 delete Hook 處理常式delete-stack。
Lambda Hook 資源輸入語法
當您的 Lambda 被叫用進行資源操作時,您將會收到 JSON 輸入,其中包含資源屬性、提議的屬性,以及勾點叫用的相關內容。
以下是 JSON 輸入的範例形狀:
{ "awsAccountId": String, "stackId": String, "changeSetId": String, "hookTypeName": String, "hookTypeVersion": String, "hookModel": { "LambdaFunction": String }, "actionInvocationPoint": "CREATE_PRE_PROVISION" or "UPDATE_PRE_PROVISION" or "DELETE_PRE_PROVISION" "requestData": { "targetName": String, "targetType": String, "targetLogicalId": String, "targetModel": { "resourceProperties": {...}, "previousResourceProperties": {...} } }, "requestContext": { "叫用": 1, "callbackContext": null } }
awsAccountId-
AWS 帳戶 包含要評估之資源的 ID。
stackId-
此操作所屬 CloudFormation 堆疊的堆疊 ID。如果發起人是雲端控制 API,則此欄位為空白。
changeSetId-
啟動勾點調用的變更集 ID。如果資源變更是由 Cloud Control API 或
create-stack、update-stack或delete-stack操作啟動,則此值為空白。 hookTypeName-
正在執行的勾點名稱。
hookTypeVersion-
正在執行的 Hook 版本。
hookModel-
LambdaFunction-
Hook 調用的目前 Lambda ARN。
actionInvocationPoint-
Hook 執行所在佈建邏輯中的確切點。
有效值: (
CREATE_PRE_PROVISION|UPDATE_PRE_PROVISION|DELETE_PRE_PROVISION) requestData-
targetName-
正在評估的目標類型,例如
AWS::S3::Bucket。 targetType-
正在評估的目標類型,例如
AWS::S3::Bucket。對於使用 Cloud Control API 佈建的資源,此值將為RESOURCE。 targetLogicalId-
正在評估之資源的邏輯 ID。如果 Hook 調用的原始伺服器是 CloudFormation,這將是 CloudFormation 範本中定義的邏輯資源 ID。如果此 Hook 調用的原始伺服器是 Cloud Control API,這會是建構值。
targetModel-
resourceProperties-
正在修改之資源的提議屬性。如果正在刪除資源,則此值將為空。
previousResourceProperties-
目前與正在修改的資源相關聯的屬性。如果正在建立資源,則此值將為空。
requestContext-
- 叫用
-
目前執行勾點的嘗試。
- callbackContext
-
如果 Hookwas 設定為
IN_PROGRESS,且callbackContext傳回 ,則會在叫用後出現。
Lambda Hook 資源變更輸入範例
下列範例輸入顯示將接收要更新之AWS::DynamoDB::Table資源定義的 Lambda 勾點,其中 ReadCapacityUnitsProvisionedThroughput的 已從 3 變更為 10。這是可供 Lambda 評估的資料。
{ "awsAccountId": "123456789012", "stackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/MyStack/1a2345b6-0000-00a0-a123-00abc0abc000", "hookTypeName": "my::lambda::resourcehookfunction", "hookTypeVersion": "00000008", "hookModel": { "LambdaFunction": "arn:aws:lambda:us-west-2:123456789012:function:MyFunction" }, "actionInvocationPoint": "UPDATE_PRE_PROVISION", "requestData": { "targetName": "AWS::DynamoDB::Table", "targetType": "AWS::DynamoDB::Table", "targetLogicalId": "DDBTable", "targetModel": { "resourceProperties": { "AttributeDefinitions": [ { "AttributeType": "S", "AttributeName": "Album" }, { "AttributeType": "S", "AttributeName": "Artist" } ], "ProvisionedThroughput": { "WriteCapacityUnits": 5, "ReadCapacityUnits": 10 }, "KeySchema": [ { "KeyType": "HASH", "AttributeName": "Album" }, { "KeyType": "RANGE", "AttributeName": "Artist" } ] }, "previousResourceProperties": { "AttributeDefinitions": [ { "AttributeType": "S", "AttributeName": "Album" }, { "AttributeType": "S", "AttributeName": "Artist" } ], "ProvisionedThroughput": { "WriteCapacityUnits": 5, "ReadCapacityUnits": 5 }, "KeySchema": [ { "KeyType": "HASH", "AttributeName": "Album" }, { "KeyType": "RANGE", "AttributeName": "Artist" } ] } } }, "requestContext": { "invocation": 1, "callbackContext": null } }
若要查看資源類型可用的所有屬性,請參閱 AWS::DynamoDB::Table。
資源操作的範例 Lambda 函數
以下是 DynamoDB 的任何資源更新失敗的簡單函數,它會嘗試將 ReadCapacity 的 設定為大於 10 ProvisionedThroughput的 。如果勾點成功,訊息「ReadCapacity 已正確設定」將顯示給發起人。如果請求驗證失敗,勾點將會失敗,狀態為「ReadCapacity 不能超過 10。」
使用 Lambda Hooks 評估堆疊操作
每當您使用新範本建立、更新或刪除堆疊時,都可以透過評估新範本來設定 CloudFormation Lambda Hook,並可能封鎖堆疊操作以繼續。您可以在 Hook TargetOperations組態中將 CloudFormation Lambda Hook 設定為目標STACK操作。
Lambda Hook 堆疊輸入語法
叫用 Lambda 進行堆疊操作時,您將收到 JSON 請求,其中包含勾點叫用內容、 actionInvocationPoint和 請求內容。由於 CloudFormation 範本的大小,以及 Lambda 函數接受的有限輸入大小,實際範本會存放在 Amazon S3 物件中。的輸入requestData包含另一個物件的 Amazon S3 已簽章 URL,其中包含目前和先前的範本版本。
以下是 JSON 輸入的範例形狀:
{ "clientRequesttoken": String, "awsAccountId": String, "stackID": String, "changeSetId": String, "hookTypeName": String, "hookTypeVersion": String, "hookModel": { "LambdaFunction":String }, "actionInvocationPoint": "CREATE_PRE_PROVISION" or "UPDATE_PRE_PROVISION" or "DELETE_PRE_PROVISION" "requestData": { "targetName": "STACK", "targetType": "STACK", "targetLogicalId": String, "payload": String (S3 Presigned URL) }, "requestContext": { "invocation": Integer, "callbackContext": String } }
clientRequesttoken-
做為 Hook 請求輸入而提供的請求字符。此為必要欄位。
awsAccountId-
AWS 帳戶 包含要評估之堆疊的 ID。
stackID-
CloudFormation 堆疊的堆疊 ID。
changeSetId-
啟動勾點調用的變更集 ID。如果堆疊變更是由 Cloud Control API 或
create-stack、update-stack或delete-stack操作啟動,則此值為空白。 hookTypeName-
正在執行的勾點名稱。
hookTypeVersion-
正在執行的 Hook 版本。
hookModel-
LambdaFunction-
Hook 調用的目前 Lambda ARN。
actionInvocationPoint-
Hook 執行所在佈建邏輯中的確切點。
有效值: (
CREATE_PRE_PROVISION|UPDATE_PRE_PROVISION|DELETE_PRE_PROVISION) requestData-
targetName-
此值將為
STACK。 targetType-
此值將為
STACK。 targetLogicalId-
堆疊名稱。
payload-
Amazon S3 預先簽章的 URL,其中包含具有目前和先前範本定義的 JSON 物件。
requestContext-
如果正在重新叫用勾點,則會設定此物件。
invocation-
目前執行勾點的嘗試。
callbackContext-
如果勾點設定為
callbackContextIN_PROGRESS並傳回,則會在叫用時出現。
請求資料中的 payload 屬性是您程式碼需要擷取的 URL。一旦收到 URL,您會取得具有下列結構描述的物件:
{ "template": String, "previousTemplate": String }
template-
提供給
create-stack或 的完整 CloudFormation 範本update-stack。根據提供給 CloudFormation 的內容,它可以是 JSON 或 YAML 字串。在
delete-stack操作中,此值將為空。 previousTemplate-
先前的 CloudFormation 範本。根據提供給 CloudFormation 的內容,它可以是 JSON 或 YAML 字串。
在
delete-stack操作中,此值將為空。
Lambda Hook 堆疊變更輸入範例
以下是堆疊變更輸入的範例。Hook 正在評估將 更新ObjectLockEnabled為 true 的變更,並新增 Amazon SQS 佇列:
{ "clientRequestToken": "f8da6d11-b23f-48f4-814c-0fb6a667f50e", "awsAccountId": "123456789012", "stackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/MyStack/1a2345b6-0000-00a0-a123-00abc0abc000", "changeSetId": null, "hookTypeName": "my::lambda::stackhook", "hookTypeVersion": "00000008", "hookModel": { "LambdaFunction": "arn:aws:lambda:us-west-2:123456789012:function:MyFunction" }, "actionInvocationPoint": "UPDATE_PRE_PROVISION", "requestData": { "targetName": "STACK", "targetType": "STACK", "targetLogicalId": "my-cloudformation-stack", "payload": "https://s3......" }, "requestContext": { "invocation": 1, "callbackContext": null } }
這是 payload的範例requestData:
{ "template": "{\"Resources\":{\"S3Bucket\":{\"Type\":\"AWS::S3::Bucket\",\"Properties\":{\"ObjectLockEnabled\":true}},\"SQSQueue\":{\"Type\":\"AWS::SQS::Queue\",\"Properties\":{\"QueueName\":\"NewQueue\"}}}}", "previousTemplate": "{\"Resources\":{\"S3Bucket\":{\"Type\":\"AWS::S3::Bucket\",\"Properties\":{\"ObjectLockEnabled\":false}}}}" }
堆疊操作的範例 Lambda 函數
下列範例是一個簡單的 函數,可下載堆疊操作承載、剖析範本 JSON,並傳回 SUCCESS。
使用 Lambda Hooks 評估變更集操作
每當您建立變更集時,都可以設定 CloudFormation Lambda Hook 來先評估新的變更集,並可能封鎖其執行。您可以在 Hook TargetOperations組態中將 CloudFormation Lambda Hook 設定為目標CHANGE_SET操作。
Lambda Hook 變更集輸入語法
變更集操作的輸入類似於堆疊操作,但 的承載requestData也包含變更集引入的資源變更清單。
以下是 JSON 輸入的範例形狀:
{ "clientRequesttoken": String, "awsAccountId": String, "stackID": String, "changeSetId": String, "hookTypeName": String, "hookTypeVersion": String, "hookModel": { "LambdaFunction":String }, "requestData": { "targetName": "CHANGE_SET", "targetType": "CHANGE_SET", "targetLogicalId": String, "payload": String (S3 Presigned URL) }, "requestContext": { "invocation": Integer, "callbackContext": String } }
clientRequesttoken-
做為 Hook 請求輸入而提供的請求字符。此為必要欄位。
awsAccountId-
AWS 帳戶 包含要評估之堆疊的 ID。
stackID-
CloudFormation 堆疊的堆疊 ID。
changeSetId-
啟動勾點調用的變更集 ID。
hookTypeName-
正在執行的勾點名稱。
hookTypeVersion-
正在執行的 Hook 版本。
hookModel-
LambdaFunction-
Hook 調用的目前 Lambda ARN。
requestData-
targetName-
此值將為
CHANGE_SET。 targetType-
此值將為
CHANGE_SET。 targetLogicalId-
變更集 ARN。
payload-
Amazon S3 預先簽章的 URL,其中包含具有目前範本的 JSON 物件,以及此變更集引進的變更清單。
requestContext-
如果正在重新叫用勾點,則會設定此物件。
invocation-
目前執行勾點的嘗試。
callbackContext-
如果勾點設定為
IN_PROGRESS並callbackContext傳回,則會在叫用時出現。
請求資料中的 payload 屬性是您程式碼需要擷取的 URL。收到 URL 後,您會取得具有下列結構描述的物件:
{ "template": String, "changedResources": [ { "action": String, "beforeContext": JSON String, "afterContext": JSON String, "lineNumber": Integer, "logicalResourceId": String, "resourceType": String } ] }
template-
提供給
create-stack或 的完整 CloudFormation 範本update-stack。根據提供給 CloudFormation 的內容,它可以是 JSON 或 YAML 字串。 changedResources-
已變更資源的清單。
action-
套用至資源的變更類型。
有效值: (
CREATE|UPDATE|DELETE) beforeContext-
變更前資源屬性的 JSON 字串。建立資源時,此值為 null。此 JSON 字串中的所有布林值和數值都是 STRINGS。
afterContext-
如果執行此變更集,資源屬性的 JSON 字串。正在刪除資源時,此值為 null。此 JSON 字串中的所有布林值和數值都是 STRINGS。
lineNumber-
範本中造成此變更的行號。如果動作是 ,則
DELETE此值將為 null。 logicalResourceId-
要變更之資源的邏輯資源 ID。
resourceType-
正在變更的資源類型。
Lambda Hook 變更集變更輸入範例
以下是變更集變更輸入的範例。在下列範例中,您可以查看變更集引進的變更。第一個變更是刪除名為 的佇列CoolQueue。第二個變更是新增名為 的新佇列NewCoolQueue。上次變更是 的更新DynamoDBTable。
{ "clientRequestToken": "f8da6d11-b23f-48f4-814c-0fb6a667f50e", "awsAccountId": "123456789012", "stackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/MyStack/1a2345b6-0000-00a0-a123-00abc0abc000", "changeSetId": "arn:aws:cloudformation:us-west-2:123456789012:changeSet/SampleChangeSet/1a2345b6-0000-00a0-a123-00abc0abc000", "hookTypeName": "my::lambda::changesethook", "hookTypeVersion": "00000008", "hookModel": { "LambdaFunction": "arn:aws:lambda:us-west-2:123456789012:function:MyFunction" }, "actionInvocationPoint": "CREATE_PRE_PROVISION", "requestData": { "targetName": "CHANGE_SET", "targetType": "CHANGE_SET", "targetLogicalId": "arn:aws:cloudformation:us-west-2:123456789012:changeSet/SampleChangeSet/1a2345b6-0000-00a0-a123-00abc0abc000", "payload": "https://s3......" }, "requestContext": { "invocation": 1, "callbackContext": null } }
這是 payload的範例requestData.payload:
{ template: 'Resources:\n' + ' DynamoDBTable:\n' + ' Type: AWS::DynamoDB::Table\n' + ' Properties:\n' + ' AttributeDefinitions:\n' + ' - AttributeName: "PK"\n' + ' AttributeType: "S"\n' + ' BillingMode: "PAY_PER_REQUEST"\n' + ' KeySchema:\n' + ' - AttributeName: "PK"\n' + ' KeyType: "HASH"\n' + ' PointInTimeRecoverySpecification:\n' + ' PointInTimeRecoveryEnabled: false\n' + ' NewSQSQueue:\n' + ' Type: AWS::SQS::Queue\n' + ' Properties:\n' + ' QueueName: "NewCoolQueue"', changedResources: [ { logicalResourceId: 'SQSQueue', resourceType: 'AWS::SQS::Queue', action: 'DELETE', lineNumber: null, beforeContext: '{"Properties":{"QueueName":"CoolQueue"}}', afterContext: null }, { logicalResourceId: 'NewSQSQueue', resourceType: 'AWS::SQS::Queue', action: 'CREATE', lineNumber: 14, beforeContext: null, afterContext: '{"Properties":{"QueueName":"NewCoolQueue"}}' }, { logicalResourceId: 'DynamoDBTable', resourceType: 'AWS::DynamoDB::Table', action: 'UPDATE', lineNumber: 2, beforeContext: '{"Properties":{"BillingMode":"PAY_PER_REQUEST","AttributeDefinitions":[{"AttributeType":"S","AttributeName":"PK"}],"KeySchema":[{"KeyType":"HASH","AttributeName":"PK"}]}}', afterContext: '{"Properties":{"BillingMode":"PAY_PER_REQUEST","PointInTimeRecoverySpecification":{"PointInTimeRecoveryEnabled":"false"},"AttributeDefinitions":[{"AttributeType":"S","AttributeName":"PK"}],"KeySchema":[{"KeyType":"HASH","AttributeName":"PK"}]}}' } ] }
變更集操作的範例 Lambda 函數
下列範例是一個簡單的 函數,可下載變更集操作承載、逐一查看每個變更,然後在傳回 之前列印屬性前後的 SUCCESS。