When dealing with huge number of AWS services, it can be challenging to provision and manage those resources. AWS CloudFormation allows easy and time efficient way to manage, configure and provision your resources. AWS resources and infrastructure can be managed by writing simple text files also called as Templates. The templates can be written in JSON or YAML. Essentially CloudFormation can be described as deploying Infrastructure As Code.
No resources are manually created, resulting in fewer human errors
Code can be versioned controlled
Cost Saving: you can automate deletion of a template at certain time and re-create again at desired time.
There is no cost associated with CloudFormation, you only pay for resources allocated.
Building Blocks of CloudFormation
A template is JSON or YAML based text file where you define all the components of CloudFormation.
Resources is the only mandatory component of CloudFormation. It specifies an AWS Resource you wish to create and all the configuration for that resources. e.g. EC2 Instance, VPC, Lambda, etc.
Resources: MyEC2Instance: Type: AWS::EC2::Instance Properties: ImageId: "ami-79fd7eee"
Parameters and Pseudo Parameters
Parameters is an optional component that allows you to provide dynamic inputs for your template. Using parameters you can reuse the template with different input values. In following example, the parameter InstanceTypeParameter has default value as t2.micro if no other input in 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.
There are certain parameters predefined by CloudFormation also called as Pseudo Parameters. You can directly use them in the template. Below are some examples of pseudo parameters.
AWS::AccountId Returns the account ID of the account in which resources are being created.
AWS::Region Returns the region in which the resources are being created
AWS::StackName Returns the name of the Stack
Mappings define static set of variables for your template.
Mappings: Mapping01: Key01: Name: Value01 Key02: Name: Value02 Key03: Name: Value03
For above mapping particular value can be referred using Fn::FindInMap intrinsic function -
Fn::FindInMap: [ Mapping01, Key02, Name]
Outputs declare optional output values that can be imported in other stacks for cross-stack reference. You can not delete a stack if its outputs are referenced by other stacks.
You can use export keyword to output the values from one template and use Fn::ImportValue instrinsic function in another template to import those values
Conditions define list of conditions based on which a particular resource must be created.
AWSTemplateFormatVersion: 2010-09-09 Parameters: EnvType: Description: Environment type. Default: test Type: String AllowedValues: - prod - test Conditions: CreateProdResources: !Equals - !Ref EnvType - prod Resources: EC2Instance: Type: 'AWS::EC2::Instance' Properties: ImageId: ami-0ff8a91507f77f867 MountPoint: Type: 'AWS::EC2::VolumeAttachment' Condition: CreateProdResources
In above example, if the input value of EnvType parameter is prod then MountPoint volume will also be created and attached to the EC2 Instance. In case of EnvType as test, only EC2 instance will be created.
Optional metadata section includes arbitrary details about the template. The information can be a resource specific as shown in below code snippet.
Metadata: Instances: Description: "Information about the instances" Databases: Description: "Information about the databases"
It is not recommended to use sensitive data in metadata section.
Transform in CloudFormation defines one or more macros to process the template. The transform can refer to code stored in S3.
Transform: AWS::Serverless-2016-10-31 Resources: LambdaFunction: Type: AWS::Serverless::Function Properties: Handler: com.dev.Test::handleRequest FunctionName: Test Runtime: java8 CodeUri: 's3://mybucket/test.zip'
In above example, AWS Serverless transform is a macro, it transforms and expands the SAM template into a CloudFormation template.
There are various built in functions that can be used to manage your resources. These functions can be used at properties whose values are not available until runtime. Below are some of the intrinsic functions -
Fn::Ref For parameter, it returns a value and for a resource it returns resource ID.
Fn::GetAtt Returns specific attribute of a resource
Fn::FindInMap Returns value associated with a key
Fn::Sub Substitutes a variable from a string
For all intrinsic function you can use a short form e.g. !Ref, !GetAtt, etc.
Stacks and Stack Sets
A stack is a single unit that manages all the resources you define in CloudFormation template. Stack can perform create, update and delete operations on the AWS Resources.
Stack Sets extends the abilities of stacks and allows management of resources in multiple account and regions with single operation.
Nested stacks allows reuse of standard templates stored in S3 inside another CloudFormation template. Nested stacks not only provides reusability, it also solves the problem of templates exceeding the maximum size supported by AWS.
Serverless Application Model(SAM)
If you are dealing with Serverless applications then SAM comes handy to provision the resources. It has simplified syntax that uses a macro which in turn expands the template into CloudFormation template.
If the template is not configured properly, there is chance the stack creation will fail, in such cases CloudFormation does Rollback in two ways
- Stack Creation Fail
By default if stack creation fails, everything is rollbacked. You can see the logs in events. You can also disable the rollback and troubleshoot the cause of the failure.
- Stack Update Fail
When stack update fails, CloudFormation automatically rollbacks to previous working state.
Amongst all the competitors CloudFormation has always stayed ahead to provide a safe and easy Infrastructure As Code tool. This article covered the basics of CloudFormation and how it's various features can be used to create, manage and delete AWS Resources.