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" } ] } } } }