This is dedicated to Cloud Formation..

  • Can you name CF template sections?
---
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
  • Maping & Conditions usage example?

The following sample template includes an EnvType input parameter, where you can specify prod to create a stack for production or test to create a stack for testing. For a production environment, AWS CloudFormation creates an Amazon EC2 instance and attaches a volume to the instance. For a test environment, AWS CloudFormation creates only the Amazon EC2 instance.

The CreateProdResources condition evaluates to true if the EnvType parameter is equal to prod. In the sample template, the NewVolume and MountPoint resources are associated with the CreateProdResources condition. Therefore, the resources are created only if the EnvType parameter is equal to prod.

AWSTemplateFormatVersion: "2010-09-09"
Mappings: 
  RegionMap: 
    us-east-1: 
      AMI: "ami-7f418316"
      TestAz: "us-east-1a"
    us-west-1: 
      AMI: "ami-951945d0"
      TestAz: "us-west-1a"
    us-west-2: 
      AMI: "ami-16fd7026"
      TestAz: "us-west-2a"
    eu-west-1: 
      AMI: "ami-24506250"
      TestAz: "eu-west-1a"
    sa-east-1: 
      AMI: "ami-3e3be423"
      TestAz: "sa-east-1a"
    ap-southeast-1: 
      AMI: "ami-74dda626"
      TestAz: "ap-southeast-1a"
    ap-southeast-2: 
      AMI: "ami-b3990e89"
      TestAz: "ap-southeast-2a"
    ap-northeast-1: 
      AMI: "ami-dcfa4edd"
      TestAz: "ap-northeast-1a"
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: !FindInMap [RegionMap, !Ref "AWS::Region", AMI]
  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
Outputs: 
  VolumeId: 
    Condition: CreateProdResources
    Value: 
      !Ref NewVolume 
  • Name some intrinsic functions?

You can use the following intrinsic functions to define conditions:

  • Fn::AndFn::FindInMapFn::EqualsFn::IfFn::NotFn::OrWhat is a Custom Resource?

Custom resources enable you to write custom provisioning logic in templates that AWS CloudFormation runs anytime you create, update (if you changed the custom resource), or delete stacks. For example, you might want to include resources that aren’t available as AWS CloudFormation resource types. You can include those resources by using custom resources. That way you can still manage all your related resources in a single stack.

  • Metadata example?

You can use the optional Metadata section to include arbitrary JSON or YAML objects that provide details about the template. For example, you can include template implementation details about specific resources, as shown in the following snippet:

Metadata:
  Instances:
    Description: "Information about the instances"
  Databases: 
    Description: "Information about the databases"
Metadata Keys

Some AWS CloudFormation features retrieve settings or configuration information that you define from the Metadata section. You define this information in the following AWS CloudFormation-specific metadata keys:

AWS::CloudFormation::Init
Defines configuration tasks for the cfn-init helper script. This script is useful for configuring and installing applications on EC2 instances. For more information, see AWS::CloudFormation::Init.

AWS::CloudFormation::Interface
Defines the grouping and ordering of input parameters when they are displayed in the AWS CloudFormation console. By default, the AWS CloudFormation console alphabetically sorts parameters by their logical ID. For more information, see AWS::CloudFormation::Interface.

Example: AWS::CloudFormation::Init

http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-init.html

Resources:

MyInstance:

Type: "AWS::EC2::Instance"

Metadata:

AWS::CloudFormation::Init:

config:

packages:

:

groups:

:

users:

:

sources:

:

files:

:

commands:

:

services:

:

Properties:

:An example Template covering all sections?

AWSTemplateFormatVersion: "2010-09-09"
Description: "AWS CloudFormation Sample Template Drupal_Single_Instance. Drupal is an open source content management platform powering millions of websites and applications. This template installs a singe instance deployment with a local MySQL database for storage. It uses the AWS CloudFormation bootstrap scripts to install packages and files at instance launch time. **WARNING** This template creates an Amazon EC2 instance. You will be billed for the AWS resources used if you create a stack from this template."
Parameters: 
 KeyName: 
 Description: "Name of an existing EC2 KeyPair to enable SSH access to the instances"
 Type: String
 MinLength: 1
 MaxLength: 255
 AllowedPattern: "[\\x20-\\x7E]*"
 ConstraintDescription: "can contain only ASCII characters."
 InstanceType: 
 Description: "WebServer EC2 instance type"
 Type: String
 Default: "m1.small"
 AllowedValues: 
 - 
 "t1.micro"
 - 
 "m1.small"
 - 
 "m1.medium"
 - 
 "m1.large"
 - 
 "m1.xlarge"
 - 
 "m2.xlarge"
 - 
 "m2.2xlarge"
 - 
 "m2.4xlarge"
 - 
 "m3.xlarge"
 - 
 "m3.2xlarge"
 - 
 "c1.medium"
 - 
 "c1.xlarge"
 - 
 "cc1.4xlarge"
 - 
 "cc2.8xlarge"
 - 
 "cg1.4xlarge"
 ConstraintDescription: "must be a valid EC2 instance type."
 SiteName: 
 Default: "My Site"
 Description: "The name of the Drupal Site"
 Type: String
 SiteEMail: 
 Description: "EMail for site adminitrator"
 Type: String
 SiteAdmin: 
 Description: "The Drupal site admin account username"
 Type: String
 MinLength: 1
 MaxLength: 16
 AllowedPattern: "[a-zA-Z][a-zA-Z0-9]*"
 ConstraintDescription: "must begin with a letter and contain only alphanumeric characters."
 SitePassword: 
 NoEcho: true
 Description: "The Drupal site admin account password"
 Type: String
 MinLength: 1
 MaxLength: 41
 AllowedPattern: "[a-zA-Z0-9]*"
 ConstraintDescription: "must contain only alphanumeric characters."
 DBName: 
 Default: drupaldb
 Description: "The Drupal database name"
 Type: String
 MinLength: 1
 MaxLength: 64
 AllowedPattern: "[a-zA-Z][a-zA-Z0-9]*"
 ConstraintDescription: "must begin with a letter and contain only alphanumeric characters."
 DBUsername: 
 Default: admin
 NoEcho: true
 Description: "The Drupal database admin account username"
 Type: String
 MinLength: 1
 MaxLength: 16
 AllowedPattern: "[a-zA-Z][a-zA-Z0-9]*"
 ConstraintDescription: "must begin with a letter and contain only alphanumeric characters."
 DBPassword: 
 Default: admin
 NoEcho: true
 Description: "The Drupal database admin account password"
 Type: String
 MinLength: 1
 MaxLength: 41
 AllowedPattern: "[a-zA-Z0-9]*"
 ConstraintDescription: "must contain only alphanumeric characters."
 DBRootPassword: 
 NoEcho: true
 Description: "Root password for MySQL"
 Type: String
 MinLength: 1
 MaxLength: 41
 AllowedPattern: "[a-zA-Z0-9]*"
 ConstraintDescription: "must contain only alphanumeric characters."
 SSHLocation: 
 Description: "The IP address range that can be used to SSH to the EC2 instances"
 Type: String
 MinLength: 9
 MaxLength: 18
 Default: "0.0.0.0/0"
 AllowedPattern: "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})"
 ConstraintDescription: "must be a valid IP CIDR range of the form x.x.x.x/x."
Mappings: 
 AWSInstanceType2Arch: 
 "t1.micro": 
 Arch: 64
 "m1.small": 
 Arch: 64
 "m1.medium": 
 Arch: 64
 "m1.large": 
 Arch: 64
 "m1.xlarge": 
 Arch: 64
 "m2.xlarge": 
 Arch: 64
 "m2.2xlarge": 
 Arch: 64
 "m2.4xlarge": 
 Arch: 64
 "m3.xlarge": 
 Arch: 64
 "m3.2xlarge": 
 Arch: 64
 "c1.medium": 
 Arch: 64
 "c1.xlarge": 
 Arch: 64
 "cc1.4xlarge": 
 Arch: 64HVM
 "cc2.8xlarge": 
 Arch: 64HVM
 "cg1.4xlarge": 
 Arch: 64HVM
 AWSRegionArch2AMI: 
 "us-east-1": 
 32: "ami-a0cd60c9"
 64: "ami-aecd60c7"
 64HVM: "ami-a8cd60c1"
 "us-west-2": 
 32: "ami-46da5576"
 64: "ami-48da5578"
 64HVM: NOT_YET_SUPPORTED
 "us-west-1": 
 32: "ami-7d4c6938"
 64: "ami-734c6936"
 64HVM: NOT_YET_SUPPORTED
 "eu-west-1": 
 32: "ami-61555115"
 64: "ami-6d555119"
 64HVM: "ami-67555113"
 "ap-southeast-1": 
 32: "ami-220b4a70"
 64: "ami-3c0b4a6e"
 64HVM: NOT_YET_SUPPORTED
 "ap-southeast-2": 
 32: "ami-b3990e89"
 64: "ami-bd990e87"
 64HVM: NOT_YET_SUPPORTED
 "ap-northeast-1": 
 32: "ami-2a19aa2b"
 64: "ami-2819aa29"
 64HVM: NOT_YET_SUPPORTED
 "sa-east-1": 
 32: "ami-f836e8e5"
 64: "ami-fe36e8e3"
 64HVM: NOT_YET_SUPPORTED
Resources: 
 WebServer: 
 Type: "AWS::EC2::Instance"
 Metadata: 
 "AWS::CloudFormation::Init": 
 config: 
 packages: 
 yum: 
 httpd: 
 php: 
 "php-mysql": 
 "php-gd": 
 "php-xml": 
 "php-mbstring": 
 mysql: 
 "mysql-server": 
 "mysql-devel": 
 "mysql-libs": 
 sources: 
 "/var/www/html": "http://ftp.drupal.org/files/projects/drupal-7.8.tar.gz"
 "/home/ec2-user": "http://ftp.drupal.org/files/projects/drush-7.x-4.5.tar.gz"
 files: 
 "/tmp/setup.mysql": 
 content: 
 "Fn::Join": 
 - 
 ""
 - 
 - 
 "CREATE DATABASE "
 - 
 Ref: DBName
 - 
 ";\n"
 - 
 "CREATE USER '"
 - 
 Ref: DBUsername
 - 
 "'@'localhost' IDENTIFIED BY '"
 - 
 Ref: DBPassword
 - 
 "';\n"
 - 
 "GRANT ALL ON "
 - 
 Ref: DBName
 - 
 ".* TO '"
 - 
 Ref: DBUsername
 - 
 "'@'localhost';\n"
 - 
 "FLUSH PRIVILEGES;\n"
 mode: 000644
 owner: root
 group: root
 services: 
 sysvinit: 
 httpd: 
 enabled: true
 ensureRunning: true
 mysqld: 
 enabled: true
 ensureRunning: true
 sendmail: 
 enabled: false
 ensureRunning: false
 Properties: 
 ImageId: 
 "Fn::FindInMap": 
 - 
 AWSRegionArch2AMI
 - 
 Ref: "AWS::Region"
 - 
 "Fn::FindInMap": 
 - 
 AWSInstanceType2Arch
 - 
 Ref: InstanceType
 - 
 Arch
 InstanceType: 
 Ref: InstanceType
 SecurityGroups: 
 - 
 Ref: WebServerSecurityGroup
 KeyName: 
 Ref: KeyName
 UserData: 
 "Fn::Base64": 
 "Fn::Join": 
 - 
 ""
 - 
 - 
 "#!/bin/bash -v\n"
 - 
 "yum update -y aws-cfn-bootstrap\n"
 - 
 "# Helper function\n"
 - 
 "function error_exit\n"
 - 
 "{\n"
 - 
 " /opt/aws/bin/cfn-signal -e 0 -r \"$1\" '"
 - 
 Ref: WaitHandle
 - 
 "'\n"
 - 
 " exit 1\n"
 - 
 "}\n"
 - 
 "# Install Apache Web Server, MySQL, PHP and Drupal\n"
 - 
 "/opt/aws/bin/cfn-init -s "
 - 
 Ref: "AWS::StackId"
 - 
 " -r WebServer "
 - 
 " --region "
 - 
 Ref: "AWS::Region"
 - 
 " || error_exit 'Failed to run cfn-init'\n"
 - 
 "# Setup MySQL root password and create a user\n"
 - 
 "mysqladmin -u root password '"
 - 
 Ref: DBRootPassword
 - 
 "' || error_exit 'Failed to initialize root password'\n"
 - 
 "mysql -u root --password='"
 - 
 Ref: DBRootPassword
 - 
 "' < /tmp/setup.mysql || error_exit 'Failed to create database user'\n"
 - 
 "# Make changes to Apache Web Server configuration\n"
 - 
 "mv /var/www/html/drupal-7.8/* /var/www/html\n"
 - 
 "mv /var/www/html/drupal-7.8/.* /var/www/html\n"
 - 
 "rmdir /var/www/html/drupal-7.8\n"
 - 
 "sed -i 's/AllowOverride None/AllowOverride All/g' /etc/httpd/conf/httpd.conf\n"
 - 
 "service httpd restart\n"
 - 
 "# Create the site in Drupal\n"
 - 
 "cd /var/www/html\n"
 - 
 "~ec2-user/drush/drush site-install standard --yes"
 - 
 " --site-name='"
 - 
 Ref: SiteName
 - 
 "' --site-mail="
 - 
 Ref: SiteEMail
 - 
 " --account-name="
 - 
 Ref: SiteAdmin
 - 
 " --account-pass="
 - 
 Ref: SitePassword
 - 
 " --db-url=mysql://"
 - 
 Ref: DBUsername
 - 
 ":"
 - 
 Ref: DBPassword
 - 
 "@localhost/"
 - 
 Ref: DBName
 - 
 " --db-prefix=drupal_\n"
 - 
 "chown apache:apache sites/default/files\n"
 - 
 "# All is well so signal success\n"
 - 
 "/opt/aws/bin/cfn-signal -e 0 -r \"Drupal setup complete\" '"
 - 
 Ref: WaitHandle
 - 
 "'\n"
 WaitHandle: 
 Type: "AWS::CloudFormation::WaitConditionHandle"
 WaitCondition: 
 Type: "AWS::CloudFormation::WaitCondition"
 DependsOn: WebServer
 Properties: 
 Handle: 
 Ref: WaitHandle
 Timeout: 300
 WebServerSecurityGroup: 
 Type: "AWS::EC2::SecurityGroup"
 Properties: 
 GroupDescription: "Enable HTTP access via port 80 and SSH access"
 SecurityGroupIngress: 
 - 
 IpProtocol: tcp
 FromPort: 80
 ToPort: 80
 CidrIp: "0.0.0.0/0"
 - 
 IpProtocol: tcp
 FromPort: 22
 ToPort: 22
 CidrIp: 
 Ref: SSHLocation
Outputs: 
 WebsiteURL: 
 Value: 
 "Fn::Join": 
 - 
 ""
 - 
 - 
 "http://"
 - 
 "Fn::GetAtt": 
 - 
 WebServer
 - 
 PublicDnsName
 Description: "Drupal Website"