cloudformation basics
Why Automate?
- Reproducible – Automate infrastructure creation
- 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
EIP addresses need to know the EC2 instance Id
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
Leave a Reply