Expert · Infrastructure as code · topic 36 of 50 · 30 min
AWS CloudFormation
Explanation
Templates and stacks
A template is a YAML or JSON file that describes AWS resources. YAML is easier to read, so most people use it. When you deploy a template, CloudFormation creates a stack: a named group of resources that are created, updated and deleted together. You can deploy the same template many times as different stacks, for example results-bucket-dev and results-bucket-prod.
The sections of a template
| Section | Required? | What it holds |
|---|---|---|
| AWSTemplateFormatVersion | No | The template format version. The only value is '2010-09-09'. |
| Description | No | A line of text that says what the template is for. |
| Parameters | No | Inputs you pass at deploy time, such as the environment name. |
| Mappings | No | Fixed lookup tables, for example an instance size per environment. |
| Conditions | No | True or false rules, for example "create this only in prod". |
| Resources | Yes | The AWS resources to create. Each has a logical name, a Type and Properties. |
| Outputs | No | Values to show after deploy or share with other stacks, like a bucket name. |
A full example: a versioned S3 bucket
AWSTemplateFormatVersion: '2010-09-09'
Description: Versioned S3 bucket for exam result PDFs
Parameters:
EnvName:
Type: String
AllowedValues: [dev, prod]
Default: dev
Description: Which environment this stack is for
Resources:
ResultsBucket:
Type: AWS::S3::Bucket
Properties:
BucketName: !Sub 'results-${EnvName}-${AWS::AccountId}'
VersioningConfiguration:
Status: Enabled
PublicAccessBlockConfiguration:
BlockPublicAcls: true
BlockPublicPolicy: true
IgnorePublicAcls: true
RestrictPublicBuckets: true
Tags:
- Key: env
Value: !Ref EnvName
Outputs:
BucketName:
Description: Name of the results bucket
Value: !Ref ResultsBucket
BucketArn:
Description: ARN of the results bucket
Value: !GetAtt ResultsBucket.ArnIntrinsic functions
Intrinsic functions are small built-in helpers that compute values when the stack is deployed. In YAML they start with an exclamation mark.
- !Ref Name: the value of a parameter, or the main identifier of a resource. For an S3 bucket, !Ref gives the bucket name.
- !GetAtt Resource.Attribute: another attribute of a resource, such as ResultsBucket.Arn. An ARN (Amazon Resource Name) is the full unique ID of a resource.
- !Sub 'text ${Name}': puts parameter values, resource values or pseudo parameters (built-in values such as AWS::AccountId, AWS::Region and AWS::StackName) into a string.
- !Join ['-', [a, b, c]]: joins a list of values with a separator, giving a-b-c.
Mappings and Conditions are used less often but are useful. A Mappings table can say "dev uses t3.micro, prod uses t3.large", read with !FindInMap. A condition such as IsProd: !Equals [!Ref EnvName, prod] can be attached to a resource so it is only created in production.
Deploying with the AWS CLI
# Check the template for syntax errors
aws cloudformation validate-template --template-body file://bucket.yaml
# Create the stack, or update it if it exists (uses a change set behind the scenes)
aws cloudformation deploy \
--template-file bucket.yaml \
--stack-name results-bucket-dev \
--parameter-overrides EnvName=dev
# Read the outputs
aws cloudformation describe-stacks --stack-name results-bucket-dev \
--query "Stacks[0].Outputs"
# Only create the change set, so you can review it before running it
aws cloudformation deploy --template-file bucket.yaml \
--stack-name results-bucket-prod --parameter-overrides EnvName=prod \
--no-execute-changesetChange sets, rollback and drift detection
A change set is a preview: "these resources will be added, these modified, and this one replaced". Replacement matters. Some property changes, such as BucketName, cannot be made in place, so CloudFormation creates a new resource and deletes the old one. Always read the change set before running it in production.
Rollback: if any resource fails during create or update, CloudFormation undoes the changes and returns the stack to its last good state. Your stack is never left half-built without you knowing. Drift detection compares each resource with the template and reports properties changed outside CloudFormation (aws cloudformation detect-stack-drift).
Nested stacks and StackSets
A nested stack is a stack created from inside another template (resource type AWS::CloudFormation::Stack). It lets you reuse a standard piece, such as a VPC, in many templates. A StackSet deploys the same template to many AWS accounts and regions at once, for example a security baseline in every account of an organisation.
Need help?
Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.
Try:
Watch the lesson
AWS CloudFormation · 1/8
CloudFormation is the infrastructure as code service built into AWS. You describe resources in a template, and AWS builds them.
Prefer a video by a teacher? Find free videos on “aws cloudformation tutorial for beginners template stack change set” on YouTube ↗
In real life: A state exam board publishes results with one template
A state school board publishes result PDFs from S3. Its cloud team keeps a CloudFormation template like the one in this lesson in Git: versioning on (so a wrongly overwritten PDF can be recovered), public access blocked (files are served through a CDN with access control), and a tag for the environment. The same template creates results-dev for testing and results-prod for the real results. Before result day, the team deploys a change with --no-execute-changeset, reads the change set in a short review call, and only then executes it.
aws cloudformation deploy --template-file bucket.yaml \
--stack-name results-bucket-prod \
--parameter-overrides EnvName=prod --no-execute-changesetPractice (0/3 done)
In the bucket.yaml template of this lesson, what value does the output BucketName (Value: !Ref ResultsBucket) show after deploying with EnvName=dev?
Write validate(template) for a CloudFormation template that has been loaded into a Python dict. Return a list of error strings, sorted alphabetically: - If "Resources" is missing or empty, return ["Resources section is missing"] and nothing else. - For every resource without a "Type", add "<Name>: missing Type". - Look through everything inside Resources and Outputs for dicts like {"Ref": "X"}. If X is not a parameter name, not a resource name and does not start with "AWS::" (a pseudo parameter), add "Unknown Ref: X". A valid template returns [].
Extend bucket.yaml: add a Number parameter ExpiryDays (default 365), add a lifecycle rule to the bucket that deletes objects after that many days, and add an output with the stack's region. Then write the CLI command that creates a change set for the dev stack with ExpiryDays=30 without executing it.
Quick quiz
Read more (free)
Related help
Before this, learn
This topic builds on these. If something here feels new, open them first.
Related topics
- Terraform for the cloudInfrastructure as code · same module
- IaC in a team: reviews, pipelines and policyInfrastructure as code · same module
- Terraform state, backends and driftDevOps: Git, Docker, Kubernetes and CI/CD · Infrastructure as code with Terraform
- Why infrastructure as codeDevOps: Git, Docker, Kubernetes and CI/CD · Infrastructure as code with Terraform
- The command line on all three cloudsGoogle Cloud and comparing the clouds
- Creating and securing an AWS accountAWS account, IAM and billing
Questions people ask about this
Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.
Which section must every CloudFormation template have?
Answer: Resources
Resources is the only required section. All the others are optional.
Which intrinsic function gives you the ARN of a bucket called ResultsBucket?
Answer: !GetAtt ResultsBucket.Arn
!GetAtt reads an attribute such as Arn. For a bucket, !Ref gives the name, not the ARN.
An update fails halfway because one resource could not be created. What does CloudFormation do by default?
Answer: Rolls the stack back to its last working state
Automatic rollback returns the stack to the last good state when a create or update fails.
You want to see exactly what will change in production before anything happens. What do you use?
Answer: A change set
A change set is a preview of the additions, modifications and replacements that an update will make.
Your company wants the same security baseline stack in 30 accounts and 3 regions. Which feature fits best?
Answer: StackSets
StackSets deploy one template to many accounts and regions from a single place.
In a plan, a resource is marked -/+. What will happen?Related
Answer: It will be destroyed and a new one created
-/+ means replace: Terraform destroys the old object and creates a new one. Check this carefully for databases.
Your company has 200 resources that were created in the console. What is the usual way to bring them under Terraform?Related
Answer: Import them (import blocks or terraform import), then plan until it shows no changes
Importing adds existing resources to the state; a clean plan proves the code matches them.
You run the same IaC apply twice in a row with no changes to the files. What should happen the second time?Related
Answer: Nothing changes, because the apply is idempotent
Idempotent means running it again gives the same result, so the second run finds nothing to do.
Which ARN means "every object in the bucket named photos"?Related
Answer: arn:aws:s3:::photos/*
Objects are bucket-name/key, so /* covers every object. S3 ARNs have no region or account.
Pass the quiz (60% or more) or mark this topic as done when you are ready.
Your progress is saved on this device only.
Next steps
- 2 more topics in “Infrastructure as code” before its exam: Terraform for the cloud, IaC in a team: reviews, pipelines and policy.
- Module 9 exam: Infrastructure as code · 12 questions · 20 min, without help. 4 topics of this module still to finish first.
- Then the next module, High availability, scaling and disaster recovery. 50 topics left in the course before the final exam.