cvwiki

CloudFormation

Nov 5, 2022

# Resources

# CloudFormation

1
2
3
4
5
6
7
Resources:
  Instance: ## Name of the logical resource (Can be anything)
    Type: 'AWS::EC2::Instance'
		Properties:
		  ImageId: !Ref LatestAmiId
		  InstanceType: "t3.micro"
			KeyName: 'A4L' ## SSH key to use

# Non-Portable Template Example

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
Resources:
  Bucket: 
    Type: 'AWS::S3::Bucket'
		Properties:
		  BucketName: 'accatpics13333337'
  Instance:
    Type: 'AWS::EC2::Instance'
		Properties:
			KeyName: 'A4L'
		  InstanceType: 't2.micro'
		  ImageId: 'ami-04d29b6f966df1537' ## AMI ID for Amazon Linux 2

# Template Parameters and Pseudo Parameters

# Template Parameters

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
Parameters:
  InstanceType:
    Type: String
    Default: 't3.micro'
		AllowedValues:
		  - 't3.micro'
		  - 't3.medium'
		  - 't3.large'
		Description: 'Pick a supported InstanceType'
	InstanceAmiId:
	  Type: String
		Description: 'AMI ID For Instances.'

# Pseudo Parameters

# Best Practices

# Intrinsic Functions

1
2
3
4
5
6
7
8
9
VPC:
  Type: AWS::EC2::VPC
	Properties:
	  CidrBlock: "10.16.0.0/16"
Subnet1:
  Type: AWS::EC2::Subnet
  Properties:
    CidrBlock: !Select [ "0", !Cidr [ !GetAtt VPC.CidrBlock, "16", "12" ] ]
		VpcId: !Ref VPC

# Mappings

# Outputs

Example Output

1
2
3
4
Outputs:
  WordpressURL:
    Description: "Instance Web URL"
    Value: !Join [ '', 'https://', !GetAtt Instance.DNSName ] ]

# Conditions

1
2
3
4
5
6
7
Parameters:
  EnvType:
    Default: 'dev'
    Type: String
    AllowedValues:
      - 'dev'
      - 'prod'
1
2
3
4
Conditions:
  IsProd: !Equals
    - !Ref EnvType
    - 'prod'
1
2
3
4
5
6
Resources:
  Wordpress:
    Type: 'AWS::EC2::Instance'
		Condition: IsProd
    Properties:
      ImageId: 'whatever'

# Depends On

# Wait Conditions, Creation Policies & cfn-signal

# CreationPolicy Example:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
AutoScalingGroup:
Type: AWS::AutoScaling::AutoScalingGroup
Properties:
  ... (stuff here)
  DesiredCapacity: '3'
	MinSize: '1'
	MaxSize: '4'
CreationPolicy:
  ResourceSignal:
	  Count: '3'
		Timeout: PT15M 
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
LaunchConfig:
  Type:
  AWS::AutoScaling::LaunchConfiguration  
	Properties:
	  ... (stuff here)
		UserData:
		  "Fn::Base64"
			  !Sub |
			    #/bin/bash -xe
					yum update -y aws-cfn-bootstrap
					... ('some bootstrapping')
					/opt/aws/bin/cfn-signal -e $?
					--stack ${AWS::StackName}
					--resource AutoScalingGroup
					--region ${AWS::Region}
# WaitCondition Example:
1
2
3
4
5
6
7
WaitCondition:
  Type: AWS::CloudFormation::WaitCondition
  DependsOn: "someresource"
	Properties:
	  Handle: !Ref "WaitHandle"
		Timeout: "300"
		Count: '1'
1
2
WaitHandle:
  Type: AWS::CloudFormation::WaitConditionHandle

# Nested Stacks (reuses the code, not the resources)

# CFN Nested Stacks
1
2
3
4
5
6
7
8
VPCSTACK:
  Type: AWS::CloudFormation::Stack
  Properties:
    TemplateURL: https://someurl.com/template.yaml
    Parameters:
      Param1: !Ref SomeParam1
      Param2: !Ref SomeParam2
      Param3: !Ref SomeParam3

# Cross-Stack References (reuse the actual resources in another stack)

1
2
3
4
5
6
Outputs:
  SHAREDVPCID:
    Description: Shared Services VPC
		Value: !Ref VPC
		Export:
		  Name: SHAREDVPC

# Stack Sets (CloudFormation stacks across AWS accounts & regions)

# Deletion Policy: Tune resource deletion to take backups, to prevent data loss during stack delete operations

# Stack Roles

# cfn-init: Run once to bootstrap an EC2 instance (configure, install dependencies, etc.)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
EC2Instance:
  Type: AWS::EC2::Instance
  CreationPolicy: ...
  Metadata:
    AWS::CloudFormation::Init:
      configSets: ... # defines which configkeys to use and in which order to apply
      install_cfn: ...
      software_install: ...
      configure_instance: ...
      install_wordpress: ...
      configure_wordpress: ... # this is an example of a config key

The below is ran on EC2 startup:

1
2
3
4
5
6
UserData:
  Fn::Base64: !Sub |
    #!/bin/bash -xe
    yum -y update
    /opt/aws/bin/cfn-init -v --stack ${AWS::StackId} --resource EC2Instance --configsets wordpress_install --region ${AWS::Region}
    /opt/aws/bin/cfn-signal -e --stack ${AWS::StackId} --resource EC2Instance --region ${AWS::Region}

ConfigKey could contain the following:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
packages:
 .. 'packages to install'
groups:
 .. 'local group mgmt'
users:
 .. 'local user mgmt'
sources:
 .. 'download and extract archives'
files:
 .. 'files to create'
commands:
 .. 'commands to execute'
services:
 .. 'services to enable'

# cfn-hup: Trigger a cfn-init operation when EC2 metadata changes are detected during stack update operations

# ChangeSets: Preview changes to a template

# Custom Resources: Extend the functionality of CloudFormation beyond things it natively supports

# #sysops Scenarios

Question: A SysOps Administrator needs to install and configure software applications to an EC2 instance that will be deployed using CloudFormation. The Administrator has to ensure that the applications are properly running before the stack creation proceeds. Which of the following options can satisfy the given requirement?

Answer: Add a CreationPolicy attribute to the instance then send a success signal after the applications are installed and configured. Use the cfn-signal helper script to signal a resource.

You can associate the CreationPolicy attribute with a resource to prevent its status from reaching create complete until AWS CloudFormation receives a specified number of success signals or the timeout period is exceeded. To signal a resource, you can use the cfn-signal helper script or SignalResource API. AWS CloudFormation publishes valid signals to the stack events so that you track the number of signals sent.

The creation policy is invoked only when AWS CloudFormation creates the associated resource. Currently, the only AWS CloudFormation resources that support creation policies are AWS::AutoScaling::AutoScalingGroup, AWS::EC2::Instance, and AWS::CloudFormation::WaitCondition.

Use the CreationPolicy attribute when you want to wait on resource configuration actions before the stack creation proceeds. For example, if you install and configure software applications running on an EC2 instance, you might want those applications to be running before proceeding. In such cases, you can add a CreationPolicy attribute to the instance, and then send a success signal to the instance after the applications are installed and configured.


Question: A SysOps Administrator needs to create a CloudFormation template that should automatically rollback in the event that the entire stack failed to launch. The application stack requires the pre-requisite packages to be installed first in order for it to run properly, which could take about an hour or so to complete.

What should the Administrator add in the template to accomplish this requirement?

Answer: In the ResourceSignal parameter of the CreationPolicy resource attribute, add a Timeout property with a value of 2 hours.

Associate the CreationPolicy attribute with a resource to prevent its status from reaching create complete until AWS CloudFormation receives a specified number of success signals or the timeout period is exceeded. To signal a resource, you can use the cfn-signal helper script or ScriptResource API. AWS CloudFormation publishes valid signals to the stack events so that you track the number of signals sent.

The creation policy is invoked only when AWS CloudFormation creates the associated resource. Currently, the only AWS CloudFormation resources that support creation policies AWS::AutoScaling::AutoScalingGroup, AWS::EC2::Instance, AWS::CloudFormation::WaitCondition.

Use the CreationPolicy attribute when you want to wait on resource configuration actions before stack creation proceeds. For example, if you install and configure software applications on an EC2 instance, you might want those applications to be running before proceeding. In such cases, you can add a CreationPolicy attribute to the instance, and then send a success signal to the instance after the applications are installed and configured.

1
2
3
4
5
6
CreationPolicy:
  AutoScalingCreationPolicy:
    MinSuccessfulInstancesPercent: Integer
  ResourceSignal:
    Count: Integer
    Timeout: String

The Timeout property is the length of time that AWS CloudFormation waits for the number of signals that were specified in the Count property. The timeout period starts after AWS CloudFormation starts creating the resource, and the timeout expires no sooner than the time you specify but can occur shortly thereafter. The maximum time that you can specify is 12 hours.


Question: A SysOps Administrator has been instructed to handle the deployment of the cloud resources in a single AWS account using CloudFormation. The Administrator must develop a unified template that can be reused for multiple environments instead of manually copying and pasting the same configurations into the template. The dedicated template will be used and referenced from within other templates in the same AWS Region. If the template has been updated, any stack that is referencing it will automatically use the updated configuration.

How can the Administrator meet this requirement?

Answer: Use Nested Stacks.

Nested stacks are stacks created as part of other stacks. You can create a nested stack within another stack by using the AWS::CloudFormation::Stack resource.

As your infrastructure grows, common patterns can emerge in which you declare the same components in multiple templates. You can separate out these commons components and create dedicated templates for them. Then use the resource in your template to reference other templates, creating nested stacks.

For example, assume that you have a load balancer configuration that you use for most of your stacks. Instead of copying and pasting the same configurations into your templates, you can create a dedicated template for the load balancer. Then, you just use the AWS::CloudFormation::Stack resource to reference that template from within other templates.

If the load balancer template is updated, any stack that is referencing it will use the updated load balancer (only after you update the stack). In addition to simplifying updates, this approach lets you use experts to create and maintain components that you might not necessarily be familiar with. All you need to do is reference their templates.

StackSets would be incorrect here because a stack set simply lets you create stacks in AWS accounts across regions by using a single AWS CloudFormation template. The scenario mentioned that the cloud resources are in a single AWS account and also, the dedicated template will be referenced from within other templates in the same AWS Region. For this kind of situation, using a nested stack is more suitable than StackSets.

ChangeSets would also be incorrect because a ChangeSet is primarily used to preview how the proposed changes to a stack might impact your running resources in AWS.

StackPolicies is also incorrect because a StackPolicy is commonly used to prevent stack resources from being unintentionally updated or deleted during a stack update. A stack policy is a JSON document that defines the update actions that can performed on designated resources.