1.1 - PaulDuvall/aws-compliance-workshop GitHub Wiki

1.1 AWS CloudFormation

A CloudFormation template is a set of instructions for creating AWS resources, which includes practically everything that can be created in AWS. At its simplest, the service accepts a template (a YAML-based blueprint describing the resources you want to create or update) and creates a Stack (a set of resources created using a single template). The resulting Stacks represent groups of resources whose lifecycles are inherently linked.

Use AWS CloudFormation

  1. Review Template Anatomy.
  2. Review the top-level objects of a CloudFormation template: AWSTemplateFormatVersion, Description, Parameters, Resources, Mappings, Outputs in the CloudFormation template. The Resources object is the only object that is required.
  3. Resources contain the definitions of the AWS resources you want to create with the template. Each resource is listed separately and specifies the properties necessary for creating that particular resource. The resource declaration begins with a String that specifies the logical name for the resource. The logical name can be used to refer to the resources within the template.
  4. You use Parameters to declare values that can be passed to the template when you create the Stack. A parameter is an effective way to specify anything you want users to customize or store in the template itself.
  5. You use Mappings to declare conditional values that are evaluated in a similar manner as a switch statement. An example mapping might be to select the correct AMI for the Region and the Architecture Type for the instance type.
  6. Outputs define custom values that are returned by the describe-stacks command and in the AWS Management Console Outputs tab after the stack is created. You can use Output values to return information from the resources in the stacks such as the URL for a website created in the template.

Template Anatomy

---
AWSTemplateFormatVersion: "version date"

Description:
  String

Metadata:
  template metadata

Parameters:
  set of parameters

Mappings:
  set of mappings

Conditions:
  set of conditions

Transform:
  set of transforms

Resources:
  set of resources

Outputs:
  set of outputs

Examples

---
AWSTemplateFormatVersion: '2010-09-09'

Description: This template creates one or more Amazon resources.

Metadata:
  AWS::CloudFormation::Interface:
    ParameterGroups:
      - Label:
          default: "GitHub Configuration"
        Parameters:
          - GitHubToken
          - GitHubUser
          - GitHubRepo
          - GitHubBranch
    ParameterLabels:
      GitHubToken:
        default: GitHub OAuth2 Token
      GitHubUser: 
        default: GitHub User/Org Name
      GitHubRepo: 
        default: GitHub Repository Name
      GitHubBranch: 
        default: GitHub Branch Name

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]*$

Mappings: 
  RegionMap: 
    us-east-1: 
      "HVM64": "ami-0ff8a91507f77f867"
    us-west-1: 
      "HVM64": "ami-0bdb828fd58c52235"
    eu-west-1: 
      "HVM64": "ami-047bb4163c506cd98"
    ap-southeast-1: 
      "HVM64": "ami-08569b978cc4dfa10"
    ap-northeast-1: 
      "HVM64": "ami-06cd52961ce9f0d85"

Conditions: 
  CreateProdResources: !Equals [ !Ref EnvType, prod ]

Transform: AWS::Serverless-2016-10-31

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: {}
    
Outputs:
  StackVPC:
    Description: The ID of the VPC
    Value: !Ref MyVPC
    Export:
      Name: !Sub "${AWS::StackName}-VPCID"

Simple CloudFormation Template

---
AWSTemplateFormatVersion: '2010-09-09'
Description: This template creates one or more Amazon resources. You will be billed for the AWS resources used if you create a stack from this template.
Resources:
  MyQueue:
    Type: AWS::SQS::Queue
    Properties:
      QueueName:
        Fn::Join:
        - ''
        - - SampleQueue-
          - Ref: AWS::StackName
Outputs:
  MyAWSAccountId:
    Value:
      Ref: MyQueue

CloudFormation References

Launching a Stack from a Template

CLI

Here is an example using the AWS CLI called from the Cloud9 terminal:

aws cloudformation create-stack --stack-name ccoa-1-simple-cli --template-url https://s3.amazonaws.com/cloudformation-templates-stelligent/labs/_example/example.yml --capabilities CAPABILITY_NAMED_IAM

aws cloudformation describe-stacks --stack-name ccoa-1-simple-cli --query 'Stacks[0].Outputs[?OutputKey==`SourceQueueARN`].OutputValue' --output text

AWS Console

  1. Go to the AWS CloudFormation Console
  2. Click Create stack
  3. In the Amazon S3 URL field, enter https://s3.amazonaws.com/cloudformation-templates-stelligent/labs/_example/example.yml
  4. Click Next
  5. Enter a Stack name (e.g. ccoa-1-simple-console) and click Next
  6. Click Next
  7. Click Create stack and wait for the stack to launch.

CloudFormation Stack

SDK

Here is an example using the Node.js SDK for AWS to launch a CloudFormation stack:

var AWS = require('aws-sdk');
AWS.config.update({region: 'us-east-1'});
console.log('Loading function');

exports.handler = function(event, context) {
  console.log('value1 =', event.key1);
  console.log('value2 =', event.key2);
  console.log('value3 =', event.key3);
  var cloudformation = new AWS.CloudFormation();
  var params = {
    StackName: 'ccoa-1-node-cfn',
    Capabilities: ['CAPABILITY_IAM'],
    OnFailure: 'ROLLBACK',
    TemplateURL: 'https://s3.amazonaws.com/cloudformation-templates-stelligent/labs/_example/example.yml',
    TimeoutInMinutes: 0
  };
  cloudformation.createStack(params, function(err, data) {
    if (err) console.log(err, err.stack); // an error occurred
    else console.log(data); // successful response
  });
  context.succeed("Finished");
};

CloudFormation Benefits

With CloudFormation, you can define all of your AWS resources as code and it can be treated as a software asset like your application code. Therefore, you can version it, test it, and provision it as part of a continuous process that is deployed to production. Moreover, since it is a declarative model, you can repeatably and safely deploy changes as part of a single source of truth.

  • Model multiple components of your infrastructure as a unit and as code
  • Single source of truth
  • Version, test, and run with every change just like the rest of your software system

CloudFormation Documentation

AWS Documentation Hub

Here is the AWS CloudFormation Documentation.

There is a user guide, API Reference, and CLI documentation for CloudFormation. You can also visit AWS Solutions for production-ready solutions you can launch from CloudFormation.

User Guide

Review the AWS CloudFormation user guide.

AWS Resource and Property Types Reference

Go to Template Reference and then Resource and Property Reference

API Reference

Review the AWS CloudFormation API Reference.

CLI Reference

Review the CLI documentation for CloudFormation.

AWS Solutions

Review AWS Solutions.

AWS Solutions

AWS Quick Starts

AWS Quick Starts

AWS CodeStar

AWS CodeStar has many end-to-end continuous delivery examples that you can use to get started.

AWS CodeStar

Create a new CloudFormation template

From your AWS Cloud9 terminal, create a new directory and then a new file.

cd ~/environment/ccoa
touch ccoa-1-cfn.yml

Open the ccoa-1-cfn.yml file and paste the contents below and save the file:

---
AWSTemplateFormatVersion: '2010-09-09'
Description: This template creates one or more Amazon resources. 
  You will be billed for AWS resources used if you create a stack
Resources:
  MyQueue:
    Type: AWS::SQS::Queue
    Properties:
      QueueName:
        Fn::Join:
        - ''
        - - SampleQueue-
          - Ref: AWS::StackName
Outputs:
  SourceQueueARN: 
    Description: "ARN of source queue"
    Value: 
      Fn::GetAtt: 
        - "MyQueue"
        - "Arn"

Launch CloudFormation Stack from Console

From your Cloud9 terminal environment, type the following (the S3 bucket you are uploading to is the one you created when setting up your development environment):

aws s3 sync /home/ec2-user/environment/ccoa s3://ccoa-$(aws sts get-caller-identity --output text --query 'Account')
  1. Go to the CloudFormation Console
  2. Click Create stack
  3. Enter https://mybucket.s3.amazonaws.com/ccoa-1-cfn.yml in the Amazon S3 URL field (replacing mybucket the S3 bucket you created)
  4. Click Next
  5. Enter ccoa-1-cfn for the Stack name and click Next on the Specify stack details page
  6. Select Disabled radio button for Rollback on failure under Stack creation options
  7. Click Next
  8. Click Create stack

CloudFormation Console

View the Outputs

  1. Go to the CloudFormation console and select the stack once it is CREATE_COMPLETE, select the Outputs tab and select the checkbox next to the stack and click the Outputs tab.
  2. From Outputs, view the SourceQueueARN output.

Resources

Cleanup

Go to Cleanup to remove any resources you created in this sublesson.