CloudFormation AWS infrastructure resources management system https://aws.amazon.com/cloudformation/ Template Basics about templates A template is a text file which declare your AWS resources that make up a stack Can be written in JSON or YAML (preferable) formats Find multiple template snippets Structure AWS template follows AWS SAM template anatomy SAM template has almost the same original CloudFormation template structure, but with special additional resources and properties Transform ( required ) set a macro to process the template Resources ( required ) list of resource objects, like Lambda function, S3 buckets, API Gateways etc... AWSTemplateFormatVersion capabilities of the template based on a version Description arbitrary comments Metadata additional details of the resources in the template Parameters customized values for template or resources Mappings key-value dictionaries from which a value can be looked up and used in the template Conditions condition to created a resource or set a parameter Outputs set a value which can be imported into other stacks or show on CloudFormation console
Transform: AWS::Serverless-2016-10-31
Globals:
set of globals
Description:
String
Metadata:
template metadata
Parameters:
set of parameters
Mappings:
set of mappings
Conditions:
set of conditions
Resources:
set of resources
Outputs:
set of outputs
AWSTemplateFormatVersion Details are here if not specified the latest will be assumed
AWSTemplateFormatVersion: "2010-09-09"
Description Details are here Comments about your template.
Description: >
Here are some
details about
the template.
Metadata Details are here Additional comments or some specific settings Not clear...
Metadata:
Instances:
Description: "Information about the instances"
Databases:
Description: "Information about the databases"
Resources Details are here Resources list included in the stack All resources properties
Resources:
MyEC2Instance:
Type: "AWS::EC2::Instance"
Properties:
ImageId: "ami-0ff8a91507f77f867"
Example of different property types
Properties:
String: OneStringValue
String: A longer string value
Number: 123
LiteralList:
- "[first]-string-value with a special characters"
- "[second]-string-value with a special characters"
Boolean: true
ReferenceForOneValue:
Ref: MyLogicalResourceName
ReferenceForOneValueShortCut: !Ref MyLogicalResourceName
FunctionResultWithFunctionParams: !Sub |
Key=%${MyParameter}
Example defines two resources. The MyInstance resource includes the MyQueue resource as part of its UserData property.
Resources:
MyInstance:
Type: "AWS::EC2::Instance"
Properties:
UserData:
"Fn::Base64":
!Sub |
Queue=${MyQueue}
AvailabilityZone: "us-east-1a"
ImageId: "ami-0ff8a91507f77f867"
MyQueue:
Type: "AWS::SQS::Queue"
Properties: {}
Parameters Details are here Adds custom values to your template each time you create or update a stack to point to the parameter use Ref function can reference parameters from the Resources & Outputs sections of the same template. maximum of 200 parameters in a template Each parameter must be given a logical name A parameter must have a type Following props are available: AllowedPattern AllowedValues ConstraintDescription Default Description MaxLength MaxValue MinLength MinValue NoEcho Type
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.
Resources:
Ec2Instance:
Type: AWS::EC2::Instance
Properties:
InstanceType:
Ref: InstanceTypeParameter
ImageId: ami-0ff8a91507f77f867
Parameters:
DBPort:
Default: 3306
Description: TCP/IP port for the database
Type: Number
MinValue: 1150
MaxValue: 65535
DBPwd:
NoEcho: true
Description: The database admin account password
Type: String
MinLength: 1
MaxLength: 41
AllowedPattern: ^[a-zA-Z0-9]*$
Parameters:
myKeyPair:
Description: Amazon EC2 Key Pair
Type: "AWS::EC2::KeyPair::KeyName"
mySubnetIDs:
Description: Subnet IDs
Type: "List<AWS::EC2::Subnet::Id>"
Rules Details are here Rules validates parameter values during a stack creation CloudFormation evaluates the assertions to verify whether an assertion for a parameter value is true If a parameter value is invalid, AWS CloudFormation does not create or update the stack Following function can be used: 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 Two rules check the value of the InstanceType parameter. Depending on the value of the environment parameter ( test or prod ), the user must specify a1.medium or a1.large for the InstanceType parameter. The InstanceType and Environment parameters must be declared in the Parameters section of the same template.
Rules:
testInstanceType:
RuleCondition: !Equals
- !Ref Environment
- test
Assertions:
- Assert:
'Fn::Contains':
- - a1.medium
- !Ref InstanceType
AssertDescription: 'For a test environment, the instance type must be a1.medium'
prodInstanceType:
RuleCondition: !Equals
- !Ref Environment
- prod
Assertions:
- Assert:
'Fn::Contains':
- - a1.large
- !Ref InstanceType
AssertDescription: 'For a production environment, the instance type must be a1.large'
Mappings Details are here matches a key to a corresponding set of named values can use to specify conditional parameter values, similar to a lookup table match a key to a corresponding value by using the Fn::FindInMap function which returns a named value based on a specified key. Example template contains an Amazon EC2 resource whose ImageId property is assigned by the FindInMap function. The FindInMap function specifies key as the region where the stack is created and HVM64 as the name of the value to map to.
AWSTemplateFormatVersion: "2010-09-09"
Mappings:
RegionMap:
us-east-1:
HVM64: ami-0ff8a91507f77f867
HVMG2: ami-0a584ac55a7631c0c
us-west-1:
HVM64: ami-0bdb828fd58c52235
HVMG2: ami-066ee5fd4a9ef77f1
eu-west-1:
HVM64: ami-047bb4163c506cd98
HVMG2: ami-0a7c483d527806435
ap-northeast-1:
HVM64: ami-06cd52961ce9f0d85
HVMG2: ami-053cdd503598e4a9d
ap-southeast-1:
HVM64: ami-08569b978cc4dfa10
HVMG2: ami-0be9df32ae9f92309
Resources:
myEC2Instance:
Type: "AWS::EC2::Instance"
Properties:
ImageId: !FindInMap [RegionMap, !Ref "AWS::Region", HVM64]
InstanceType: m1.small
Conditions Details are here controls whether certain resources are created or whether certain resource properties are assigned a value during stack creation or update for ex. may create a condition when to create the resource or output or set a property function to be used: Fn::And , Fn::Equals , Fn::If , Fn::Not , Fn::Or In the example we have EnvType input parameter, where you can specify prod or test to create a stack. For a prod env we create an EC2 instance and attache a volume to the instance. For a test env just create the EC2 instance.
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
Nested condition. For a stack deployed in a production environment, AWS CloudFormation creates a policy for the S3 bucket.
Parameters:
EnvType:
Type: String
AllowedValues:
- prod
- test
BucketName:
Default: ''
Type: String
Conditions:
IsProduction: !Equals
- !Ref EnvType
- prod
CreateBucket: !Not
- !Equals
- !Ref BucketName
- ''
CreateBucketPolicy: !And
- !Condition IsProduction
- !Condition CreateBucket
Resources:
Bucket:
Type: 'AWS::S3::Bucket'
Condition: CreateBucket
Policy:
Type: 'AWS::S3::BucketPolicy'
Condition: CreateBucketPolicy
Properties:
Bucket: !Ref Bucket
PolicyDocument: ...
Transform Details are here Specifies a macros to process the template Must include this section with a value of AWS::Serverless-2016-10-31 Additional transforms are optional. Let's skip it for now... Globals Details are here Defines properties that are common to all your serverless functions and APIs. This section is unique to AWS SAM. Transform Details are here Specifies a macros to process the template Must include this section with a value of AWS::Serverless-2016-10-31 Let's skip it for now... Outputs Details are here declares output values that you can import into other stacks, return in response (to describe stack calls), or view on the AWS CloudFormation console. For ex, can output the S3 bucket name to make the bucket easier to find. Max 200 outputs per template BackupLoadBalancerDNSName output returns the DNS name for the resource with the logical ID BackupLoadBalancer only when the CreateProdResources condition is true. (The second output shows how to specify multiple outputs.)
Outputs:
BackupLoadBalancerDNSName:
Description: The DNSName of the backup load balancer
Value: !GetAtt BackupLoadBalancer.DNSName
Condition: CreateProdResources
InstanceID:
Description: The Instance ID
Value: !Ref EC2Instance
Output named StackVPC returns the ID of a VPC, and then exports the value for cross-stack referencing with the name VPCID appended to the stack's name.
Outputs:
StackVPC:
Description: The ID of the VPC
Value: !Ref MyVPC
Export:
Name: !Sub "${AWS::StackName}-VPCID"
Pseudo parameters Parameters that are predefined by AWS CloudFormation Used as a parameter AWS::AccountId returns the AWS account ID of the account in which the stack is being created, such as 123456789012 AWS::NotificationARNs returns the list of notification Amazon Resource Names (ARNs) for the current stack AWS::NoValue removes the resource property when specified as a return value in the Fn::If function AWS::Partition returns the partition that the resource is in AWS::Region returns a string representing the Region in which the encompassing resource is being created AWS::StackId returns the ID of the stack AWS::StackName returns the name of the stack AWS::URLSuffix returns the suffix for a domain. The suffix is typically amazonaws.com
Outputs:
MyStacksRegion:
Value: !Ref "AWS::Region"
Built-in functions Details are here Can use intrinsic functions in resource properties, outputs, metadata attributes, and update policy attributes. You can also use intrinsic functions to conditionally create stack resources. Fn::Base64 , Fn::Cidr , Condition functions , Fn::FindInMap , Fn::GetAtt , Fn::GetAZs , Fn::ImportValue , Fn::Join , Fn::Length , Fn::Select , Fn::Split , Fn::Sub , Fn::ToJsonString , Fn::Transform , Ref condition functions: Fn::And , Fn::Equals , Fn::If , Fn::Not , Fn::Or Ref The function Ref returns the value of the specified parameter or resource When specify a parameter's logical name, it returns the value of the parameter When specify a resource's logical name, it returns a value that you can typically use to refer to that resource, such as a physical ID Find what Ref returns for every resource or parameter here
Ref: logicalName_of_the_resource_or_parameter
Or shorter way
!Ref logicalName_of_the_resource_or_parameter
Elastic IP address gets the instance ID of an EC2 MyEC2Instance resource
MyEIP:
Type: "AWS::EC2::EIP"
Properties:
InstanceId: !Ref MyEC2Instance
AWS CDK https://docs.aws.amazon.com/cdk/index.html If you do not like to deal with template.yaml you may manage your CloudFormation infrastructure through programming code using AWS CDK AWS SAM AWS Serverless Application Model is the framework on top of CloudFormation can use both the AWS CloudFormation and AWS SAM syntax within the same template SAM template has almost the same original CloudFormation template structure, but with special additional resources and properties fewer lines of code for the same result, SAM transforms your template into real CloudFormation template SAM CLI has CLI for initialize a project, deploy, debug, test, Configure CI/CD pipeline, monitor, sync local changes SAM template
AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::Serverless-2016-10-31
Resources:
getAllItemsFunction:
Type: AWS::Serverless::Function
Properties:
Handler: src/get-all-items.getAllItemsHandler
Runtime: nodejs12.x
Events:
Api:
Type: HttpApi
Properties:
Path: /
Method: GET
Connectors:
MyConn:
Properties:
Destination:
Id: SampleTable
Permissions:
- Read
SampleTable:
Type: AWS::Serverless::SimpleTable
Vs same AWS CloudFormation template
{
"AWSTemplateFormatVersion": "2010-09-09",
"Resources": {
"getAllItemsFunction": {
"Type": "AWS::Lambda::Function",
"Metadata": {
"SamResourceId": "getAllItemsFunction"
},
"Properties": {
"Code": {
"S3Bucket": "aws-sam-cli-managed-default-samclisourcebucket-1a4x26zbcdkqr",
"S3Key": "what-is-app/a6f856abf1b2c4f7488c09b367540b5b"
},
"Handler": "src/get-all-items.getAllItemsHandler",
"Role": {
"Fn::GetAtt": [
"getAllItemsFunctionRole",
"Arn"
]
},
"Runtime": "nodejs12.x",
"Tags": [
{
"Key": "lambda:createdBy",
"Value": "SAM"
}
]
}
},
"getAllItemsFunctionRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"sts:AssumeRole"
],
"Effect": "Allow",
"Principal": {
"Service": [
"lambda.amazonaws.com"
]
}
}
]
},
"ManagedPolicyArns": [
"arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
],
"Tags": [
{
"Key": "lambda:createdBy",
"Value": "SAM"
}
]
}
},
"getAllItemsFunctionApiPermission": {
"Type": "AWS::Lambda::Permission",
"Properties": {
"Action": "lambda:InvokeFunction",
"FunctionName": {
"Ref": "getAllItemsFunction"
},
"Principal": "apigateway.amazonaws.com",
"SourceArn": {
"Fn::Sub": [
"arn:${AWS::Partition}:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/",
{
"__ApiId__": {
"Ref": "ServerlessHttpApi"
},
"__Stage__": "*"
}
]
}
}
},
"ServerlessHttpApi": {
"Type": "AWS::ApiGatewayV2::Api",
"Properties": {
"Body": {
"info": {
"version": "1.0",
"title": {
"Ref": "AWS::StackName"
}
},
"paths": {
"/": {
"get": {
"x-amazon-apigateway-integration": {
"httpMethod": "POST",
"type": "aws_proxy",
"uri": {
"Fn::Sub": "arn:${AWS::Partition}:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${getAllItemsFunction.Arn}/invocations"
},
"payloadFormatVersion": "2.0"
},
"responses": {}
}
}
},
"openapi": "3.0.1",
"tags": [
{
"name": "httpapi:createdBy",
"x-amazon-apigateway-tag-value": "SAM"
}
]
}
}
},
"ServerlessHttpApiApiGatewayDefaultStage": {
"Type": "AWS::ApiGatewayV2::Stage",
"Properties": {
"ApiId": {
"Ref": "ServerlessHttpApi"
},
"StageName": "$default",
"Tags": {
"httpapi:createdBy": "SAM"
},
"AutoDeploy": true
}
},
"SampleTable": {
"Type": "AWS::DynamoDB::Table",
"Metadata": {
"SamResourceId": "SampleTable"
},
"Properties": {
"AttributeDefinitions": [
{
"AttributeName": "id",
"AttributeType": "S"
}
],
"KeySchema": [
{
"AttributeName": "id",
"KeyType": "HASH"
}
],
"BillingMode": "PAY_PER_REQUEST"
}
},
"getAllItemsFunctionMyConnPolicy": {
"Type": "AWS::IAM::ManagedPolicy",
"Metadata": {
"aws:sam:connectors": {
"getAllItemsFunctionMyConn": {
"Source": {
"Type": "AWS::Serverless::Function"
},
"Destination": {
"Type": "AWS::Serverless::SimpleTable"
}
}
}
},
"Properties": {
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"dynamodb:GetItem",
"dynamodb:Query",
"dynamodb:Scan",
"dynamodb:BatchGetItem",
"dynamodb:ConditionCheckItem",
"dynamodb:PartiQLSelect"
],
"Resource": [
{
"Fn::GetAtt": [
"SampleTable",
"Arn"
]
},
{
"Fn::Sub": [
"${DestinationArn}/index/*",
{
"DestinationArn": {
"Fn::GetAtt": [
"SampleTable",
"Arn"
]
}
}
]
}
]
}
]
},
"Roles": [
{
"Ref": "getAllItemsFunctionRole"
}
]
}
}
}
}