AWS CloudFormation Template, Functions, and Commands
About
This post is a collection of useful notes on various sections of AWS CloudFormation template, and intrinsic functions. Knowledge about them is often tested in AWS certifications. For more details on this subject refer to its user guide (https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/Welcome.html)
Template Anatomy
The following is an example of AWS CloudFormation template and its sections in YAML format. There is no sequence to writing these sections besides that if there is a Description section then it must be put after AWSTemplateFormatVersion.
Template Sections
AWSTemplateFormatVersion (optional)
The AWS CloudFormation template version that the template conforms to. ### Syntax
Description (optional)
A text string that describes the template. This section must always follow the template format version section. ### Syntax
Metadata (optional)
Objects that provide additional information about the template.
- Difference between Metadata and Description is that some cloudformation features can refer to the objects that are defined in Metadata section. For example, you can use a metadata key
AWS::CloudFormation::Interface
to define how parameters are grouped and sorted on AWS cloudformation console. By default, cloudformation console alphbetically sorts the parameters by their logical ID. - AWS strongly recommends not to use this section for storing sensitive information such as passwords or secrets.
Syntax
Parameters (optional)
Parameters enable you to input custom values to your template each time you create or update a stack. You can refer to parameters from the Resources and Outputs sections of the template using Ref intrinsic function.
CloudFormation currently supports the following parameter types
- String – A literal string
- Number – An integer or float
List<Number>
– An array of integers or floats- CommaDelimitedList – An array of literal strings that are separated by commas
AWS::EC2::KeyPair::KeyName
– An Amazon EC2 key pair nameAWS::EC2::SecurityGroup::Id
– A security group IDAWS::EC2::Subnet::Id
– A subnet IDAWS::EC2::VPC::Id
– A VPC IDList<AWS::EC2::VPC::Id>
– An array of VPC IDsList<AWS::EC2::SecurityGroup::Id>
– An array of security group IDsList<AWS::EC2::Subnet::Id>
– An array of subnet IDs
Syntax
The following example declares a parameter named InstanceTypeParameter
. This parameter lets you specify the Amazon EC2 instance type for the stack to use when you create or update the stack.
Note that InstanceTypeParameter
has a default value of t2.micro
. This is the value that AWS CloudFormation will use to provision the stack unless another value is provided.
Parameters:
InstanceTypeParameter:
Type: String
Default: t2.micro
AllowedValues:
- t2.micro
- m1.small
- m1.large
Description: Enter t2.micro, m1.small, or m1.large. Default is t2.micro.
Referencing a parameter in template (Ref function
)
In the following example, the InstanceType
property of the EC2 instance resource references the InstanceTypeParameter
parameter value.
Rules (optional)
Validates a parameter or a combination of parameters that are passed to a template during a stack creation or stack update.
You can use the following rule-specific intrinsic functions to define rule conditions and assertions: * Fn::And * Fn::Contains * Fn::EachMemberEquals * Fn::EachMemberIn * Fn::Equals * Fn::If * Fn::Not * Fn::Or * Fn::RefAll * Fn::ValueOf * Fn::ValueOfAll
Syntax
In the following example, the rule checks the value of the InstanceType
parameter. The user must specify a1.medium
, if the value of the environment parameter is test
.
Mappings (optional)
The optional Mappings section matches a key to a corresponding set of named values similar to a lookup table. For example, if you want to set values based on a region, you can create a mapping that uses the region name as a key and contains the values you want to specify for each specific region. You use the Fn::FindInMap
intrinsic function in the Resources and Outputs to retrieve values in a map. Note that you can’t include parameters, pseudo parameters, or intrinsic functions in the Mappings section.
Fn::FindInMap
The intrinsic function Fn::FindInMap
returns the value corresponding to keys in a two-level map that’s declared in the Mappings section.
Syntax for the short form:
Parameters * MapName * The logical name of a mapping declared in the Mappings section that contains the keys and values. * TopLevelKey * The top-level key name. Its value is a list of key-value pairs. * SecondLevelKey * The second-level key name, which is set to one of the keys from the list assigned to TopLevelKey.
A more concrete example
Conditions (optional)
Conditions that control whether certain resources are created or whether certain resource properties are assigned a value during stack creation or update. For example, you could conditionally create a resource that depends on whether the stack is for a production or test environment.
Conditions are defined in Conditions
section, and are then applied in following sections. * Parameters * Resources * Outputs
You can use following intrinsic functions to define your conditions * Fn::And * Fn::Equals * Fn::If * Fn::Not * Fn::Or
Syntax
A more concrete example
AWSTemplateFormatVersion: 2010-09-09
Parameters:
EnvType:
Description: Environment type.
Default: test
Type: String
AllowedValues:
- prod
- test
ConstraintDescription: must specify prod or test.
Conditions:
CreateProdResources: !Equals
- !Ref EnvType
- prod
Resources:
EC2Instance:
Type: 'AWS::EC2::Instance'
Properties:
ImageId: ami-0ff8a91507f77f867
MountPoint:
Type: 'AWS::EC2::VolumeAttachment'
Condition: CreateProdResources
Properties:
InstanceId: !Ref EC2Instance
VolumeId: !Ref NewVolume
Device: /dev/sdh
NewVolume:
Type: 'AWS::EC2::Volume'
Condition: CreateProdResources
Properties:
Size: 100
AvailabilityZone: !GetAtt
- EC2Instance
- AvailabilityZone
Difference between Rules and Conditions usage?
- Rules are used to evaluate the input given by the user in Parameters
- Conditions turn come after all rules have been evaluated
- Conditions are not limited to Parameters and can also work with Resources and Outputs
Transform (optional)
For serverless applications (also referred to as Lambda-based applications), specifies the version of the AWS Serverless Application Model (AWS SAM) to use. When you specify a transform, you can use AWS SAM syntax to declare resources in your template. The model defines the syntax that you can use and how it's processed.
You can also use AWS::Include transforms to work with template snippets that are stored separately from the main AWS CloudFormation template. You can store your snippet files in an Amazon S3 bucket and then reuse the functions across multiple templates.
Syntax
AWS::Include transform
Use the AWS::Include transform, which is a macro hosted by AWS CloudFormation, to insert boilerplate content into your templates. The AWS::Include
transform lets you create a reference to a template snippet in an Amazon S3 bucket. The AWS::Include
function behaves similarly to an include, copy, or import directive in programming languages.
Example
Resources (required)
Specifies the stack resources and their properties, such as an Amazon Elastic Compute Cloud instance or an Amazon Simple Storage Service bucket. You can refer to resources in the Resources and Outputs sections of the template.
Syntax
A more concrete example
Outputs (optional)
The optional Outputs section declares output values that you can import into other stacks (to create cross-stack references), return in response (to describe stack calls), or view on the AWS CloudFormation console. For example, you can output the S3 bucket name from a stack to make the bucket easier to find.
Notes * You can declare a maximum of 200 outputs in a template. * AWS strongly recommend you don’t use this section to output sensitive information, such as passwords or secrets * Output values are available after the stack operation is complete. Stack output values aren’t available when a stack status is in any of the IN_PROGRESS status. * AWS also does not recommend establishing dependencies between a service runtime and the stack output value because output values might not be available at all times.
Syntax
Outputs:
Logical ID:
Description: Information about the value
Value: Value to return
Export:
Name: Name of resource to export
A more concrete example where certain values are shown as output at the end of stack creation.
Outputs:
BackupLoadBalancerDNSName:
Description: The DNSName of the backup load balancer
Value: !GetAtt BackupLoadBalancer.DNSName
Condition: CreateProdResources
InstanceID:
Description: The Instance ID
Value: !Ref EC2Instance
For Cross-Stack output use Export tag. Values outputed with “Export” tag can be imported in other stacks “in the same region”. Then, use the Fn::ImportValue
intrinsic function to import the value in another stack “in the same region”.
Some other important Intrinsic Functions
Fn::GetAtt
The Fn::GetAtt
intrinsic function returns the value of an attribute from a resource in the template.
Syntax
!GetAtt logicalNameOfResource.attributeName
- logicalNameOfResource
- The logical name (also called logical ID) of the resource that contains the attribute that you want.
- attributeName
- The name of the resource-specific attribute whose value you want. See the resource’s reference page for details about the attributes available for that resource type.
- Return value
- The attribute value.
A more concrete example
!GetAtt myELB.DNSName
Notes: * For the Fn::GetAtt
logical resource name, you can’t use functions. You must specify a string that’s a resource’s logical ID. * For the Fn::GetAtt
attribute name, you can use the Ref function
.
Fn::ImportValue
The intrinsic function Fn::ImportValue
returns the value of an output exported by another stack. You typically use this function to create cross-stack references.
Notes: * For each AWS account, Export names must be unique within a region. * You can’t create cross-stack references across regions. You can use the intrinsic function Fn::ImportValue
to import only values that have been exported within the same region. * You can’t delete a stack if another stack references one of its outputs. * You can’t modify or remove an output value that is referenced by another stack.
Syntax
!ImportValue sharedValueToImport
A more concrete example.
Fn::Sub
The intrinsic function Fn::Sub
substitutes variables in an input string with values that you specify. In your templates, you can use this function to construct commands or outputs that include values that aren’t available until you create or update a stack.
Syntax
Parameters
- String
- A string with variables that AWS CloudFormation substitutes with their associated values at runtime. Write variables as
${MyVarName}
. Variables can be template parameter names, resource logical IDs, resource attributes, or a variable in a key-value map.
- A string with variables that AWS CloudFormation substitutes with their associated values at runtime. Write variables as
- VarName
- The name of a variable that you included in the
String
parameter.
- The name of a variable that you included in the
- VarValue
- The value that CloudFormation substitutes for the associated variable name at runtime.
A more concrete example. The following example uses a mapping to substitute the ${Domain}
variable with the resulting value from the Ref
function.
Important CloudFormation CLI Commands
- Package a template using
aws cloudformation package
command - Validate a CloudFormation template using
aws cloudformation validate-template
command - Deploy a template using the
aws cloudformation deploy
command