{
"AWSTemplateFormatVersion" : "2010-09-09",
"Description" : "AWS CloudFormation Sample Template for WordPress_Chef: 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 (Availability Zone) Amazon RDS database instance for storage. It demonstrates using the AWS CloudFormation bootstrap scripts to deploy the Chef client and using Chef-client in local mode to deploy WordPress. **WARNING** This template creates an Amazon EC2 instance, an Elastic Load Balancing 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 key pair to enable SSH access to the instances",
"Type": "String",
"MinLength": "1",
"MaxLength": "255",
"AllowedPattern" : "[\\x20-\\x7E]*",
"ConstraintDescription" : "Can contain only ASCII characters."
},
"InstanceType" : {
"Description" : "Web Server EC2 instance type",
"Type" : "String",
"Default" : "m1.small",
"AllowedValues" : [ "t1.micro", "t2.micro", "t2.small", "t2.medium", "m1.small", "m1.medium", "m1.large", "m1.xlarge", "m2.xlarge", "m2.2xlarge", "m2.4xlarge", "m3.medium", "m3.large", "m3.xlarge", "m3.2xlarge", "c1.medium", "c1.xlarge", "c3.large", "c3.xlarge", "c3.2xlarge", "c3.4xlarge", "c3.8xlarge", "g2.2xlarge", "r3.large", "r3.xlarge", "r3.2xlarge", "r3.4xlarge", "r3.8xlarge", "i2.xlarge", "i2.2xlarge", "i2.4xlarge", "i2.8xlarge", "hi1.4xlarge", "hs1.8xlarge", "cr1.8xlarge", "cc2.8xlarge", "cg1.4xlarge"],
"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" : {
"Default" : "db.m1.small",
"Description" : "Database instance class",
"Type" : "String",
"AllowedValues" : [ "db.t1.micro", "db.m1.small", "db.m1.medium", "db.m1.large", "db.m1.xlarge", "db.m2.xlarge", "db.m2.2xlarge", "db.m2.4xlarge", "db.m3.medium", "db.m3.large", "db.m3.xlarge", "db.m3.2xlarge", "db.r3.large", "db.r3.xlarge", "db.r3.2xlarge", "db.r3.4xlarge", "db.r3.8xlarge", "db.m2.xlarge", "db.m2.2xlarge", "db.m2.4xlarge", "db.cr1.8xlarge"],
"ConstraintDescription" : "Must select a valid database instance type."
},
"DBName" : {
"Default": "wordpressdb",
"Description" : "The WordPress database name",
"Type": "String",
"MinLength": "1",
"MaxLength": "64",
"AllowedPattern" : "[a-zA-Z][a-zA-Z0-9]*",
"ConstraintDescription" : "Mmust begin with a letter and contain only alphanumeric characters."
},
"DBUsername" : {
"Default": "admin",
"NoEcho": "true",
"Description" : "The WordPress database admin account user name",
"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": "password",
"NoEcho": "true",
"Description" : "The WordPress database admin account password",
"Type": "String",
"MinLength": "8",
"MaxLength": "41",
"AllowedPattern" : "[a-zA-Z0-9]*",
"ConstraintDescription" : "Must contain only alphanumeric characters."
},
"MultiAZDatabase": {
"Default": "false",
"Description" : "Create a multi-AZ MySQL Amazon RDS database instance",
"Type": "String",
"AllowedValues" : [ "true", "false" ],
"ConstraintDescription" : "Must be either true or false."
},
"WebServerCapacity": {
"Default": "1",
"Description" : "The initial number of web server instances",
"Type": "Number",
"MinValue": "1",
"MaxValue": "5",
"ConstraintDescription" : "Must be between 1 and 5 EC2 instances."
},
"DBAllocatedStorage" : {
"Default": "5",
"Description" : "The size of the database (GB)",
"Type": "Number",
"MinValue": "5",
"MaxValue": "1024",
"ConstraintDescription" : "Must be between 5 and 1024 GB."
}
},
"Mappings" : {
"AWSInstanceType2Arch" : {
"t1.micro" : { "Arch" : "PV64" },
"t2.micro" : { "Arch" : "HVM64" },
"t2.small" : { "Arch" : "HVM64" },
"t2.medium" : { "Arch" : "HVM64" },
"m1.small" : { "Arch" : "PV64" },
"m1.medium" : { "Arch" : "PV64" },
"m1.large" : { "Arch" : "PV64" },
"m1.xlarge" : { "Arch" : "PV64" },
"m2.xlarge" : { "Arch" : "PV64" },
"m2.2xlarge" : { "Arch" : "PV64" },
"m2.4xlarge" : { "Arch" : "PV64" },
"m3.medium" : { "Arch" : "PV64" },
"m3.large" : { "Arch" : "PV64" },
"m3.xlarge" : { "Arch" : "PV64" },
"m3.2xlarge" : { "Arch" : "PV64" },
"c1.medium" : { "Arch" : "PV64" },
"c1.xlarge" : { "Arch" : "PV64" },
"c3.large" : { "Arch" : "PV64" },
"c3.xlarge" : { "Arch" : "PV64" },
"c3.2xlarge" : { "Arch" : "PV64" },
"c3.4xlarge" : { "Arch" : "PV64" },
"c3.8xlarge" : { "Arch" : "PV64" },
"g2.2xlarge" : { "Arch" : "HVMG2" },
"r3.large" : { "Arch" : "HVM64" },
"r3.xlarge" : { "Arch" : "HVM64" },
"r3.2xlarge" : { "Arch" : "HVM64" },
"r3.4xlarge" : { "Arch" : "HVM64" },
"r3.8xlarge" : { "Arch" : "HVM64" },
"i2.xlarge" : { "Arch" : "HVM64" },
"i2.2xlarge" : { "Arch" : "HVM64" },
"i2.4xlarge" : { "Arch" : "HVM64" },
"i2.8xlarge" : { "Arch" : "HVM64" },
"hi1.4xlarge" : { "Arch" : "PV64" },
"hs1.8xlarge" : { "Arch" : "PV64" },
"cr1.8xlarge" : { "Arch" : "HVM64" },
"cc2.8xlarge" : { "Arch" : "HVM64" },
"cg1.4xlarge" : { "Arch" : "HVMGPU" }
},
"AWSRegionArch2AMI" : {
"us-east-1" : { "PV64" : "ami-7c807d14", "HVM64" : "ami-76817c1e", "HVMG2" : "ami-9c13ecf4", "HVMGPU" : "ami-c6867bae" },
"us-west-2" : { "PV64" : "ami-1b3b462b", "HVM64" : "ami-d13845e1", "HVMG2" : "ami-6d8cf15d", "HVMGPU" : "NOT_SUPPORTED" },
"us-west-1" : { "PV64" : "ami-a8d3d4ed", "HVM64" : "ami-f0d3d4b5", "HVMG2" : "ami-84494fc1", "HVMGPU" : "NOT_SUPPORTED" },
"eu-west-1" : { "PV64" : "ami-672ce210", "HVM64" : "ami-892fe1fe", "HVMG2" : "ami-1138f166", "HVMGPU" : "ami-972fe1e0" },
"ap-southeast-1" : { "PV64" : "ami-56b7eb04", "HVM64" : "ami-a6b6eaf4", "HVMG2" : "ami-7a1a4528", "HVMGPU" : "NOT_SUPPORTED" },
"ap-northeast-1" : { "PV64" : "ami-25dd9324", "HVM64" : "ami-29dc9228", "HVMG2" : "ami-4d3b734c", "HVMGPU" : "NOT_SUPPORTED" },
"ap-southeast-2" : { "PV64" : "ami-6bf99c51", "HVM64" : "ami-d9fe9be3", "HVMG2" : "ami-010c683b", "HVMGPU" : "NOT_SUPPORTED" },
"sa-east-1" : { "PV64" : "ami-c7e649da", "HVM64" : "ami-c9e649d4", "HVMG2" : "NOT_SUPPORTED", "HVMGPU" : "NOT_SUPPORTED" },
"us-gov-west-1" : { "PV64" : "ami-ab4a2d88", "HVM64" : "ami-a54a2d86", "HVMG2" : "NOT_SUPPORTED", "HVMGPU" : "NOT_SUPPORTED" },
"cn-north-1" : { "PV64" : "ami-cab82af3", "HVM64" : "ami-ccb82af5", "HVMG2" : "NOT_SUPPORTED", "HVMGPU" : "NOT_SUPPORTED" }
}
},
"Resources" : {
"ElasticLoadBalancer" : {
"Type" : "AWS::ElasticLoadBalancing::LoadBalancer",
"Metadata" : {
"Comment1" : "Configure the Load Balancer with a simple health check and cookie-based stickiness",
"Comment2" : "Use install path for healthcheck to avoid redirects - ELB healthcheck does not handle 302 return codes"
},
"Properties" : {
"AvailabilityZones" : { "Fn::GetAZs" : "" },
"LBCookieStickinessPolicy" : [ {
"PolicyName" : "CookieBasedPolicy",
"CookieExpirationPeriod" : "30"
} ],
"Listeners" : [ {
"LoadBalancerPort" : "80",
"InstancePort" : "80",
"Protocol" : "HTTP",
"PolicyNames" : [ "CookieBasedPolicy" ]
} ],
"HealthCheck" : {
"Target" : "HTTP:80/wp-admin/install.php",
"HealthyThreshold" : "2",
"UnhealthyThreshold" : "5",
"Interval" : "10",
"Timeout" : "5"
}
}
},
"WebServerGroup" : {
"Type" : "AWS::AutoScaling::AutoScalingGroup",
"Properties" : {
"AvailabilityZones" : { "Fn::GetAZs" : "" },
"LaunchConfigurationName" : { "Ref" : "LaunchConfig" },
"MinSize" : "1",
"MaxSize" : "5",
"DesiredCapacity" : { "Ref" : "WebServerCapacity" },
"HealthCheckType" : "ELB",
"LoadBalancerNames" : [ { "Ref" : "ElasticLoadBalancer" } ]
}
},
"LaunchConfig": {
"Type" : "AWS::AutoScaling::LaunchConfiguration",
"Metadata" : {
"AWS::CloudFormation::Init" : {
"configSets" : {
"wordpress_install" : ["install_cfn", "install_chefdk", "install_chef", "install_wordpress", "run_chef"]
},
"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 ",
" --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_chef" : {
"sources" : {
"/var/chef/chef-repo" : "http://github.com/opscode/chef-repo/tarball/master"
},
"files" : {
"/tmp/install.sh" : {
"source" : "https://www.opscode.com/chef/install.sh",
"mode" : "000400",
"owner" : "root",
"group" : "root"
},
"/var/chef/chef-repo/.chef/knife.rb" : {
"content" : { "Fn::Join": [ "", [
"cookbook_path [ '/var/chef/chef-repo/cookbooks' ]\n",
"node_path [ '/var/chef/chef-repo/nodes' ]\n"
]]},
"mode" : "000400",
"owner" : "root",
"group" : "root"
},
"/var/chef/chef-repo/.chef/client.rb" : {
"content" : { "Fn::Join": [ "", [
"cookbook_path [ '/var/chef/chef-repo/cookbooks' ]\n",
"node_path [ '/var/chef/chef-repo/nodes' ]\n"
]]},
"mode" : "000400",
"owner" : "root",
"group" : "root"
}
},
"commands" : {
"01_make_chef_readable" : {
"command" : "chmod +rx /var/chef"
},
"02_install_chef" : {
"command" : "bash /tmp/install.sh",
"cwd" : "/var/chef"
},
"03_create_node_list" : {
"command" : "chef-client -z -c /var/chef/chef-repo/.chef/client.rb",
"cwd" : "/var/chef/chef-repo",
"env" : { "HOME" : "/var/chef" }
}
}
},
"install_chefdk" : {
"packages" : {
"rpm" : {
"chefdk" : "https://opscode-omnibus-packages.s3.amazonaws.com/el/6/x86_64/chefdk-0.2.0-2.el6.x86_64.rpm"
}
}
},
"install_wordpress" : {
"files" : {
"/var/chef/chef-repo/.chef/knife.rb" : {
"content" : { "Fn::Join": [ "", [
"cookbook_path [ '/var/chef/chef-repo/cookbooks/wordpress/berks-cookbooks' ]\n",
"node_path [ '/var/chef/chef-repo/nodes' ]\n"
]]},
"mode" : "000400",
"owner" : "root",
"group" : "root"
},
"/var/chef/chef-repo/.chef/client.rb" : {
"content" : { "Fn::Join": [ "", [
"cookbook_path [ '/var/chef/chef-repo/cookbooks/wordpress/berks-cookbooks' ]\n",
"node_path [ '/var/chef/chef-repo/nodes' ]\n"
]]},
"mode" : "000400",
"owner" : "root",
"group" : "root"
},
"/var/chef/chef-repo/cookbooks/wordpress/attributes/aws_rds_config.rb" : {
"content": { "Fn::Join": [ "", [
"normal['wordpress']['db']['pass'] = '", {"Ref" : "DBPassword"}, "'\n",
"normal['wordpress']['db']['user'] = '", {"Ref" : "DBUsername"}, "'\n",
"normal['wordpress']['db']['host'] = '", {"Fn::GetAtt" : ["DBInstance", "Endpoint.Address"]}, "'\n",
"normal['wordpress']['db']['name'] = '", {"Ref" : "DBName"}, "'\n"
]]},
"mode" : "000400",
"owner" : "root",
"group" : "root"
}
},
"commands" : {
"01_get_cookbook" : {
"command" : "knife cookbook site download wordpress",
"cwd" : "/var/chef/chef-repo",
"env" : { "HOME" : "/var/chef" }
},
"02_unpack_cookbook" : {
"command" : "tar xvfz /var/chef/chef-repo/wordpress*",
"cwd" : "/var/chef/chef-repo/cookbooks"
},
"03_init_berkshelf": {
"command" : "berks init /var/chef/chef-repo/cookbooks/wordpress --skip-vagrant --skip-git",
"cwd" : "/var/chef/chef-repo/cookbooks/wordpress",
"env" : { "HOME" : "/var/chef" }
},
"04_vendorize_berkshelf" : {
"command" : "berks vendor",
"cwd" : "/var/chef/chef-repo/cookbooks/wordpress",
"env" : { "HOME" : "/var/chef" }
},
"05_configure_node_run_list" : {
"command" : "knife node run_list add -z `knife node list -z` recipe[wordpress]",
"cwd" : "/var/chef/chef-repo",
"env" : { "HOME" : "/var/chef" }
}
}
},
"run_chef" : {
"commands" : {
"01_run_chef_client" : {
"command" : "chef-client -z -c /var/chef/chef-repo/.chef/client.rb",
"cwd" : "/var/chef/chef-repo",
"env" : { "HOME" : "/var/chef" }
}
}
}
}
},
"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 aws-cfn-bootstrap\n",
"/opt/aws/bin/cfn-init ",
" --stack ", { "Ref" : "AWS::StackName" },
" --resource LaunchConfig ",
" --configsets wordpress_install ",
" --region ", { "Ref" : "AWS::Region" }, "\n",
"/opt/aws/bin/cfn-signal -e $? '", { "Ref" : "WebServerWaitHandle" }, "'\n"
]]}}
}
},
"WebServerWaitHandle" : {
"Type" : "AWS::CloudFormation::WaitConditionHandle"
},
"WebServerWaitCondition" : {
"Type" : "AWS::CloudFormation::WaitCondition",
"DependsOn" : "WebServerGroup",
"Properties" : {
"Handle" : {"Ref" : "WebServerWaitHandle"},
"Timeout" : "900"
}
},
"DBInstance" : {
"Type": "AWS::RDS::DBInstance",
"Properties": {
"DBName" : { "Ref" : "DBName" },
"Engine" : "MySQL",
"MultiAZ" : { "Ref": "MultiAZDatabase" },
"MasterUsername" : { "Ref" : "DBUsername" },
"DBInstanceClass" : { "Ref" : "DBClass" },
"DBSecurityGroups" : [{ "Ref" : "DBSecurityGroup" }],
"AllocatedStorage" : { "Ref" : "DBAllocatedStorage" },
"MasterUserPassword": { "Ref" : "DBPassword" }
}
},
"DBSecurityGroup": {
"Type": "AWS::RDS::DBSecurityGroup",
"Properties": {
"DBSecurityGroupIngress": [{ "EC2SecurityGroupName": { "Ref": "WebServerSecurityGroup"} }],
"GroupDescription" : "Front-end access"
}
},
"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"}}
]
}
}
},
"Outputs" : {
"WebsiteURL" : {
"Value" : { "Fn::Join" : ["", ["http://", { "Fn::GetAtt" : [ "ElasticLoadBalancer", "DNSName" ]}]]},
"Description" : "WordPress website"
}
}
}