

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

# 建立 CloudFormation 巨集定義
<a name="template-macros-author"></a>

當您建立巨集定義時，巨集定義會在指定的帳戶中提供基礎 Lambda 函式，供 CloudFormation 調用以處理範本。

## 事件映射
<a name="template-macros-event-mapping"></a>

當 CloudFormation 調用巨集的 Lambda 函式時，會傳送 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` 函數除外) 在範本內的位置為基礎的所有同級節點 (及其子系)。如需詳細資訊，請參閱[巨集的範本範圍](#template-macros-scope)。
+ `transformId`

  叫用此函數的巨集的名稱。
+ `params`

  若為 `Fn::Transform` 函數呼叫，則為該函數指定的任何參數。CloudFormation 不會在將這些參數傳遞至 函數之前對其進行評估。

  對於 `Transform` 範本區段包含的巨集，這個區段是空的。
+ `requestId`

  叫用此函數的請求的 ID。
+ `templateParameterValues`

  範本 [Parameters](parameters-section-structure.md) 區段中指定的任何參數。CloudFormation 會在將這些參數傳遞至函數之前對其進行評估。

## 回應格式
<a name="template-macros-response-format"></a>

CloudFormation 期望 Lambda 函式傳回的回應是下列 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 會在堆疊 **Stack details** (堆疊詳細資訊) 頁面的 **Events** (事件) 窗格中顯示此錯誤訊息。

  例如：

  ```
  Error creating change set: Transform
                              {{AWS 帳戶 account
                              number}}::{{macro name}} failed with:
                              {{error message string}}.
  ```

## 建立巨集定義
<a name="create-a-macro-definition"></a>

**建立 CloudFormation 巨集定義**

1. [建置 Lambda 函式](https://docs.aws.amazon.com/lambda/latest/dg/getting-started.html)，用於處理範本內容的處理。它可以處理範本的任何部分，甚至整個範本。

1. 建立包含 `AWS::CloudFormation::Macro` 資源類型的 CloudFormation 範本，並指定 `Name` 和 `FunctionName` 屬性。`FunctionName` 屬性必須包含當 CloudFormation 執行巨集時調用的 Lambda 函式的 ARN。

1. (選用) 為了協助除錯，當您為巨集建立 `AWS::CloudFormation::Macro` 資源類型時，您也可以指定 `LogGroupName` 和 `LogRoleArn` 屬性。這些屬性可讓您指定 CloudWatch Logs 日誌群組，供 CloudFormation 在調用巨集的基礎 Lambda 函式時傳送錯誤日誌記錄資訊，也可指定 CloudFormation 將日誌項目傳送到這些日誌時應該擔任的角色。

1. 在您要使用它的帳戶中，使用具有巨集的範本[建立堆疊](cfn-console-create-stack.md)。或者，在管理員帳戶中使用包含該巨集的範本，[建立具有自我管理許可的堆疊集](stacksets-getting-started-create-self-managed.md)，然後在目標帳戶中建立堆疊執行個體。

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

## 巨集的範本範圍
<a name="template-macros-scope"></a>

範本的 `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
```

## 巨集評估順序
<a name="template-macros-order"></a>

您可以在給定的範本中參考多個巨集，包括由 CloudFormation 託管的轉換，例如 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/transform-aws-include.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/transform-aws-include.html) 和 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/transform-aws-serverless.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/transform-aws-serverless.html)。

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

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

例如，在以下範本範例中，CloudFormation 會先評估 `PolicyAdder` 巨集，因為它是範本中最深層巢狀的巨集。然後，CloudFormation 會評估 `MyMacro`，再評估 `AWS::Serverless`，因為它在 `Transform` 區段中列在 `AWS::Serverless` 前面。

```
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}}
```