💾 Archived View for cfdocs.wetterberg.nu › template-macros.gemini captured on 2024-03-21 at 15:25:41. Gemini links have been rewritten to link to archived content
⬅️ Previous capture (2021-12-03)
-=-=-=-=-=-=-
Macros enable you to perform custom processing on templates, from simple actions like find-and-replace operations to extensive transformations of entire templates.
To get an idea of the breadth of possibilities, consider the `AWS::Include` and `AWS::Serverless` transforms, which are macros hosted by AWS CloudFormation:
Deploying Lambda-based applications
There are two major steps to processing templates using macros: *creating* the macro itself, and then *using* the macro to perform processing on your templates.
To create a macro definition, you need to create the following:
To use a macro, reference the macro in your template:
Next, you typically create a change set and then execute it. (Processing macros can add multiple resources that you might not be aware of. To ensure that you're aware of all of the changes introduced by macros, we strongly advise that you use change sets.) AWS CloudFormation passes the specified template content, along with any additional specified parameters, to the Lambda function specified in the macro resource. The Lambda function returns the processed template content, be it a snippet or an entire template.
After all macros in the template have been called, AWS CloudFormation generates a change set that includes the processed template content. After you review the change set, execute it to apply the changes.
{P Image}
If you are comfortable creating or updating a stack directly from a processed template, without first reviewing the proposed changes in a change set, you can do so by specifying the `CAPABILITY_AUTO_EXPAND` capability during a `CreateStack` or `UpdateStack` request. You should only create stacks directly from a stack template that contains macros if you know what processing the macro performs.
In addition, change sets do not currently support nested stacks. If you want to create a stack from a stack template that contains macros and nested stacks, you must create the stack directly from the template using this capability.
For more information, see CreateStack or UpdateStack in the *AWS CloudFormation API Reference*.
When you create a macro definition, the macro definition makes the underlying Lambda function available in the specified account so that AWS CloudFormation can invokes it to process the templates.
For macros, AWS CloudFormation invokes the underlying Lambda functions with the following event mapping. AWS CloudFormation sends its request in JSON format, and it expects the function response to be formatted as JSON too.
{ "region" : "us-east-1", "accountId" : "$ACCOUNT_ID", "fragment" : { ... }, "transformId" : "$TRANSFORM_ID", "params" : { ... }, "requestId" : "$REQUEST_ID", "templateParameterValues" : { ... } }
AWS CloudFormation expects the underlying function to return a response in the following JSON format:
{ "requestId" : "$REQUEST_ID", "status" : "$STATUS", "fragment" : { ... } }
For information about additional considerations when creating macros, see Considerations when creating AWS CloudFormation macro definitions.
You can use macros only in the account in which they were created as a resource. The name of the macro must be unique within a given account. However, you can make the same functionality available in multiple accounts by enabling cross-account access on the underlying Lambda function, and then creating macro definitions referencing that function in multiple accounts. In the example below, three accounts contain macro definitions that each point to the same Lambda function.
{P Image}
For more information, see Overview of managing access permissions to your AWS Lambda resources in the *AWS Lambda Developer Guide*.
Overview of managing access permissions to your AWS Lambda resources
In order to create a macro definition, the user must have permissions to create a stack within the specified account.
In order for AWS CloudFormation to successfully run a macro included in a template, the user must have `Invoke` permissions for the underlying Lambda function. To prevent potential escalation of privileges, AWS CloudFormation impersonates the user while running the macro. For more information, see Lambda permissions model in the *AWS Lambda Developer Guide* and Actions and condition context keys for AWS Lambda in the *IAM User Guide*.
Actions and condition context keys for AWS Lambda
The AWS::Serverless transform and AWS::Include transform transforms are macros hosted by AWS CloudFormation. No special permissions are necessary to use them, and they are available from within any account in AWS CloudFormation.
To aid in debugging, you can also specify the `LogGroupName` and `LogRoleArn` properties when creating the AWS::CloudFormation::Macro resource type for your macro. These properties enable you to specify the CloudWatch log group to which AWS CloudFormation sends error logging information when invoking the macro's underlying AWS Lambda function, and the role AWS CloudFormation should assume when sending log entries to those logs.
When a macro is run, the owner of the Lambda function is billed for any charges related to the execution of that function.
The AWS::Serverless transform and AWS::Include transform transforms are macros hosted by AWS CloudFormation. There is no charge for using them.
When creating macro definitions, keep the following in mind:
http://docs.aws.amazon.com/general/latest/gr/rande.html#lambda_region
After AWS CloudFormation has successfully created the stack which contains the macro definition, the macro is available for use within that account. You use a macro by referencing it in the stack template, at the appropriate location relevant to the template contents you want to process.
You can reference multiple macros in a given template, including transforms hosted by AWS CloudFormation, such as AWS::Include transform and AWS::Serverless transform.
Macros are evaluated in order, based on their location in the template, from the most deeply nested outward to the most general. Macros at the same location in the template are evaluated serially based on the order in which they are listed.
Transforms such as `AWS::Include` and `AWS::Transform` are treated the same as any other macros in terms of action order and scope.
For example, in the template sample below, AWS CloudFormation evaluates the `PolicyAdder` macro first, because it is the most deeply-nested macro in the template. AWS CloudFormation then evaluates `MyMacro` before evaluating `AWS::Serverless` because it is listed before `AWS::Serverless` in the `Transform` section.
AWSTemplateFormatVersion: 2010-09-09 Transform: [MyMacro, AWS::Serverless] Resources: WaitCondition: Type: AWS::CloudFormation::WaitCondition MyBucket: Type: 'AWS::S3::Bucket' Properties: BucketName: MyBucket Tags: [{"key":"value"}] 'Fn::Transform': - Name: PolicyAdder CorsConfiguration:[] MyEc2Instance: Type: 'AWS::EC2::Instance' Properties: ImageID: "ami-123"
Macros referenced in the `Transform` section of a template can process the entire contents of that template.
Macros referenced in a `Fn::Transform` function can process the contents of any of the sibling elements (including children) of that `Fn::Transform` function in the template.
For example, in the template sample below, `AWS::Include` can process all of the `MyBucket` properties, based on the location of the `Fn::Transform` function that contains it. `MyMacro` can process the contents of the entire template because of its inclusion in the `Transform` section.
// 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: MyBucket Tags: [{"key":"value"}] 'Fn::Transform': - Name: 'AWS::Include' Parameters: Location: s3://MyAmazonS3BucketName/MyFileName.yaml CorsConfiguration:[] //End of processable content for AWS::Include MyEc2Instance: Type: 'AWS::EC2::Instance' Properties: ImageID: "ami-123" // End of processable content for MyMacro
To create or update a stack using a template that references macros, you typically create a change set and then execute it. A change set describes the actions CloudFormation will take based on the processed template. Processing macros can add multiple resources that you might not be aware of. To ensure that you're aware of all of the changes introduced by macros, we strongly recommend you use change sets. After you review the change set, you can execute it to actually apply the changes.
A macro can add IAM resources to your template. For these resources, AWS CloudFormation requires you to acknowledge their capabilities. Because AWS CloudFormation can't know which resources are added before processing your template, you might need to acknowledge IAM capabilities when you create the change set, depending on whether the referenced macros contain IAM resources. That way, when you run the change set, AWS CloudFormation has the necessary capabilities to create IAM resources.
acknowledge their capabilities
If you are comfortable creating or updating a stack directly from a processed template, without first reviewing the proposed changes in a change set, you can do so by specifying the `CAPABILITY_AUTO_EXPAND` capability during a `CreateStack` or `UpdateStack` request. You should only create stacks directly from a stack template that contains macros if you know what processing the macro performs.
In addition, change sets do not currently support nested stacks. If you want to create a stack from a stack template that contains macros and nested stacks, you must create the stack directly from the template using this capability.
For more information, see CreateStack or UpdateStack in the *AWS CloudFormation API Reference*.
If you use the AWS CLI, you can use the `package` and `deploy` commands to reduce the number of steps for launching stacks from templates that reference macros. For more information, see Deploying Lambda\-based applications in the *AWS Lambda Developer Guide*.
Deploying Lambda-based applications
A template's *stage* indicates whether the template is the original user-submitted template or one in which AWS CloudFormation has processed the macros.
Use the processed template for troubleshooting stack issues. If a template doesn't reference macros, the original and processed templates are identical.
You can use the AWS CloudFormation console or AWS CLI to see the stage of a stack template.
The maximum size for a processed stack template is 51,200 bytes when passed directly into a `CreateStack`, `UpdateStack`, or `ValidateTemplate` request, or 460,800 bytes when passed as an S3 object using an Amazon S3 template URL. However, during processing CloudFormation updates the temporary state of the template as it serially processes the macros contained in the template. Because of this, the size of the template *during processing* may temporarily exceed the allowed size of a fully-processed template. CloudFormation allows some buffer for these in-process templates. However, you should design your templates and macros keeping in mind the maximum allowed size for a processed stack template.
If CloudFormation returns a `Transformation data limit exceeded` error while processing your template, your template has exceeded the maximum template size CloudFormation allows during processing.
To resolve this issue, consider doing the following:
Restructure your template into multiple templates to avoid exceeding the maximum size for in-process templates. For example:
Use nested stack templates to encapsulate parts of the template. For more information, see Working with nested stacks.
Create multiple stacks and use cross-stack references to exchange information between them. For more information, see Walkthrough: Refer to resource outputs in another AWS CloudFormation stack.
Reduce the size of template fragment returned by a given macro. CloudFormation does not tamper with the contents of fragments returned by macros.
Walkthrough: Refer to resource outputs in another AWS CloudFormation stack
In order for AWS CloudFormation to successfully run a macro referenced in a template, the user must have `Invoke` permissions for the underlying Lambda function. For more information, see Overview of managing access permissions to your AWS Lambda resources in the *AWS Lambda Developer Guide*.
Overview of managing access permissions to your AWS Lambda resources
In addition to the Macro example: Creating and using a macro walkthrough in this guide, you can find example macros, including source code and templates, in the Macros examples section of the Amazon Web Services \- Labs repo on GitHub. These examples are provided 'as-is' for instructional purposes.
Macro example: Creating and using a macro
AWS::CloudFormation::Macro
Transform
Fn::Transform
AWS::Serverless transform
AWS::Include transform