You are building a CloudFormation template that creates an ECS service, but you need to transform the template at deploy time to inject company-standard tags, logging configuration, and security baselines. How do you use CloudFormation macros and transforms?
Quick Answer
Create a CloudFormation macro backed by a Lambda function that processes the template fragment during deployment. The Lambda receives the template, modifies it programmatically (adding tags, injecting log groups, applying security defaults), and returns the transformed template. Reference it with `Transform` in the template.
Detailed Answer
CloudFormation Macros
Macros are template-processing functions that run during CloudFormation's template processing phase. When CloudFormation encounters a Transform reference, it sends the template (or a fragment) to the associated Lambda function. The Lambda modifies the template JSON and returns the result. CloudFormation then processes the transformed template as if you wrote it that way. The most well-known macro is AWS::Serverless-2016-10-31 (SAM transform).
Macro Types
Template-level macros process the entire template and are referenced in the Transform section at the top level. Snippet-level macros process specific sections and are invoked via Fn::Transform within a resource definition. Template-level macros are ideal for organization-wide standards (inject tags, logging), while snippet-level macros are useful for reusable resource patterns (generate a standard monitoring stack for any service).
Implementation
The Lambda receives an event with templateParameterValues, fragment (the template section to process), requestId, and params (macro-specific parameters). It must return requestId, status (success/failure), and fragment (the modified template). The Lambda can add resources, modify properties, inject conditions, and transform the template in any way. It runs during the change set creation phase, so you can see the transformed result before deploying.
Use Cases and Limitations
Common use cases: inject standard tags across all resources, add CloudWatch log groups for every Lambda, enforce encryption on all storage resources, add WAF rules to all API Gateways, and create standard alarm sets. Limitations: macros add complexity and make templates harder to read (the deployed template differs from the source). Debugging macro output requires examining the processed template. Macro Lambdas must be deployed before they can be used in templates.