Skip to content

Instantly share code, notes, and snippets.

@Krucamper
Created September 2, 2018 20:38
Show Gist options
  • Save Krucamper/2aa7e855fae8e3cfd265a2bf188e7ea2 to your computer and use it in GitHub Desktop.
Save Krucamper/2aa7e855fae8e3cfd265a2bf188e7ea2 to your computer and use it in GitHub Desktop.
AWS CloudFormation Wordpress Auto Scaling Template
{
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "AWS CloudFormation Sample Template WordPress_Multi_AZ: WordPress is web software you can use to create a beautiful website or blog. This template installs a highly-available, scalable WordPress deployment using a multi-az Amazon RDS database instance for storage. It demonstrates using the AWS CloudFormation bootstrap scripts to deploy WordPress. **WARNING** This template creates an Amazon EC2 instance, an Elastic Load Balancer and an Amazon RDS database 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": "AWS::EC2::KeyPair::KeyName",
"ConstraintDescription": "must be the name of an existing EC2 KeyPair."
},
"InstanceType": {
"Description": "WebServer EC2 instance type",
"Type": "String",
"Default": "t2.micro",
"AllowedValues": [
"t2.micro"
],
"ConstraintDescription": "must be a valid EC2 instance type."
},
"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."
},
"DBClass": {
"Description": "Database instance class",
"Type": "String",
"Default": "db.t2.micro",
"AllowedValues": [
"db.t2.micro"
],
"ConstraintDescription": "must select a valid database instance type."
},
"DBName": {
"Default": "wordpressdb",
"Description": "The WordPress database name",
"Type": "String",
"MinLength": "1",
"MaxLength": "64",
"ConstraintDescription": "must begin with a letter and contain only alphanumeric characters.",
"AllowedPattern": "[a-zA-Z][a-zA-Z0-9]*"
},
"DBUser": {
"NoEcho": "true",
"Description": "The WordPress database admin account username",
"Type": "String",
"MinLength": "4",
"MaxLength": "20",
"AllowedPattern": "[a-zA-Z0-9]*",
"ConstraintDescription": "must contain only alphanumeric characters."
},
"DBPassword": {
"NoEcho": "true",
"Description": "The WordPress database admin account password",
"Type": "String",
"MinLength": "4",
"MaxLength": "20",
"AllowedPattern": "[a-zA-Z0-9]*",
"ConstraintDescription": "must contain only alphanumeric characters."
},
"MultiAZDatabase": {
"Default": "true",
"Description": "Create a Multi-AZ MySQL Amazon RDS database instance",
"Type": "String",
"AllowedValues": [
"true",
"false"
],
"ConstraintDescription": "must be either true or false."
},
"WebServerCapacity": {
"Default": "2",
"Description": "The initial number of WebServer instances",
"Type": "Number",
"MinValue": "2",
"MaxValue": "4",
"ConstraintDescription": "must be between 2 and 4 EC2 instances."
},
"DBAllocatedStorage": {
"Default": "6",
"Description": "The size of the database (Gb)",
"Type": "Number",
"MinValue": "6",
"MaxValue": "1024",
"ConstraintDescription": "must be between 6 and 1024Gb."
},
"OperatorEMail": {
"Description": "EMail address to notify if there are any scaling operations",
"Type": "String",
"Default": "[email protected]",
"AllowedPattern": "([a-zA-Z0-9_\\-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)",
"ConstraintDescription": "must be a valid email address."
}
},
"Mappings": {
"AWSInstanceType2Arch": {
"t2.micro": {
"Arch": "HVM64"
}
},
"AWSInstanceType2NATArch": {
"t2.micro": {
"Arch": "NATHVM64"
}
},
"AWSRegionArch2AMI": {
"ap-southeast-1": {
"PV64": "ami-df9e4cbc",
"HVM64": "ami-a59b49c6",
"HVMG2": "ami-1c0ba17f"
}
}
},
"Conditions": {
"Is-EC2-VPC": {
"Fn::Or": [
{
"Fn::Equals": [
{
"Ref": "AWS::Region"
},
"eu-central-1"
]
},
{
"Fn::Equals": [
{
"Ref": "AWS::Region"
},
"cn-north-1"
]
},
{
"Fn::Equals": [
{
"Ref": "AWS::Region"
},
"ap-northeast-2"
]
}
]
},
"Is-EC2-Classic": {
"Fn::Not": [
{
"Condition": "Is-EC2-VPC"
}
]
}
},
"Resources": {
"ElasticLoadBalancer": {
"Type": "AWS::ElasticLoadBalancing::LoadBalancer",
"Properties": {
"AvailabilityZones": {
"Fn::GetAZs": ""
},
"CrossZone": "true",
"LBCookieStickinessPolicy": [
{
"PolicyName": "CookieBasedPolicy",
"CookieExpirationPeriod": "30"
}
],
"Listeners": [
{
"LoadBalancerPort": "80",
"InstancePort": "80",
"Protocol": "HTTP",
"PolicyNames": [
"CookieBasedPolicy"
]
}
],
"HealthCheck": {
"Target": "HTTP:80/wordpress/wp-admin/install.php",
"HealthyThreshold": "2",
"UnhealthyThreshold": "5",
"Interval": "10",
"Timeout": "5"
}
}
},
"WebServerSecurityGroup": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"GroupDescription": "Enable HTTP access via port 80 locked down to the load balancer + SSH access",
"SecurityGroupIngress": [
{
"IpProtocol": "tcp",
"FromPort": "80",
"ToPort": "80",
"SourceSecurityGroupOwnerId": {
"Fn::GetAtt": [
"ElasticLoadBalancer",
"SourceSecurityGroup.OwnerAlias"
]
},
"SourceSecurityGroupName": {
"Fn::GetAtt": [
"ElasticLoadBalancer",
"SourceSecurityGroup.GroupName"
]
}
},
{
"IpProtocol": "tcp",
"FromPort": "22",
"ToPort": "22",
"CidrIp": {
"Ref": "SSHLocation"
}
}
]
}
},
"WebServerGroup": {
"Type": "AWS::AutoScaling::AutoScalingGroup",
"Properties": {
"AvailabilityZones": {
"Fn::GetAZs": ""
},
"LaunchConfigurationName": {
"Ref": "LaunchConfig"
},
"MinSize": "1",
"MaxSize": "4",
"DesiredCapacity": {
"Ref": "WebServerCapacity"
},
"LoadBalancerNames": [
{
"Ref": "ElasticLoadBalancer"
}
],
"NotificationConfigurations": [
{
"TopicARN": {
"Ref": "ScalingSNSTopic"
},
"NotificationTypes": [
"autoscaling:EC2_INSTANCE_LAUNCH",
"autoscaling:EC2_INSTANCE_LAUNCH_ERROR",
"autoscaling:EC2_INSTANCE_TERMINATE",
"autoscaling:EC2_INSTANCE_TERMINATE_ERROR"
]
}
]
},
"CreationPolicy": {
"ResourceSignal": {
"Timeout": "PT15M"
}
},
"UpdatePolicy": {
"AutoScalingRollingUpdate": {
"MinInstancesInService": "1",
"MaxBatchSize": "1",
"PauseTime": "PT15M",
"WaitOnResourceSignals": "true"
}
}
},
"LaunchConfig": {
"Type": "AWS::AutoScaling::LaunchConfiguration",
"Metadata": {
"AWS::CloudFormation::Init": {
"configSets": {
"wordpress_install": [
"install_cfn",
"install_wordpress"
]
},
"install_cfn": {
"files": {
"/etc/cfn/cfn-hup.conf": {
"content": {
"Fn::Join": [
"",
[
"[main]\n",
"stack=",
{
"Ref": "AWS::StackId"
},
"\n",
"region=",
{
"Ref": "AWS::Region"
},
"\n"
]
]
},
"mode": "000400",
"owner": "root",
"group": "root"
},
"/etc/cfn/hooks.d/cfn-auto-reloader.conf": {
"content": {
"Fn::Join": [
"",
[
"[cfn-auto-reloader-hook]\n",
"triggers=post.update\n",
"path=Resources.LaunchConfig.Metadata.AWS::CloudFormation::Init\n",
"action=/opt/aws/bin/cfn-init -v ",
" --stack ",
{
"Ref": "AWS::StackName"
},
" --resource LaunchConfig ",
" --configsets wordpress_install ",
" --region ",
{
"Ref": "AWS::Region"
},
"\n"
]
]
},
"mode": "000400",
"owner": "root",
"group": "root"
}
},
"services": {
"sysvinit": {
"cfn-hup": {
"enabled": "true",
"ensureRunning": "true",
"files": [
"/etc/cfn/cfn-hup.conf",
"/etc/cfn/hooks.d/cfn-auto-reloader.conf"
]
}
}
}
},
"install_wordpress": {
"packages": {
"yum": {
"php": [],
"php-mysql": [],
"mysql": [],
"httpd": []
}
},
"sources": {
"/var/www/html": "http://wordpress.org/latest.tar.gz"
},
"files": {
"/tmp/create-wp-config": {
"content": {
"Fn::Join": [
"",
[
"#!/bin/bash\n",
"cp /var/www/html/wordpress/wp-config-sample.php /var/www/html/wordpress/wp-config.php\n",
"sed -i \"s/'database_name_here'/'",
{
"Ref": "DBName"
},
"'/g\" wp-config.php\n",
"sed -i \"s/'username_here'/'",
{
"Ref": "DBUser"
},
"'/g\" wp-config.php\n",
"sed -i \"s/'password_here'/'",
{
"Ref": "DBPassword"
},
"'/g\" wp-config.php\n",
"sed -i \"s/'localhost'/'",
{
"Fn::GetAtt": [
"DBInstance",
"Endpoint.Address"
]
},
"'/g\" wp-config.php\n"
]
]
},
"mode": "000500",
"owner": "root",
"group": "root"
}
},
"commands": {
"01_configure_wordpress": {
"command": "/tmp/create-wp-config",
"cwd": "/var/www/html/wordpress"
}
},
"services": {
"sysvinit": {
"httpd": {
"enabled": "true",
"ensureRunning": "true"
}
}
}
}
}
},
"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 -xe\n",
"yum update -y aws-cfn-bootstrap\n",
"/opt/aws/bin/cfn-init -v ",
" --stack ",
{
"Ref": "AWS::StackName"
},
" --resource LaunchConfig ",
" --configsets wordpress_install ",
" --region ",
{
"Ref": "AWS::Region"
},
"\n",
"/opt/aws/bin/cfn-signal -e $? ",
" --stack ",
{
"Ref": "AWS::StackName"
},
" --resource WebServerGroup ",
" --region ",
{
"Ref": "AWS::Region"
},
"\n"
]
]
}
}
}
},
"DBEC2SecurityGroup": {
"Type": "AWS::EC2::SecurityGroup",
"Condition": "Is-EC2-VPC",
"Properties": {
"GroupDescription": "Open database for access",
"SecurityGroupIngress": [
{
"IpProtocol": "tcp",
"FromPort": "3306",
"ToPort": "3306",
"SourceSecurityGroupName": {
"Ref": "WebServerSecurityGroup"
}
}
]
}
},
"DBInstance": {
"Type": "AWS::RDS::DBInstance",
"Properties": {
"DBName": {
"Ref": "DBName"
},
"Engine": "MySQL",
"MultiAZ": {
"Ref": "MultiAZDatabase"
},
"MasterUsername": {
"Ref": "DBUser"
},
"MasterUserPassword": {
"Ref": "DBPassword"
},
"DBInstanceClass": {
"Ref": "DBClass"
},
"AllocatedStorage": {
"Ref": "DBAllocatedStorage"
},
"VPCSecurityGroups": {
"Fn::If": [
"Is-EC2-VPC",
[
{
"Fn::GetAtt": [
"DBEC2SecurityGroup",
"GroupId"
]
}
],
{
"Ref": "AWS::NoValue"
}
]
},
"DBSecurityGroups": {
"Fn::If": [
"Is-EC2-Classic",
[
{
"Ref": "DBSecurityGroup"
}
],
{
"Ref": "AWS::NoValue"
}
]
}
}
},
"DBSecurityGroup": {
"Type": "AWS::RDS::DBSecurityGroup",
"Condition": "Is-EC2-Classic",
"Properties": {
"DBSecurityGroupIngress": {
"EC2SecurityGroupName": {
"Ref": "WebServerSecurityGroup"
}
},
"GroupDescription": "database access"
}
},
"WebServerScaleUpPolicy": {
"Type": "AWS::AutoScaling::ScalingPolicy",
"Properties": {
"AdjustmentType": "ChangeInCapacity",
"AutoScalingGroupName": {
"Ref": "WebServerGroup"
},
"Cooldown": "60",
"ScalingAdjustment": "1"
}
},
"WebServerScaleDownPolicy": {
"Type": "AWS::AutoScaling::ScalingPolicy",
"Properties": {
"AdjustmentType": "ChangeInCapacity",
"AutoScalingGroupName": {
"Ref": "WebServerGroup"
},
"Cooldown": "60",
"ScalingAdjustment": "-1"
}
},
"CPUAlarmHigh": {
"Type": "AWS::CloudWatch::Alarm",
"Properties": {
"AlarmDescription": "Scale-up if CPU > 70% for 10 minutes",
"MetricName": "CPUUtilization",
"Namespace": "AWS/EC2",
"Statistic": "Average",
"Period": "60",
"EvaluationPeriods": "5",
"Threshold": "70",
"AlarmActions": [
{
"Ref": "WebServerScaleUpPolicy"
}
],
"Dimensions": [
{
"Name": "AutoScalingGroupName",
"Value": {
"Ref": "WebServerGroup"
}
}
],
"ComparisonOperator": "GreaterThanThreshold"
}
},
"CPUAlarmLow": {
"Type": "AWS::CloudWatch::Alarm",
"Properties": {
"AlarmDescription": "Scale-down if CPU < 30% for 10 minutes",
"MetricName": "CPUUtilization",
"Namespace": "AWS/EC2",
"Statistic": "Average",
"Period": "60",
"EvaluationPeriods": "5",
"Threshold": "30",
"AlarmActions": [
{
"Ref": "WebServerScaleDownPolicy"
}
],
"Dimensions": [
{
"Name": "AutoScalingGroupName",
"Value": {
"Ref": "WebServerGroup"
}
}
],
"ComparisonOperator": "LessThanThreshold"
}
},
"ScalingSNSTopic": {
"Type": "AWS::SNS::Topic",
"Properties": {
"Subscription": [
{
"Endpoint": {
"Ref": "OperatorEMail"
},
"Protocol": "email"
}
]
}
}
},
"Outputs": {
"WebsiteURL": {
"Value": {
"Fn::Join": [
"",
[
"http://",
{
"Fn::GetAtt": [
"ElasticLoadBalancer",
"DNSName"
]
},
"/wordpress"
]
]
},
"Description": "WordPress Website"
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment