使用範本巨集對 CloudFormation 範本執行自訂處理 - AWS CloudFormation

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

使用範本巨集對 CloudFormation 範本執行自訂處理

巨集可讓您對範本執行自訂處理,從簡單的動作 (例如作 find-and-replace 業) 到整個範本的大量轉換。

要了解可能性的廣度,請考慮AWS::IncludeAWS::Serverless轉換,它們是由 CloudFormation以下主控的宏:

CloudFormation 巨集的運作方式

使用巨集處理範本有兩個主要步驟:建立巨集本身,然後使用巨集在您的範本上執行處理。

若要建立巨集定義,您需要建立下列項目:

  • 同時 AWS Lambda 執行模板處理的功能。此 Lambda 函數接受程式碼片段或整個範本,以及您定義的任何其他參數。它會傳回已處理的範本程式碼片段或整個範本作為回應。

  • 類型的資源 AWS::CloudFormation::Macro,這可讓使用者從 CloudFormation 範本中呼叫 Lambda 函數。此資源指定ARN要為此巨集叫用的 Lambda 函數,以及其他選用屬性以協助偵錯。若要在帳號內建立此資源,請撰寫包含該AWS::CloudFormation::Macro資源的範本,然後從範本建立具有自我管理權限的堆疊或堆疊集。 AWS CloudFormation StackSets目前不支援從參考巨集的範本建立或更新具有服務管理權限的堆疊集。

若要使用巨集,請在範本中參考巨集:

  • 若要處理範本的區或程式碼片段,請在 函數位於相對於您要轉換的模板內容。當您使用 Fn::Transform 時,您也可以傳遞它需要的任何指定參數。

  • 若要處理整個範本,請在範本的 Transform 區段中參考巨集。

接著,您通常會建立變更集,然後加以執行。(處理宏可以添加多個您可能不知道的資源。 為了確保您知道巨集引入的所有變更,我們強烈建議您使用變更集。) CloudFormation 將指定的範本內容與任何其他指定的參數一起傳遞至巨集資源中指定的 Lambda 函數。Lambda 函數會傳回已處理的範本內容,不論是程式碼片段或整個範本。

呼叫樣板中的所有巨集之後, CloudFormation 會產生包含已處理範本內容的變更集。檢閱變更集之後,請執行它來套用變更。

重要

如果您的堆疊集範本參考了一或多個巨集,您必須直接從處理的範本建立堆疊集,而不必先檢視變更集中產生的變更。若要直接建立或更新堆疊集,您必須使用CreateStackSetUpdateStackSet動作並指定CAPABILITY_AUTO_EXPAND功能。從直接參考巨集的範本建立或更新堆疊集之前,請確定您知道巨集會執行哪些處理操作。

使用Fn::Transform內部函數或模板的Transform部分,將模板內容和關聯參數傳遞給宏的基礎 Lambda 函數,返回處理過的模板內容。
注意

如果您可以直接透過處理範本安心建立或更新堆疊,無需先在變更集中審核建議的變更,則可在 CreateStackUpdateStack 請求中指定 CAPABILITY_AUTO_EXPAND 功能這麼做。如果您知道巨集會執行哪些處理,您應只直接透過參考巨集的範本來建立堆疊。

若要取得更多資訊,請參閱UpdateStack中的CreateStackAWS CloudFormation API參考

建立 CloudFormation 巨集定義

當您建立巨集定義時,巨集定義會在指定的帳戶中使用基礎 Lambda 函數,以便 CloudFormation 叫用它來處理範本。

CloudFormation 宏功能界面

對於巨集,請使用下列事件對應 CloudFormation 來叫用基礎 Lambda 函數。 CloudFormation 以JSON格式發送其請求,並且它希望函數響應JSON也被格式化。

{ "region" : "us-east-1", "accountId" : "$ACCOUNT_ID", "fragment" : { ... }, "transformId" : "$TRANSFORM_ID", "params" : { ... }, "requestId" : "$REQUEST_ID", "templateParameterValues" : { ... } }
  • region

    巨集所在的區域。

  • accountId

    供巨集用來叫用 Lambda 函數的帳戶的帳戶 ID。

  • fragment

    可用於自訂處理的範本內容 (JSON格式為單位)。

    • 對於 Transform 範本區段包含的巨集,這是整個範本 (Transform 區段除外)。

    • 對於 Fn::Transform 內部函數呼叫包含的巨集,這包括以內部函數 (Fn::Transform 函數除外) 在範本內的位置為基礎的所有同級節點 (及其子系)。如需詳細資訊,請參閱CloudFormation 巨集範圍

  • transformId

    叫用此函數的巨集的名稱。

  • params

    對於Fn::Transform函數調用,該函數的任何指定參數。 CloudFormation 在將這些參數傳遞給函數之前,不會評估這些參數。

    對於 Transform 範本區段包含的巨集,這個區段是空的。

  • requestId

    叫用此函數的請求的 ID。

  • templateParameterValues

    範本Parameters區段中指定的任何參數。 CloudFormation 在將這些參數傳遞給函數之前評估這些參數。

CloudFormation 預期基礎函數以下列JSON格式傳回回應:

{ "requestId" : "$REQUEST_ID", "status" : "$STATUS", "fragment" : { ... } "errorMessage": "optional error message for failures" }
  • requestId

    叫用此函數的請求的 ID。這必須與叫用函數 CloudFormation 時提供的要求 ID 相符。

  • status

    請求的狀態 (不區分大小寫)。應該設定為success。 CloudFormation 將任何其他回應視為失敗。

  • fragment

    CloudFormation 要包含在已處理範本中的已處理範本內容,包括同層級。 CloudFormation 將傳遞至 Lambda 函數的範本內容取代為在 Lambda 回應中收到的範本片段。

    處理過的範本內容必須有效JSON,且其包含在已處理的範本中必須產生有效的範本。

    如果您的函數實際上並未更改 CloudFormation傳遞給它的模板內容,但是您仍然需要在處理過的模板中包含該內容,則您的函數需要在其響應 CloudFormation 中將該模板內容返回到該模板內容。

  • errorMessage

    說明轉換失敗原因的錯誤訊息。 CloudFormation在堆疊的 [堆疊詳細資料] 頁面的 [事件] 窗格中顯示此錯誤訊息。

    例如,「建立變更集時發生錯誤:轉換 AWS 帳戶 account number::macro name 失敗:error message string".

如需建立巨集時其他考量的相關資訊,請參閱建立 CloudFormation 巨集定義時的考量

CloudFormation 巨集帳戶範圍和權限

巨集只能在它們已建立為資源的帳戶中使用。巨集的名稱在給定帳戶內必須是唯一的。不過,您可以在基礎 Lambda 函數上啟用跨帳戶存取,然後建立巨集定義在多個帳戶中參考該函數,就能讓多個帳戶使用相同的功能。在下列範例中,三個帳戶包含巨集定義,各指向相同的 Lambda 函數。

通過允許跨帳戶訪問 Lambda 功能, AWS 可讓您在參考該函數的多個帳戶中建立巨集。

如需詳細資訊,請參閱管理您的存取權限概觀 AWS中的 Lambda 資源 AWS Lambda 開發人員指南

為了建立巨集定義,使用者必須有許可,才能在指定的帳戶內建立堆疊或堆疊集。

若 CloudFormation 要成功執行範本中包含的巨集,使用者必須擁有基礎 Lambda 函數的Invoke權限。若要防止潛在的權限提升,請在執行巨 CloudFormation 集時模擬使用者。如需詳細資訊,請參閱 AWS Lambda 開發人員指南操作以及條件上下文鍵 AWS Lambda (在 IAM 使用者指南中)

AWS::Serverless 轉換程序和轉AWS::Include 轉換程序換是由主控的巨集 CloudFormation。不需要特殊權限即可使用它們,而且可以從中的任何帳戶中取得這些權限 CloudFormation。

偵錯 CloudFormation 巨集

為了協助除錯,當您為巨集建立 AWS::CloudFormation::Macro 資源類型時,您也可以指定 LogGroupNameLogRoleArn 屬性。這些內容可讓您指定在 CloudWatch 呼叫巨集的基礎資訊時, CloudFormation 將錯誤記錄資訊傳送至的記錄群組 AWS Lambda 功能,並且在將日誌條目發送到這些日誌時 CloudFormation 應該承擔角色。

帳單

當巨集執行時,Lambda 函數的擁有者需要支付執行該函數的任何相關費用。

AWS::Serverless 轉換程序和轉AWS::Include 轉換程序換是由主控的巨集 CloudFormation。可免費使用它們。

建立 CloudFormation 巨集定義時的考量

建立巨集定義時,請謹記下列事項:

  • 巨集僅支援 AWS 區域 where AWS Lambda 是可用的。如需可使用 Lambda 的區域清單,請參閱 AWS Lambda 端點和配額

  • 任何已處理的範本片段都必須有效JSON。

  • 任何處理的範本程式碼片段都必須通過建立堆疊、更新堆疊、建立堆疊集或更新堆疊集操作的驗證檢查。

  • CloudFormation 先解析巨集,然後處理範本。產生的範本必須有效JSON且不得超過範本大小限制。

  • 由於處理範本中元素的順 CloudFormation 序,巨集無法在其傳回的已處理範本內容中包含模組 CloudFormation。如需有關模組的詳細資訊,請參閱CloudFormation CLI使用指南中的「開發模組」。

  • 使用更新復原功能時, CloudFormation 會使用原始範本的複本。即使加入的程式碼片段有所變更,它也會復原至原始範本。

  • 在宏中包含宏不起作用,因為我們不遞歸處理宏。

  • 巨集內目前不支援 Fn::ImportValue 內部函數。

  • 範本包含的內部函數是在任何巨集之後評估。因此,巨集傳回的已處理範本內容可能包含內部函數的呼叫,一樣照常評估。

  • StackSets 目前不支援從參考 CloudFormation巨集的範本建立或更新具有服務管理權限的堆疊集。

  • 如果您的堆疊集範本參考一或多個巨集,您必須直接從處理的範本建立或更新堆疊集,而不必先檢視變更集中產生的變更。若要直接建立或更新堆疊集,請使用CreateStackSetUpdateStackSet動作並指定CAPABILITY_AUTO_EXPAND功能。處理巨集可能會新增您不了解的多個資源。從直接參考巨集的範本建立或更新堆疊集之前,請確定您知道巨集會執行哪些處理操作。

  • 變更集目前不支援巢狀堆疊。如果您要使用參考巨集包含巢狀堆疊的堆疊範本來建立或更新堆疊,您必須直接建立或更新堆疊。若要執行此操作,請使用CreateStackUpdateStack動作並指定CAPABILITY_AUTO_EXPAND權能。

若要建立 CloudFormation 巨集定義:
  1. 建立一個 AWS Lambda 處理 CloudFormation 模板的函數。

    您建置的 Lambda 函數會執行範本內容的處理。您的函數可以處理範本的任何部分,甚至整個範本。如需您的函數必須遵循的事件映射的詳細資訊,請參閱 CloudFormation 宏功能界面。如需建立巨集時其他考量的相關資訊,請參閱建立 CloudFormation 巨集定義時的考量

  2. 建立包含AWS::CloudFormation::Macro資源類型的範本

    • 您必須指定 NameFunctionName 屬性。該FunctionName屬性指定 CloudFormation 運行宏時調用ARN的 Lambda 函數的。

    • 為了協助除錯,您也可以指定 LogGroupNameLogRoleArn 屬性。

  3. 從包含所需帳戶中巨集的範本建立堆疊,或從範本建立具有自我管理許可的堆疊集,參考管理員帳戶中的巨集,然後在所需的目標帳戶中建立堆疊執行個體。

    CloudFormation 成功建立包含巨集定義的堆疊後,即可在這些帳戶中使用巨集。

在範本中使用 CloudFormation 巨集

CloudFormation 成功建立包含巨集定義的堆疊後,即可在這些帳戶中使用巨集。在範本中,請在您要處理的範本內容的相對適當位置上參考巨集,以此來使用巨集。

CloudFormation 巨集評估順序

您可以參考指定範本中的多個巨集,包括由主控的轉換 CloudFormation,例如AWS::Include 轉換程序AWS::Serverless 轉換程序

巨集是根據在範本中的位置而依序評估,從最深巢狀往外到最通用。範本中同一位置的巨集是根據它們所列順序而按順序評估。

在動作順序和範圍方面,轉換 (例如 AWS::IncludeAWS::Transform) 與任何其他巨集視為相同。

例如,在以下範本範例中, CloudFormation 會先評估PolicyAdder巨集,因為它是範本中巢狀最深的巨集。 CloudFormation 然後在評估MyMacro之前進行評估,AWS::Serverless因為它AWS::ServerlessTransform部分之前列出。

AWSTemplateFormatVersion: 2010-09-09 Transform: [MyMacro, AWS::Serverless] Resources: WaitCondition: Type: AWS::CloudFormation::WaitCondition MyBucket: Type: 'AWS::S3::Bucket' Properties: BucketName: amzn-s3-demo-bucket Tags: [{"key":"value"}] 'Fn::Transform': - Name: PolicyAdder CorsConfiguration: [] MyEc2Instance: Type: 'AWS::EC2::Instance' Properties: ImageID: ami-1234567890abcdef0

CloudFormation 巨集範圍

範本的 Transform 區段中參考的巨集可以處理該範本的整個內容。

Fn::Transform 函數中參考的巨集可以處理該 Fn::Transform 函數在範本中的任何同級元素 (包括子系) 的內容。

例如,在以下範本範例中,AWS::Include 可以根據其所在 Fn::Transform 函數的位置,而處理所有 MyBucket 屬性。MyMacro 可以處理整個範本的內容,因為它已納入 Transform 區段中。

# Start of processable content for MyMacro AWSTemplateFormatVersion: 2010-09-09 Transform: [MyMacro] Resources: WaitCondition: Type: AWS::CloudFormation::WaitCondition MyBucket: Type: 'AWS::S3::Bucket' # Start of processable content for AWS::Include Properties: BucketName: amzn-s3-demo-bucket1 Tags: [{"key":"value"}] 'Fn::Transform': - Name: 'AWS::Include' Parameters: Location: s3://amzn-s3-demo-bucket2/MyFileName.yaml CorsConfiguration: [] # End of processable content for AWS::Include MyEc2Instance: Type: 'AWS::EC2::Instance' Properties: ImageID: ami-1234567890abcdef0 # End of processable content for MyMacro

變更集合和 CloudFormation 巨集

若要使用參考巨集的範本來建立或更新堆疊,您通常會建立變更集,然後執行它。變更集描述 CloudFormation 將根據已處理的範本採取的動作。處理巨集可能會新增您不了解的多個資源。為了確保您知道巨集所產生的所有變更,我們強烈建議您使用變更集。檢閱變更集之後,您可以執行它來確實套用變更。

巨集可以將IAM資源新增至您的範本。對於這些資源, CloudFormation需要您確認其功能。由於在處理範本之前 CloudFormation 無法知道要新增哪些資源,因此您可能需要在建立變更集時確認IAM功能,具體取決於參考的巨集是否包含IAM資源。如此一來,當您執行變更集時,就 CloudFormation 具有建立IAM資源的必要功能。

重要

如果您的堆疊集範本參考了一或多個巨集,您必須直接從處理的範本建立堆疊集,而不必先檢視變更集中產生的變更。若要直接建立或更新堆疊集,您必須使用CreateStackSetUpdateStackSet動作並指定CAPABILITY_AUTO_EXPAND功能。從直接參考巨集的範本建立或更新堆疊集之前,請確定您知道巨集會執行哪些處理操作。

注意

如果您可以直接透過處理範本安心建立或更新堆疊,無需先在變更集中審核建議的變更,則可在 CreateStackUpdateStack 請求中指定 CAPABILITY_AUTO_EXPAND 功能這麼做。如果您知道巨集執行哪些處理,您應只直接透過包含巨集的堆疊範本來建立堆疊。您不能將變更集與堆疊集巨集一起使用;您必須直接更新堆疊集。

若要取得更多資訊,請參閱UpdateStack中的CreateStackAWS CloudFormation API參考

如果您使用 AWS CLI,您可以使用packagedeploy指令減少從參考巨集的範本啟動堆疊的步驟數。如需詳細資訊,請參閱部署以 Lambda 為基礎的應用程式 AWS Lambda 開發人員指南

範本階段和 CloudFormation 巨集

範本的階段會指出範本是原始使用者提交的範本,還是 CloudFormation 已經處理巨集的範本。

  • Original:使用者最初提交以建立或更新堆疊或堆疊集的範本。

  • Processed: CloudFormation 用於在處理任何引用的宏後創建或更新堆棧或堆棧集的模板。即使原始範本的格式為JSON,已處理的範本也會格式化為YAML。

使用處理過的範本針對堆疊問題進行故障診斷。如果範本未參考巨集,則原始範本和處理過的範本會相同。

您可以使用控 CloudFormation 制台AWS CLI查看堆棧模板的階段。

注意

直接傳入CreateStackUpdateStackValidateTemplate請求時,已處理堆疊範本的大小上限為 51,200 位元組,或使用 Amazon S3 範本URL作為 S3 物件傳送時為 1 MB。但是,在處理 CloudFormation 期間,範本會依序處理範本中包含的巨集而更新暫時狀態。因此,在處理期間範本的大小可能會暫時超過完整處理範本的允許大小。 CloudFormation 允許這些進程中的模板的一些緩衝區。不過,您在設計範本和巨集時應謹記處理堆疊範本的允許大小上限。

如果在處理範本時 CloudFormation 傳回Transformation data limit exceeded錯誤,表示您的範本已超過處理期間 CloudFormation 允許的範本大小上限。

若要解決這個問題,請考量下列解決方案:

在範本中使用 CloudFormation 巨集的步驟
注意

若 CloudFormation 要成功執行範本中參考的巨集,使用者必須擁有基礎 Lambda 函數的Invoke權限。如需詳細資訊,請參閱管理您的存取權限概觀 AWS中的 Lambda 資源 AWS Lambda 開發人員指南

  1. 在範本中包含巨集的參考。

    • 若要處理範本程式碼片段,請在 Fn::Transform 函數 (位置相對於您想要處理的範本內容) 中參考巨集。

    • 若要處理整個範本,請在範本的 Transform 區段中參考巨集。

  2. 使用範本建立變更集

    重要

    如果您的堆疊集範本參考了一或多個巨集,您必須直接從處理的範本建立堆疊集,而不必先檢視變更集中產生的變更。若要直接建立或更新堆疊集,您必須使用CreateStackSetUpdateStackSet動作並指定CAPABILITY_AUTO_EXPAND功能。從直接參考巨集的範本建立或更新堆疊集之前,請確定您知道巨集會執行哪些處理操作。

  3. 檢閱和執行變更集

    重要

    如果您的堆疊集範本參考了一或多個巨集,您必須直接從處理的範本建立堆疊集,而不必先檢視變更集中產生的變更。若要直接建立或更新堆疊集,您必須使用CreateStackSetUpdateStackSet動作並指定CAPABILITY_AUTO_EXPAND功能。從直接參考巨集的範本建立或更新堆疊集之前,請確定您知道巨集會執行哪些處理操作。

巨集範例

除了本指南中的巨集範例:建立和使用巨集逐步解說之外,您還可以在我們的GitHub 儲存庫中找到範例巨集,包括原始程式碼和範本。這些範例「按現狀」提供作為教學用途。

另請參閱

AWS::CloudFormation: 巨集

Transform

Fn::Transform

AWS::Serverless 轉換程序

AWS::Include 轉換程序