CloudFormation Template Reference
Table of Contents
Intrinsic Functions
Intrinsic functions are built-in functions that help manage stacks, evaluated at stack creation/update time.
Ref
Returns the value of a parameter or resource.
For parameters: Returns parameter value For resources: Returns resource ID (varies by type)
Parameters:
KeyName:
Type: String
Resources:
WebServer:
Type: AWS::EC2::Instance
Properties:
KeyName: !Ref KeyName # Returns parameter value
SubnetId: !Ref PublicSubnet # Returns subnet ID
Short form: !Ref LogicalName
Full form: Fn::Ref: LogicalName
GetAtt
Returns attribute of a resource.
Resources:
WebServer:
Type: AWS::EC2::Instance
Properties:
ImageId: ami-0c55b159cbfafe1f0
Outputs:
PublicIP:
Value: !GetAtt WebServer.PublicIp
PrivateIP:
Value: !GetAtt WebServer.PrivateIp
AvailabilityZone:
Value: !GetAtt WebServer.AvailabilityZone
Short form: !GetAtt LogicalName.AttributeName
Full form: Fn::GetAtt: [LogicalName, AttributeName]
Common attributes by resource:
- EC2 Instance:
PublicIp,PrivateIp,AvailabilityZone - S3 Bucket:
Arn,DomainName,WebsiteURL - RDS:
Endpoint.Address,Endpoint.Port
Sub
Substitutes variables in a string.
Resources:
WebServer:
Type: AWS::EC2::Instance
Properties:
Tags:
- Key: Name
Value: !Sub ${EnvironmentName}-WebServer-${AWS::Region}
- Key: Description
Value: !Sub |
Web server for ${EnvironmentName} environment
Deployed in ${AWS::Region}
Variables:
- Template parameters:
${ParameterName} - Resources:
${LogicalName} - Pseudo-parameters:
${AWS::Region},${AWS::AccountId}, etc.
With explicit mapping:
!Sub
- 'arn:aws:ec2:${Region}:${Account}:vpc/${VpcId}'
- Region: !Ref AWS::Region
Account: !Ref AWS::AccountId
VpcId: !Ref VPC
Join
Joins array elements with delimiter.
!Join
- ','
- - !Ref PublicSubnet1
- !Ref PublicSubnet2
- !Ref PublicSubnet3
# Returns: subnet-123,subnet-456,subnet-789
Split
Splits string into array.
!Split
- ','
- 'subnet-123,subnet-456,subnet-789'
# Returns: [subnet-123, subnet-456, subnet-789]
Select
Returns single element from array.
!Select
- 0 # Index
- !GetAZs '' # Array
# Returns first AZ
GetAZs
Returns list of Availability Zones.
!GetAZs '' # Current region
!GetAZs 'us-east-1' # Specific region
# Returns: [us-east-1a, us-east-1b, us-east-1c, ...]
FindInMap
Returns value from Mappings section.
Mappings:
RegionMap:
us-east-1:
AMI: ami-0c55b159cbfafe1f0
us-west-2:
AMI: ami-0d1cd67c26f5fca19
Resources:
WebServer:
Type: AWS::EC2::Instance
Properties:
ImageId: !FindInMap [RegionMap, !Ref 'AWS::Region', AMI]
ImportValue
Returns value exported by another stack.
# Stack 1: Export value
Outputs:
VPCId:
Value: !Ref VPC
Export:
Name: MyVPC-ID
# Stack 2: Import value
Resources:
WebServer:
Type: AWS::EC2::Instance
Properties:
SubnetId: !ImportValue MyVPC-PublicSubnet
If
Conditional return based on condition evaluation.
Conditions:
IsProduction: !Equals [!Ref EnvironmentName, prod]
Resources:
WebServer:
Type: AWS::EC2::Instance
Properties:
InstanceType: !If [IsProduction, t2.large, t2.micro]
Cidr
Generates CIDR blocks.
!Cidr
- !GetAtt VPC.CidrBlock # Base CIDR
- 6 # Number of subnets
- 8 # Subnet bits
# For VPC 10.0.0.0/16, returns:
# [10.0.0.0/24, 10.0.1.0/24, 10.0.2.0/24, ...]
Base64
Encodes string to Base64.
Resources:
WebServer:
Type: AWS::EC2::Instance
Properties:
UserData:
Fn::Base64: !Sub |
#!/bin/bash
echo "Environment: ${EnvironmentName}" > /etc/environment
yum update -y
yum install -y httpd
systemctl start httpd
Parameters
Parameters allow users to input custom values when creating/updating stacks.
Parameter Types
String:
Parameters:
EnvironmentName:
Type: String
Default: dev
Description: Environment name (dev, staging, prod)
Number:
Parameters:
InstanceCount:
Type: Number
Default: 2
MinValue: 1
MaxValue: 10
List:
Parameters:
AvailabilityZones:
Type: List<AWS::EC2::AvailabilityZone::Name>
Description: Select at least 2 AZs
CommaDelimitedList:
Parameters:
SubnetIds:
Type: CommaDelimitedList
Description: List of subnet IDs (comma-separated)
AWS-Specific Types:
Parameters:
KeyName:
Type: AWS::EC2::KeyPair::KeyName
Description: EC2 Key Pair for SSH access
VpcId:
Type: AWS::EC2::VPC::Id
Description: VPC for deployment
SubnetIds:
Type: List<AWS::EC2::Subnet::Id>
Description: Subnets for load balancer
SecurityGroupId:
Type: AWS::EC2::SecurityGroup::Id
Description: Security group
Parameter Constraints
Parameters:
InstanceType:
Type: String
Default: t2.micro
AllowedValues:
- t2.micro
- t2.small
- t2.medium
- t2.large
Description: EC2 instance type
DatabasePassword:
Type: String
NoEcho: true # Hide value in console/CLI
MinLength: 8
MaxLength: 64
AllowedPattern: ^[a-zA-Z0-9]*$
ConstraintDescription: Must be 8-64 alphanumeric characters
CIDR:
Type: String
Default: 10.0.0.0/16
AllowedPattern: ^(\d{1,3}\.){3}\d{1,3}/\d{1,2}$
ConstraintDescription: Must be valid CIDR notation
Parameter Groups (Console UI)
Metadata:
AWS::CloudFormation::Interface:
ParameterGroups:
- Label:
default: "Network Configuration"
Parameters:
- VpcCIDR
- PublicSubnet1CIDR
- PublicSubnet2CIDR
- Label:
default: "Instance Configuration"
Parameters:
- InstanceType
- KeyName
- SSHLocation
ParameterLabels:
VpcCIDR:
default: "VPC CIDR Block"
InstanceType:
default: "Instance Type"
Outputs
Outputs export values that can be viewed or imported by other stacks.
Outputs:
VPCId:
Description: VPC ID
Value: !Ref VPC
Export:
Name: !Sub ${AWS::StackName}-VPCID
PublicSubnets:
Description: Public subnet IDs
Value: !Join [',', [!Ref PublicSubnet1, !Ref PublicSubnet2]]
Export:
Name: !Sub ${AWS::StackName}-PublicSubnets
WebServerURL:
Description: URL of web server
Value: !Sub http://${WebServer.PublicDnsName}
LoadBalancerDNS:
Description: Load balancer DNS name
Value: !GetAtt ApplicationLoadBalancer.DNSName
Using exported values in other stacks:
Resources:
WebServer:
Type: AWS::EC2::Instance
Properties:
SubnetId: !ImportValue MyNetworkStack-PublicSubnet1
Mappings
Mappings are fixed lookup tables for values based on keys.
Mappings:
RegionMap:
us-east-1:
AMI: ami-0c55b159cbfafe1f0
InstanceType: t2.micro
us-west-2:
AMI: ami-0d1cd67c26f5fca19
InstanceType: t2.small
eu-west-1:
AMI: ami-0ea3405d2d2522162
InstanceType: t2.micro
EnvironmentConfig:
dev:
InstanceType: t2.micro
MinSize: 1
MaxSize: 2
prod:
InstanceType: t2.large
MinSize: 2
MaxSize: 10
Resources:
WebServer:
Type: AWS::EC2::Instance
Properties:
ImageId: !FindInMap [RegionMap, !Ref 'AWS::Region', AMI]
InstanceType: !FindInMap
- EnvironmentConfig
- !Ref EnvironmentName
- InstanceType
Conditions
Conditions control whether resources are created or properties are defined.
Defining Conditions
Parameters:
EnvironmentName:
Type: String
AllowedValues: [dev, staging, prod]
CreateBackup:
Type: String
Default: 'false'
AllowedValues: ['true', 'false']
Conditions:
IsProduction: !Equals [!Ref EnvironmentName, prod]
IsNotProduction: !Not [!Equals [!Ref EnvironmentName, prod]]
IsDevelopment: !Equals [!Ref EnvironmentName, dev]
CreateBackupResources: !And
- !Equals [!Ref CreateBackup, 'true']
- !Equals [!Ref EnvironmentName, prod]
CreateMultiAZ: !Or
- !Equals [!Ref EnvironmentName, prod]
- !Equals [!Ref EnvironmentName, staging]
Condition Functions
Equals:
!Equals [!Ref EnvironmentName, prod]
Not:
!Not [!Equals [!Ref EnvironmentName, dev]]
And:
!And
- !Equals [!Ref EnvironmentName, prod]
- !Equals [!Ref CreateBackup, 'true']
Or:
!Or
- !Equals [!Ref EnvironmentName, prod]
- !Equals [!Ref EnvironmentName, staging]
Using Conditions
Conditional resources:
Resources:
# Only create in production
BackupVault:
Type: AWS::Backup::BackupVault
Condition: IsProduction
Properties:
BackupVaultName: ProductionBackup
# Create in all environments except dev
ALB:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Condition: IsNotProduction
Properties:
Name: MyALB
Conditional properties:
Resources:
Database:
Type: AWS::RDS::DBInstance
Properties:
Engine: postgres
MultiAZ: !If [CreateMultiAZ, true, false]
BackupRetentionPeriod: !If [IsProduction, 30, 7]
StorageEncrypted: !If [IsProduction, true, false]
Conditional outputs:
Outputs:
ProductionURL:
Condition: IsProduction
Value: !Sub https://prod.example.com
Description: Production URL
Pseudo Parameters
Pseudo parameters are predefined by CloudFormation and can be referenced like regular parameters.
AWS::AccountId # AWS account ID
AWS::NotificationARNs # Notification ARNs
AWS::NoValue # Removes corresponding property
AWS::Partition # AWS partition (aws, aws-cn, aws-us-gov)
AWS::Region # AWS region
AWS::StackId # Stack ID
AWS::StackName # Stack name
AWS::URLSuffix # Domain suffix (amazonaws.com, amazonaws.com.cn)
Examples:
Resources:
MyBucket:
Type: AWS::S3::Bucket
Properties:
BucketName: !Sub data-${AWS::AccountId}-${AWS::Region}
Tags:
- Key: StackName
Value: !Ref AWS::StackName
MyRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Principal:
Service: !Sub ec2.${AWS::URLSuffix}
Action: sts:AssumeRole
Complete Example
AWSTemplateFormatVersion: '2010-09-09'
Description: Multi-environment VPC with web server
Parameters:
EnvironmentName:
Type: String
Default: dev
AllowedValues: [dev, staging, prod]
Description: Environment name
VpcCIDR:
Type: String
Default: 10.0.0.0/16
AllowedPattern: ^(\d{1,3}\.){3}\d{1,3}/\d{1,2}$
Mappings:
EnvironmentConfig:
dev:
InstanceType: t2.micro
MultiAZ: false
staging:
InstanceType: t2.small
MultiAZ: true
prod:
InstanceType: t2.large
MultiAZ: true
Conditions:
IsProduction: !Equals [!Ref EnvironmentName, prod]
CreateMultiAZ: !FindInMap [EnvironmentConfig, !Ref EnvironmentName, MultiAZ]
Resources:
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: !Ref VpcCIDR
EnableDnsHostnames: true
Tags:
- Key: Name
Value: !Sub ${EnvironmentName}-VPC
PublicSubnet1:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock: !Select [0, !Cidr [!Ref VpcCIDR, 6, 8]]
AvailabilityZone: !Select [0, !GetAZs '']
MapPublicIpOnLaunch: true
Tags:
- Key: Name
Value: !Sub ${EnvironmentName}-Public-1
WebServer:
Type: AWS::EC2::Instance
Properties:
ImageId: ami-0c55b159cbfafe1f0
InstanceType: !FindInMap [EnvironmentConfig, !Ref EnvironmentName, InstanceType]
SubnetId: !Ref PublicSubnet1
Tags:
- Key: Name
Value: !Sub ${EnvironmentName}-WebServer
- Key: Environment
Value: !Ref EnvironmentName
ProductionAlarm:
Type: AWS::CloudWatch::Alarm
Condition: IsProduction
Properties:
AlarmName: !Sub ${EnvironmentName}-HighCPU
MetricName: CPUUtilization
Namespace: AWS/EC2
Statistic: Average
Period: 300
EvaluationPeriods: 2
Threshold: 80
ComparisonOperator: GreaterThanThreshold
Outputs:
VPCId:
Description: VPC ID
Value: !Ref VPC
Export:
Name: !Sub ${AWS::StackName}-VPCID
WebServerIP:
Description: Web server public IP
Value: !GetAtt WebServer.PublicIp
WebServerURL:
Description: Web server URL
Value: !Sub http://${WebServer.PublicDnsName}
EnvironmentInfo:
Description: Environment information
Value: !Sub |
Environment: ${EnvironmentName}
Region: ${AWS::Region}
Account: ${AWS::AccountId}
Stack: ${AWS::StackName}
Found this guide helpful? Share it with your team:
Share on LinkedIn