Why Automate?

  1. Reproducible – Automate infrastructure creation
  2. Automatic Dependencies – what to create first , second, next –  are resolved automatically – based on the References (Refs) in the stack definition.

Parts of a template

Description

Parameters (Input Parameters)  e.g. VPC Name, Region

Mappings – For Multi Region Templates – customizing per region – especially since AMI Id is different in different regions (for the same image)

Pseudo Parameters – available by default – Account ID, Region

Resources : {  

Refs

Installing / Configuring Software on Ec2 instance using UserData and Fn::Join Fn:: Base64

}

Outputs  : e.g. wordpress URL after the entire stack is created

E.g. Creating a bastion host – What’s needed (Ec2, EIP and a security group for SSH rule) and Dependencies

EC2 Instance – Security Group id is a needed property for the EC2 instance

image

 

EIP addresses need to know the EC2 instance Id

image

 

Check Resource Quotas in template first

Sample WordPress Creation JSON Stack

{
    “AWSTemplateFormatVersion”: “2010-09-09”,
    “Description”: “Simple WordPress”,
    “Parameters”: {
        “VPC”: {
            “Description”: “The default VPC”,
            “Type”: “AWS::EC2::VPC::Id”
        },
        “Subnets”: {
            “Description”: “At least two public subnets from default VPC.”,
            “Type”: “List<AWS::EC2::Subnet::Id>”
        }
    },
    “Mappings”: {
        “RegionMap”: {
            “eu-west-1”: {“AMI”: “ami-bff32ccc”},
            “ap-southeast-1”: {“AMI”: “ami-c9b572aa”},
            “ap-southeast-2”: {“AMI”: “ami-48d38c2b”},
            “eu-central-1”: {“AMI”: “ami-bc5b48d0”},
            “ap-northeast-2”: {“AMI”: “ami-249b554a”},
            “ap-northeast-1”: {“AMI”: “ami-383c1956”},
            “us-east-1”: {“AMI”: “ami-60b6c60a”},
            “sa-east-1”: {“AMI”: “ami-6817af04”},
            “us-west-1”: {“AMI”: “ami-d5ea86b5”},
            “us-west-2”: {“AMI”: “ami-f0091d91”}
        }
    },
    “Resources”: {
        “EC2Instance”: {
            “Type”: “AWS::EC2::Instance”,
            “Properties”: {
                “ImageId”: {“Fn::FindInMap”: [“RegionMap”, {“Ref”: “AWS::Region”}, “AMI”]},
                “InstanceType”: “t2.nano”,
                “NetworkInterfaces”: [{
                    “AssociatePublicIpAddress”: “true”,
                    “DeviceIndex”: “0”,
                    “GroupSet”: [{“Ref”: “WebserverSecurityGroup”}],
                    “SubnetId”: {“Fn::Select”: [“0”, {“Ref”: “Subnets”}]}
                }],
                “Tags”: [{
                    “Key”: “Name”,
                    “Value”: “simple-wordpress”
                }],
                “UserData”: {“Fn::Base64”: {“Fn::Join”: [“”, [
                    “#!/bin/bash -ex\n”,
                    “yum install -y php php-mysql mysql httpd\n”,
                    “cd /var/www/html\n”,
                    “curl -O
https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar\n”,
                    “php wp-cli.phar core download\n”,
                    “php wp-cli.phar core config –dbname=wordpress –dbuser=wordpress –dbpass=wordpress –dbhost=”, {“Fn::GetAtt”: [“Database”, “Endpoint.Address”]}, “\n”,
                    “php wp-cli.phar core install –url=
http://$(curl http://169.254.169.254/latest/meta-data/public-hostname) –title=Globomantics-Blog –admin_user=admin –admin_password=UBeDzefeX3jihRQUkrGwj2qYWnyBcp –admin_email=adam@globomatics.com –skip-email\n”,
                    “rm wp-cli.phar\n”,
                    “service httpd start\n”
                ]]}}
            }
        },
        “DBSubnetGroup”: {
            “Type”: “AWS::RDS::DBSubnetGroup”,
            “Properties”: {
                “DBSubnetGroupDescription”: “DB subnet group”,
                “SubnetIds”: {“Ref”: “Subnets”}
            }
        },
        “Database”: {
            “Type”: “AWS::RDS::DBInstance”,
            “Properties”: {
                “AllocatedStorage”: “5”,
                “DBInstanceClass”: “db.t2.micro”,
                “DBInstanceIdentifier”: “simple-wordpress”,
                “DBName”: “wordpress”,
                “Engine”: “MySQL”,
                “MasterUsername”: “wordpress”,
                “MasterUserPassword”: “wordpress”,
                “VPCSecurityGroups”: [{“Fn::GetAtt”: [“DatabaseSecurityGroup”, “GroupId”]}],
                “DBSubnetGroupName”: {“Ref”: “DBSubnetGroup”},
                “StorageType”: “gp2”
            }
        },
        “WebserverSecurityGroup”: {
            “Type”: “AWS::EC2::SecurityGroup”,
            “Properties”: {
                “GroupDescription”: “simple-wordpress-webserver”,
                “VpcId”: {“Ref”: “VPC”},
                “SecurityGroupIngress”: [{
                    “CidrIp”: “0.0.0.0/0”,
                    “FromPort”: 80,
                    “IpProtocol”: “tcp”,
                    “ToPort”: 80
                }]
            }
        },
        “DatabaseSecurityGroup”: {
            “Type”: “AWS::EC2::SecurityGroup”,
            “Properties”: {
                “GroupDescription”: “simple-wordpress-database”,
                “VpcId”: {“Ref”: “VPC”},
                “SecurityGroupIngress”: [{
                    “IpProtocol”: “tcp”,
                    “FromPort”: “3306”,
                    “ToPort”: “3306”,
                    “SourceSecurityGroupId”: {“Ref”: “WebserverSecurityGroup”}
                }]
            }
        }
    },
    “Outputs”: {
        “WordPressURL”: {
            “Description”: “The URL of the simple WordPress environment.”,
            “Value”: {“Fn::Join”: [“”, [“
http://”, {“Fn::GetAtt”: [“EC2Instance”, “PublicIp”]}]]}
        }
    }
}

AWS CloudFormation Best Practices

Best practices are recommendations that can help you use AWS CloudFormation more effectively and securely throughout its entire workflow. Learn how to plan and organize your stacks, create templates that describe your resources and the software applications that run on them, and manage your stacks and their resources. The following best practices are based on real-world experience from current AWS CloudFormation customers.

Planning and organizing

Creating templates

Managing stacks

Anuj holds professional certifications in Google Cloud, AWS as well as certifications in Docker and App Performance Tools such as New Relic. He specializes in Cloud Security, Data Encryption and Container Technologies.

Initial Consultation

Anuj Varma – who has written posts on Anuj Varma, Hands-On Technology Architect, Clean Air Activist.