AWS CloudFormation template explained
Tags: aws, awscloudformation, devops
Published: 2022-05-10 14:31:17

In my last blog post I showed you how to [deploy your first AWS CloudFormation template](https://www.techielass.com/create-an-s3-bucket-using-aws-cloudformation) and create an S3 Bucket.  What I aim to do within this blog post is walk you through the nine main components of an AWS CloudFormation template to help build up your knowledge. 

![AWS CloudFormation Template structure](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rb4zyugaq7rnukamuel8.png)

The above picture is an example YAML template we'll be using and walking through. 

## AWS CloudFormation Template Components
Within an AWS CloudFormation template there are nine components that you may encounter.  Some are optional and some are mandatory.  

## Format Version
The first component you'll encounter is the Format Version
```yml
AWSTemplateFormatVersion: 2010-09-09
```

This dictates what capabilities the template will have, the current version you will see on all up to date templates is **2010-09-09**.  This is actually an option field. 

## MetaData
This is an optional section and can be used for more information about the template.  Examples that I have seen with this section includes have been describing how resources are laid out within the AWS CloudFormation Designer.  Like below: 
```yml
Metadata:
  'AWS::CloudFormation::Designer':
    78de0c7b-0cba-4fd2-837a-adf54fe6a2f7:
      size:
        width: 140
        height: 140
      position:
        x: 370
        'y': 126
      z: 0
    41b19610-03b6-44f5-92d8-db8d6b53a0c6:
      size:
        width: 60
        height: 60
      position:
        x: 653
        'y': 163
      z: 0
```

## Description
```yml
Description: CloudFormation template for s3 bucket
```
This section is used to help you as the author or your team mates understand what the template does.  You could include a brief summary of what the template does, who authored it etc.  It is an optional section of the template. 

## Parameters
The simple template that we showed earlier doesn't have any parameters, or need them for the simplistic deployment.  But other templates may need parameter.  An example would be deploying an EC2 instance: 
```yml
Parameters:
  AvailabilityZone:
    Type: AWS::EC2::AvailabilityZone::Name
  InstanceAMI:
    Description: Managed AMI ID for EC2 Instance for deployment. Default is for deployment in us-east-1.
    Type : String
    Default: ami-04505e74c0741db8d
  KeyPairName:
    Type: String
    Description: The name of an existing Amazon EC2 key pair in this region to use to SSH into the Amazon EC2 instances.
  InstanceType:
    Type: String
    Description: Choosing two low cost options
    Default: t2.micro
    AllowedValues:
      - t2.micro
      - t2.small
  EnvironmentType:
    Type: String
    Description: Used as an identifier
 ```

In the above example we have parameters that require input when the template is deployed.  But we also have parameters that have a default value if no information is supplied for that parameter during deployment. 

Our _InstanceType_ parameters has been set to only allow two inputs as acceptable.  Which is great if you want to help guide people deploying the template to company standards or the options that are available for that specific input. 

## Mappings
Our example template doesn't have any mappings.  But for a more complex deployment you could use the mapping section to match a key to a named value.

For example if you want to map a certain values based on region.  If you are deploying an EC2 instance you might have to deal with different Amazon Machine Image (AMI) IDs so could have the mapping section like: 
```yml
Mappings: 
  RegionMap: 
    us-east-1: 
      "HVM64": "ami-0ff8a91507f77f867"
    us-west-1: 
      "HVM64": "ami-0bdb828fd58c52235"
    eu-west-1: 
      "HVM64": "ami-047bb4163c506cd98"
```

You can then query that mapping table later within your template, so that the right AMI would be picked depending on the region you are deploying to. 

## Conditions
This is an optional section within the template.  Within this section you can help the template to decide whether not to do something based on whether something is true or not. 

This can be used to great power if you want to use a template for production and also test environments, but configurations are slightly different for each environment.  You might want to configure your EC2 instances in a certain way for production, but for test you might want to save costs so you have a different set of requirements.  

You can achieve this by using conditions within your template. 

## Transform
Another optional section within a template file.  Within this section you can declare one or more macros and the template will execute them in the order they are specified. 

## Resources
```Resources:
  S3Bucket:
    DeletionPolicy: Retain
    Type: 'AWS::S3::Bucket'
    Description: Creating Amazon S3 bucket from CloudFormation
    Properties:
      AccessControl: Private
      PublicAccessBlockConfiguration:
        BlockPublicAcls: true
        BlockPublicPolicy: true
        IgnorePublicAcls: true
        RestrictPublicBuckets: true
      BucketEncryption:
        ServerSideEncryptionConfiguration:
          - ServerSideEncryptionByDefault:
              SSEAlgorithm: AES256
      VersioningConfiguration:
        Status: Enabled
```

This section is mandatory.  Every AWS CloudFormation template will have a resource section and define at least one resource. 
The above examples specifies the type of resource to be deploy, an S3 Bucket in this case.  We then more configuration information about encryption and versioning for that resource. 

## Outputs
```yml
Outputs:
  S3Bucket:
    Description: Bucket Created using this template.
    Value: !Ref S3Bucket
```
Within this section you can request information back when the template and resources have been created.  You could ask for information about a resource name, an IP address that has been created, etc.  

You can use this information as reference or when you get to more complex deployments collect the information to be able to pass on to other automation tasks. 

{% embed https://youtu.be/qhR0CdrMIz0 %}

## AWS CloudFormation template components
As you can see there are a lot of optional components for an AWS CloudFormation template.  I hope this overview has given you an insight into the power and capability that lives within an AWS CloudFormation template and you can take these learnings and move forward with your AWS learning journey.