Created
September 2, 2018 20:38
-
-
Save Krucamper/2aa7e855fae8e3cfd265a2bf188e7ea2 to your computer and use it in GitHub Desktop.
AWS CloudFormation Wordpress Auto Scaling Template
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"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