

# 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` プロパティを指定することもできます。これらのプロパティを使用すると、マクロの基盤となる Lambda 関数を呼び出すときに CloudFormation がエラーログ情報を送信する CloudWatch Logs ロググループを指定でき、またそれらのログにログエントリを送信するときに 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` などの変換は、アクションの順序と範囲の点で他のマクロと同じように扱われます。

例えば、以下のテンプレートサンプルでは、`PolicyAdder` マクロが最初に評価されます。テンプレート内で最も深くネストされているからです。次に、`AWS::Serverless` よりも先に `MyMacro` が評価されます。`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}}
```