CloudFormation Template Reference

Last updated:

Intrinsic Functions

Functions CloudFormation evaluates while it deploys the stack. Each has a short YAML form (!Ref) and a full form (Ref: or Fn::GetAtt:).

Ref

A parameter’s value, or a resource’s main identifier (which one depends on the type, such as an instance ID or a queue URL).

Resources:
  WebServer:
    Type: AWS::EC2::Instance
    Properties:
      InstanceType: !Ref InstanceType   # parameter value
      SubnetId: !Ref PublicSubnet       # subnet ID

Full form: Ref: LogicalName.

GetAtt

Another attribute of a resource. Each type’s reference page lists its attributes.

Outputs:
  QueueArn:
    Value: !GetAtt OrdersQueue.Arn
  DatabaseEndpoint:
    Value: !GetAtt Database.Endpoint.Address

Full form: Fn::GetAtt: [LogicalName, AttributeName].

Sub

A string with ${...} values substituted from parameters, resource IDs, attributes, and pseudo parameters.

Tags:
  - Key: Name
    Value: !Sub ${Environment}-web-${AWS::Region}

# With explicit variables
Value: !Sub
  - 'arn:${AWS::Partition}:s3:::${BucketName}/*'
  - BucketName: !Ref ArchiveBucket

Join and Split

Join a list into one string, or split a string into a list.

!Join [',', [!Ref SubnetA, !Ref SubnetB]]   # "subnet-1,subnet-2"
!Split [',', 'subnet-1,subnet-2']            # [subnet-1, subnet-2]

Select, GetAZs, and Cidr

Pick an element from a list, list the Region’s Availability Zones, or carve a CIDR block into subnets.

AvailabilityZone: !Select [0, !GetAZs '']            # first AZ in this Region
CidrBlock: !Select [0, !Cidr [!GetAtt VPC.CidrBlock, 6, 8]]
# !Cidr [base, count, host bits]: 6 blocks with 8 host bits (/24s from a /16)

FindInMap

A value from the Mappings section, by top-level key and second-level key.

InstanceType: !FindInMap [EnvironmentConfig, !Ref Environment, InstanceType]

ImportValue

A value another stack in the same account and Region exported from its Outputs.

# Exporting stack
Outputs:
  VpcId:
    Value: !Ref VPC
    Export:
      Name: !Sub ${AWS::StackName}-VpcId

# Importing stack
Properties:
  VpcId: !ImportValue network-prod-VpcId

GetStackOutput

An output of another stack, read directly without an export, in the same or another account and Region (since May 2026). The reference is weak, so the producer can still change or delete the output.

SubnetId:
  Fn::GetStackOutput:
    StackName: network-prod
    OutputName: PrivateSubnetA
    Region: us-west-2                                             # optional
    RoleArn: arn:aws:iam::111111111111:role/ReadNetworkOutputs    # optional, for another account

Use the full Fn::GetStackOutput: form whenever a parameter value uses another short form such as !Ref.

If

One of two values depending on a condition. AWS::NoValue removes the property instead.

MultiAZ: !If [IsProd, true, false]
SnapshotIdentifier: !If [RestoreFromSnapshot, !Ref SnapshotId, !Ref AWS::NoValue]

Base64

Base64-encodes a string, as EC2 user data requires.

UserData:
  Fn::Base64: !Sub |
    #!/bin/bash
    echo "Environment: ${Environment}" > /etc/app-environment

Language Extensions

The AWS::LanguageExtensions transform adds Fn::ForEach (repeat a resource for each item in a list), Fn::Length, Fn::ToJsonString, and a default value for Fn::FindInMap. These functions have no short YAML forms, so write Fn::Length:, not !Length.

Transform: AWS::LanguageExtensions
Resources:
  Fn::ForEach::Topics:
    - TopicName
    - [Orders, Payments, Refunds]
    - ${TopicName}Topic:
        Type: AWS::SNS::Topic

Parameters

Values supplied at deployment. The type determines what’s accepted and how the console prompts for it.

Type Accepts
String, Number Plain values
CommaDelimitedList, List<Number> Lists
AWS::EC2::VPC::Id, AWS::EC2::Subnet::Id, List<AWS::EC2::Subnet::Id>, AWS::EC2::SecurityGroup::Id, and similar Existing resource IDs, validated against the account
AWS::SSM::Parameter::Value<String>, AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>, and similar The name of a Parameter Store parameter, whose current value is read at deployment
Parameters:
  Environment:
    Type: String
    AllowedValues: [dev, staging, prod]
    Default: dev

  InstanceCount:
    Type: Number
    Default: 2
    MinValue: 1
    MaxValue: 10

  LatestAmiId:   # always the latest Amazon Linux 2023 AMI for this Region
    Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
    Default: /aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-x86_64

  VpcCidr:
    Type: String
    Default: 10.0.0.0/16
    AllowedPattern: ^(\d{1,3}\.){3}\d{1,3}/\d{1,2}$
    ConstraintDescription: Must be a CIDR block such as 10.0.0.0/16

NoEcho: true masks a parameter’s value in the console and API output, but the value can still appear elsewhere, so pass secrets with a dynamic reference instead (below).

Parameter Groups

How the console groups and labels parameters, set in Metadata.

Metadata:
  AWS::CloudFormation::Interface:
    ParameterGroups:
      - Label:
          default: Network
        Parameters: [VpcCidr]
      - Label:
          default: Compute
        Parameters: [InstanceCount, LatestAmiId]
    ParameterLabels:
      VpcCidr:
        default: VPC CIDR block

Mappings

Fixed lookup tables, two levels deep, read with !FindInMap.

Mappings:
  EnvironmentConfig:
    dev:
      InstanceType: t4g.small
      MinSize: 1
    prod:
      InstanceType: m7g.large
      MinSize: 3

Conditions

Named true-or-false expressions, built from !Equals, !And, !Or, !Not, and references to other conditions, with !Ref and !FindInMap usable inside them.

Conditions:
  IsProd: !Equals [!Ref Environment, prod]
  IsNotDev: !Not [!Equals [!Ref Environment, dev]]
  NeedsReplica: !And
    - Condition: IsProd
    - !Equals [!Ref CreateReplica, 'true']

Conditions apply to whole resources, to individual properties through !If, and to outputs.

Resources:
  ReadReplica:
    Type: AWS::RDS::DBInstance
    Condition: NeedsReplica
    Properties:
      SourceDBInstanceIdentifier: !Ref Database
      DBInstanceClass: db.r8g.large

  Database:
    Type: AWS::RDS::DBInstance
    Properties:
      MultiAZ: !If [IsProd, true, false]
      BackupRetentionPeriod: !If [IsProd, 30, 7]

Outputs:
  ReplicaEndpoint:
    Condition: NeedsReplica
    Value: !GetAtt ReadReplica.Endpoint.Address

Rules

Checks on parameter values that run before CloudFormation touches any resource, failing the operation with a message. Rule-specific functions such as Fn::Contains have no short YAML form.

Rules:
  ProdUsesLargeInstances:
    RuleCondition: !Equals [!Ref Environment, prod]
    Assertions:
      - Assert:
          Fn::Contains: [[m7g.large, m7g.xlarge], !Ref InstanceType]
        AssertDescription: Production needs m7g.large or m7g.xlarge

Dynamic References

Values CloudFormation reads from Parameter Store or Secrets Manager at deployment, without them appearing in the template or in parameter values. A template can hold 60, and they can’t be used in EC2 UserData or AWS::CloudFormation::Init.

# Parameter Store String or StringList (a specific version with :version)
QueueUrl: '{{resolve:ssm:/orders/prod/queue-url}}'

# Parameter Store SecureString (only on a short list of properties, such as RDS MasterUserPassword)
MasterUserPassword: '{{resolve:ssm-secure:/orders/prod/db-password}}'

# Secrets Manager (secret, then SecretString and a JSON key), usable on any property
MasterUserPassword: '{{resolve:secretsmanager:prod/db:SecretString:password}}'

Pseudo Parameters

Values CloudFormation always provides, used with !Ref or inside !Sub.

Pseudo parameter Value
AWS::AccountId The account ID
AWS::Region The Region, such as us-east-1
AWS::Partition The partition, such as aws, aws-cn, or aws-us-gov, for building ARNs that work in every partition
AWS::URLSuffix The domain suffix, usually amazonaws.com
AWS::StackName, AWS::StackId The stack’s name and ID
AWS::NotificationARNs The stack’s SNS notification topics
AWS::NoValue Removes a property when returned by !If
BucketName: !Sub archive-${AWS::AccountId}-${AWS::Region}
Resource: !Sub arn:${AWS::Partition}:s3:::${ArchiveBucket}/*

Found this useful? Share it:

Share on LinkedIn