Skip to content

Cloudformation

Chapter 33: AWS CloudFormation - Infrastructure as Code

Section titled “Chapter 33: AWS CloudFormation - Infrastructure as Code”

Infrastructure as Code with CloudFormation

Section titled “Infrastructure as Code with CloudFormation”

AWS CloudFormation is a service that helps you model and set up your Amazon Web Services resources so that you can spend less time managing those resources and more time focusing on your applications.

AWS CloudFormation Overview
+------------------------------------------------------------------+
| |
| +------------------------+ |
| | AWS CloudFormation | |
| +------------------------+ |
| | |
| +---------------------+---------------------+ |
| | | | |
| v v v |
| +----------+ +----------+ +----------+ |
| | Templates| | Stacks | | Change | |
| | | | | | Sets | |
| | - YAML | | - Create | | - Update | |
| | - JSON | | - Update | | - Track | |
| | - Modules| | - Delete | | - Execute| |
| +----------+ +----------+ +----------+ |
| |
+------------------------------------------------------------------+
ConceptDescription
TemplateYAML/JSON file describing resources
StackCollection of resources created from template
Change SetPreview of changes before applying
Stack SetDeploy stacks across multiple accounts/regions

CloudFormation Template Structure
+------------------------------------------------------------------+
| |
| AWSTemplateFormatVersion: '2010-09-09' |
| Description: My CloudFormation Template |
| |
| Metadata: |
| Template metadata and documentation |
| |
| Parameters: |
| Input values for customization |
| |
| Mappings: |
| Key-value pairs for conditional values |
| |
| Conditions: |
| Statements that define when resources are created |
| |
| Transform: |
| Macros and transforms (e.g., AWS::Serverless) |
| |
| Resources: (Required) |
| AWS resources to create |
| |
| Outputs: |
| Values returned after stack creation |
| |
+------------------------------------------------------------------+
AWSTemplateFormatVersion: '2010-09-09'
Description: Web Application Stack
Parameters:
Environment:
Type: String
Default: dev
AllowedValues:
- dev
- prod
Description: Environment name
InstanceType:
Type: String
Default: t3.micro
AllowedValues:
- t3.micro
- t3.small
- t3.medium
Mappings:
RegionMap:
us-east-1:
AMI: ami-0c55b159cbfafe1f0
us-west-2:
AMI: ami-0bdb828fd58c52235
Conditions:
IsProduction: !Equals [!Ref Environment, prod]
Resources:
WebServerSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Enable HTTP access
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
WebServerInstance:
Type: AWS::EC2::Instance
Properties:
ImageId: !FindInMap [RegionMap, !Ref 'AWS::Region', AMI]
InstanceType: !Ref InstanceType
SecurityGroupIds:
- !Ref WebServerSecurityGroup
Tags:
- Key: Environment
Value: !Ref Environment
Outputs:
WebsiteURL:
Description: URL of the website
Value: !Sub 'http://${WebServerInstance.PublicIp}'

CloudFormation Resource Syntax
+------------------------------------------------------------------+
| |
| Resources: |
| LogicalID: |
| Type: ResourceType |
| Properties: |
| PropertyName: PropertyValue |
| DependsOn: [DependencyList] |
| DeletionPolicy: Retain | Delete | Snapshot |
| UpdateReplacePolicy: Retain | Delete | Snapshot |
| CreationPolicy: |
| ... |
| UpdatePolicy: |
| ... |
| Metadata: |
| ... |
| |
+------------------------------------------------------------------+
Common CloudFormation Resource Types
+------------------------------------------------------------------+
| |
| Compute |
| +------------------------------------------------------------+ |
| | - AWS::EC2::Instance | |
| | - AWS::EC2::LaunchTemplate | |
| | - AWS::Lambda::Function | |
| | - AWS::ECS::Cluster | |
| | - AWS::ECS::Service | |
| +------------------------------------------------------------+ |
| |
| Networking |
| +------------------------------------------------------------+ |
| | - AWS::EC2::VPC | |
| | - AWS::EC2::Subnet | |
| | - AWS::EC2::SecurityGroup | |
| | - AWS::ElasticLoadBalancingV2::LoadBalancer | |
| | - AWS::ElasticLoadBalancingV2::TargetGroup | |
| +------------------------------------------------------------+ |
| |
| Storage |
| +------------------------------------------------------------+ |
| | - AWS::S3::Bucket | |
| | - AWS::EC2::Volume | |
| | - AWS::EFS::FileSystem | |
| +------------------------------------------------------------+ |
| |
| Database |
| +------------------------------------------------------------+ |
| | - AWS::RDS::DBInstance | |
| | - AWS::DynamoDB::Table | |
| | - AWS::ElastiCache::CacheCluster | |
| +------------------------------------------------------------+ |
| |
+------------------------------------------------------------------+

CloudFormation Intrinsic Functions
+------------------------------------------------------------------+
| |
| Ref |
| +------------------------------------------------------------+ |
| | Returns the value of the specified parameter or resource | |
| | | |
| | !Ref ParameterName | |
| | !Ref ResourceLogicalID | |
| +------------------------------------------------------------+ |
| |
| GetAtt |
| +------------------------------------------------------------+ |
| | Returns the value of an attribute from a resource | |
| | | |
| | !GetAtt ResourceLogicalID.AttributeName | |
| +------------------------------------------------------------+ |
| |
| Sub |
| +------------------------------------------------------------+ |
| | Substitutes variables in a string | |
| | | |
| | !Sub 'arn:aws:s3:::${BucketName}' | |
| | !Sub 'http://${WebServerInstance.PublicIp}' | |
| +------------------------------------------------------------+ |
| |
| Join |
| +------------------------------------------------------------+ |
| | Joins values with a delimiter | |
| | | |
| | !Join ['-', [env, app, service]] | |
| | Result: env-app-service | |
| +------------------------------------------------------------+ |
| |
| FindInMap |
| +------------------------------------------------------------+ |
| | Returns value from a mapping | |
| | | |
| | !FindInMap [MapName, Key1, Key2] | |
| +------------------------------------------------------------+ |
| |
| If / Equals / And / Or / Not |
| +------------------------------------------------------------+ |
| | Conditional functions | |
| | | |
| | !If [ConditionName, ValueIfTrue, ValueIfFalse] | |
| | !Equals [!Ref Environment, prod] | |
| +------------------------------------------------------------+ |
| |
| GetAZs / Select |
| +------------------------------------------------------------+ |
| | Returns Availability Zones | |
| | | |
| | !Select [0, !GetAZs ''] | |
| +------------------------------------------------------------+ |
| |
+------------------------------------------------------------------+

Parameters:
# String parameter
EnvironmentName:
Type: String
Default: dev
AllowedValues:
- dev
- staging
- prod
Description: Environment name
# Number parameter
InstanceCount:
Type: Number
Default: 2
MinValue: 1
MaxValue: 10
# List parameter
AvailabilityZones:
Type: List<AWS::EC2::AvailabilityZone::Name>
Description: List of availability zones
# AWS-specific parameter
VpcId:
Type: AWS::EC2::VPC::Id
Description: VPC ID
# CommaDelimitedList
SubnetIds:
Type: List<AWS::EC2::Subnet::Id>
Description: List of subnet IDs
# SSM parameter
LatestAmiId:
Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
Default: /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2
Outputs:
VpcId:
Description: The VPC ID
Value: !Ref VPC
Export:
Name: !Sub '${AWS::StackName}-VpcId'
WebServerPublicIp:
Description: Public IP of the web server
Value: !GetAtt WebServerInstance.PublicIp
LoadBalancerDNS:
Description: Load Balancer DNS name
Value: !GetAtt LoadBalancer.DNSName
Export:
Name: !Sub '${AWS::StackName}-LoadBalancerDNS'

CloudFormation Stack Operations
+------------------------------------------------------------------+
| |
| Create Stack |
| +------------------------------------------------------------+ |
| | | |
| | Template --> Validate --> Create Stack --> Resources | |
| | | |
| | Steps: | |
| | 1. Validate template | |
| | 2. Create stack | |
| | 3. Create resources | |
| | 4. Return outputs | |
| | | |
| +------------------------------------------------------------+ |
| |
| Update Stack |
| +------------------------------------------------------------+ |
| | | |
| | Options: | |
| | +------------------------------------------------------+ | |
| | | - Direct update | | |
| | | - Change set (recommended) | | |
| | +------------------------------------------------------+ | |
| | | |
| | Update Behaviors: | |
| | +------------------------------------------------------+ | |
| | | - Replace: Delete and recreate | | |
| | | - Update: Modify in place | | |
| | | - Interrupt: Restart resource | | |
| | +------------------------------------------------------+ | |
| | | |
| +------------------------------------------------------------+ |
| |
| Delete Stack |
| +------------------------------------------------------------+ |
| | | |
| | Steps: | |
| | 1. Delete resources in reverse order | |
| | 2. Handle dependencies | |
| | 3. Apply DeletionPolicy | |
| | | |
| +------------------------------------------------------------+ |
| |
+------------------------------------------------------------------+
CloudFormation Change Sets
+------------------------------------------------------------------+
| |
| Change Set Workflow |
| +------------------------------------------------------------+ |
| | | |
| | +----------+ +----------+ +----------+ | |
| | | Create | --> | Preview | --> | Execute | | |
| | | Change | | Changes | | Changes | | |
| | | Set | | | | | | |
| | +----------+ +----------+ +----------+ | |
| | | |
| | Benefits: | |
| | +------------------------------------------------------+ | |
| | | - Preview changes before applying | | |
| | | - See resource replacements | | |
| | | - Review with team | | |
| | | - Avoid unintended changes | | |
| | +------------------------------------------------------+ | |
| | | |
| +------------------------------------------------------------+ |
| |
+------------------------------------------------------------------+

CloudFormation StackSets
+------------------------------------------------------------------+
| |
| +------------------------+ |
| | StackSet | |
| +------------------------+ |
| | |
| +---------------------+---------------------+ |
| | | | |
| v v v |
| +----------+ +----------+ +----------+ |
| | Stack | | Stack | | Stack | |
| | Instance | | Instance | | Instance | |
| | | | | | | |
| | Account A| | Account B| | Account C| |
| | Region 1 | | Region 1 | | Region 2 | |
| +----------+ +----------+ +----------+ |
| |
+------------------------------------------------------------------+
StackSets Use Cases
+------------------------------------------------------------------+
| |
| 1. Multi-Account Security Baselines |
| +------------------------------------------------------------+ |
| | - Deploy security groups across accounts | |
| | - Configure IAM roles and policies | |
| | - Set up CloudTrail and Config | |
| +------------------------------------------------------------+ |
| |
| 2. Multi-Region Deployments |
| +------------------------------------------------------------+ |
| | - Deploy application stacks to multiple regions | |
| | - Configure regional resources | |
| +------------------------------------------------------------+ |
| |
| 3. Governance and Compliance |
| +------------------------------------------------------------+ |
| | - Enforce compliance rules | |
| | - Deploy audit configurations | |
| +------------------------------------------------------------+ |
| |
+------------------------------------------------------------------+

Terminal window
# Validate template
aws cloudformation validate-template \
--template-body file://template.yaml
# Create stack
aws cloudformation create-stack \
--stack-name my-stack \
--template-body file://template.yaml \
--parameters ParameterKey=Environment,ParameterValue=prod \
--capabilities CAPABILITY_IAM
# Create stack with change set
aws cloudformation create-change-set \
--stack-name my-stack \
--change-set-name my-change-set \
--template-body file://template.yaml
# Describe change set
aws cloudformation describe-change-set \
--stack-name my-stack \
--change-set-name my-change-set
# Execute change set
aws cloudformation execute-change-set \
--stack-name my-stack \
--change-set-name my-change-set
# Update stack
aws cloudformation update-stack \
--stack-name my-stack \
--template-body file://template.yaml \
--parameters ParameterKey=Environment,ParameterValue=staging
# Describe stack
aws cloudformation describe-stacks \
--stack-name my-stack
# List stacks
aws cloudformation list-stacks \
--stack-status-filter CREATE_COMPLETE UPDATE_COMPLETE
# Describe stack resources
aws cloudformation describe-stack-resources \
--stack-name my-stack
# Get template
aws cloudformation get-template \
--stack-name my-stack
# Delete stack
aws cloudformation delete-stack \
--stack-name my-stack
# Create stack set
aws cloudformation create-stack-set \
--stack-set-name my-stack-set \
--template-body file://template.yaml
# Create stack instances
aws cloudformation create-stack-instances \
--stack-set-name my-stack-set \
--accounts 123456789012 123456789013 \
--regions us-east-1 us-west-2

CloudFormation Template Best Practices
+------------------------------------------------------------------+
| |
| 1. Use YAML format |
| +------------------------------------------------------------+ |
| | - More readable than JSON | |
| | - Supports comments | |
| +------------------------------------------------------------+ |
| |
| 2. Use parameters for customization |
| +------------------------------------------------------------+ |
| | - Make templates reusable | |
| | - Avoid hardcoding values | |
| +------------------------------------------------------------+ |
| |
| 3. Use exports for cross-stack references |
| +------------------------------------------------------------+ |
| | - Share values between stacks | |
| | - Enable modular architecture | |
| +------------------------------------------------------------+ |
| |
| 4. Implement proper tagging |
| +------------------------------------------------------------+ |
| | - Tag all resources | |
| | - Use consistent tag schema | |
| +------------------------------------------------------------+ |
| |
| 5. Use DeletionPolicy for important resources |
| +------------------------------------------------------------+ |
| | - Retain critical data | |
| | - Create snapshots before deletion | |
| +------------------------------------------------------------+ |
| |
+------------------------------------------------------------------+
Stack Management Best Practices
+------------------------------------------------------------------+
| |
| 1. Always use change sets for updates |
| +------------------------------------------------------------+ |
| | - Preview changes before applying | |
| | - Avoid unintended replacements | |
| +------------------------------------------------------------+ |
| |
| 2. Use nested stacks for large templates |
| +------------------------------------------------------------+ |
| | - Break down complex infrastructure | |
| | - Reuse common components | |
| +------------------------------------------------------------+ |
| |
| 3. Implement stack policies |
| +------------------------------------------------------------+ |
| | - Protect critical resources | |
| | - Prevent accidental updates | |
| +------------------------------------------------------------+ |
| |
| 4. Monitor stack events |
| +------------------------------------------------------------+ |
| | - Track creation/update progress | |
| | - Identify failures quickly | |
| +------------------------------------------------------------+ |
| |
+------------------------------------------------------------------+

Exam Tip

Key Exam Points
+------------------------------------------------------------------+
| |
| 1. CloudFormation is Infrastructure as Code (IaC) |
| |
| 2. Templates can be YAML or JSON (YAML preferred) |
| |
| 3. Resources section is required in templates |
| |
| 4. Change sets preview changes before execution |
| |
| 5. StackSets deploy to multiple accounts/regions |
| |
| 6. Use !Ref to reference parameters and resources |
| |
| 7. Use !GetAtt to get resource attributes |
| |
| 8. DeletionPolicy: Retain, Delete, Snapshot |
| |
| 9. Exports allow cross-stack references |
| |
| 10. Nested stacks break down large templates |
| |
+------------------------------------------------------------------+

Chapter 33 Summary
+------------------------------------------------------------------+
| |
| CloudFormation Core Concepts |
| +------------------------------------------------------------+ |
| | - Templates: Infrastructure definition | |
| | - Stacks: Deployed resources | |
| | - Change Sets: Preview changes | |
| | - StackSets: Multi-account/region deployment | |
| +------------------------------------------------------------+ |
| |
| Template Components |
| +------------------------------------------------------------+ |
| | - Parameters: Input values | |
| | - Resources: AWS resources (required) | |
| | - Outputs: Return values | |
| | - Mappings: Conditional values | |
| | - Conditions: Conditional logic | |
| +------------------------------------------------------------+ |
| |
| Best Practices |
| +------------------------------------------------------------+ |
| | - Use change sets for updates | |
| | - Use parameters for reusability | |
| | - Use exports for cross-stack references | |
| | - Use nested stacks for large templates | |
| +------------------------------------------------------------+ |
| |
+------------------------------------------------------------------+

Previous Chapter: Chapter 32: AWS CodePipeline & CI/CD Best Practices Next Chapter: Chapter 34: AWS CDK - Cloud Development Kit