Custom resources & macros
Extend CloudFormation beyond built-ins.
CloudFormation supports a large but finite set of AWS resource types, and sometimes you need to manage something it does not natively cover — a resource in a brand-new service, a third-party API, or a bit of custom logic during provisioning (look up an AMI, seed a database, register a DNS record elsewhere). A custom resource lets you do that: CloudFormation calls out to a Lambda function (or an SNS topic) you provide, on create, update, and delete, and treats the result as a managed resource.
Resources:LatestAmi:Type: Custom::AmiLookup # Custom:: prefix = a custom resourceProperties:ServiceToken: !GetAtt AmiLookupFn.Arn # Lambda that does the workRegion: !Ref "AWS::Region"AppServer:Type: AWS::EC2::InstanceProperties:ImageId: !GetAtt LatestAmi.Id # use the value the Lambda returned
Macros transform the template itself
Where a custom resource provisions something at deploy time, a macro rewrites the template before deployment. You register a Lambda as a macro and invoke it with Transform; CloudFormation passes your template through it and deploys the output. The most famous macro is AWS::Serverless (SAM), which expands short serverless syntax into full resources. Macros are powerful but add a layer of indirection, so reach for them only when templating alone cannot express the pattern.
Transform: AWS::Serverless-2016-10-31 # the SAM macro expands this at deployResources:Api:Type: AWS::Serverless::Function # short form ...Properties:Handler: index.handlerRuntime: nodejs20.xEvents: { Http: { Type: Api, Properties: { Path: /, Method: get } } }# ... expands into Lambda + IAM role + API Gateway resources