{
  "AWSTemplateFormatVersion" : "2010-09-09",

  "Description" : "Install a WordPress deployment using an Amazon RDS database instance for storage. This template demonstrates using the AWS CloudFormation bootstrap scripts to install Chef Solo and then Chef Solo is used to install a simple WordPress recipe. **WARNING** This template creates an Amazon EC2 instance and an RDS database. 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": "String",
      "MinLength": "1",
      "MaxLength": "255",
      "AllowedPattern" : "[\\x20-\\x7E]*",
      "ConstraintDescription" : "can contain only ASCII characters."
    },

    "FrontendType" : {
      "Description" : "Frontend EC2 instance type",
      "Type" : "String",
      "Default" : "m1.small",
      "AllowedValues" : [ "t1.micro","m1.small","m1.medium","m1.large","m1.xlarge","m2.xlarge","m2.2xlarge","m2.4xlarge","m3.xlarge","m3.2xlarge","c1.medium","c1.xlarge","cc1.4xlarge","cc2.8xlarge","cg1.4xlarge"],
      "ConstraintDescription" : "must be a valid EC2 instance type."
    },

    "GroupSize": {
      "Default": "1",
      "Description" : "The default number of EC2 instances for the frontend cluster",
      "Type": "Number"
    },

    "MaxSize": {
      "Default": "1",
      "Description" : "The maximum number of EC2 instances for the frontend",
      "Type": "Number"
    },

    "DBClass" : {
      "Default" : "db.m1.small",
      "Description" : "Database instance class",
      "Type" : "String",
      "AllowedValues" : [ "db.m1.small", "db.m1.large", "db.m1.xlarge", "db.m2.xlarge", "db.m2.2xlarge", "db.m2.4xlarge" ],
      "ConstraintDescription" : "must select a valid database instance type."
    },

    "DBName": {
      "Default": "wordpress",
      "Description" : "The WordPress database name",
      "Type": "String",
      "MinLength": "1",
      "MaxLength": "64",
      "AllowedPattern" : "[a-zA-Z][a-zA-Z0-9]*",
      "ConstraintDescription" : "must begin with a letter and contain only alphanumeric characters."
    },

    "DBUser": {
      "Default": "admin",
      "NoEcho": "true",
      "Description" : "The WordPress database admin account username",
      "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" : "If true, creates a Multi-AZ deployment of the RDS database",
      "Type" : "String",
      "AllowedValues" : [ "true", "false" ],
      "ConstraintDescription" : "must be either true or false."
    },
    "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."
    }
  },

  "Mappings" : {
    "AWSInstanceType2Arch" : {
      "t1.micro"    : { "Arch" : "64" },
      "m1.small"    : { "Arch" : "64" },
      "m1.medium"   : { "Arch" : "64" },
      "m1.large"    : { "Arch" : "64" },
      "m1.xlarge"   : { "Arch" : "64" },
      "m2.xlarge"   : { "Arch" : "64" },
      "m2.2xlarge"  : { "Arch" : "64" },
      "m2.4xlarge"  : { "Arch" : "64" },
      "m3.xlarge"   : { "Arch" : "64" },
      "m3.2xlarge"  : { "Arch" : "64" },
      "c1.medium"   : { "Arch" : "64" },
      "c1.xlarge"   : { "Arch" : "64" },
      "cc1.4xlarge" : { "Arch" : "64HVM" },
      "cc2.8xlarge" : { "Arch" : "64HVM" },
      "cg1.4xlarge" : { "Arch" : "64HVM" }
    },

    "AWSRegionArch2AMI" : {
      "us-east-1"      : { "32" : "ami-31814f58", "64" : "ami-1b814f72", "64HVM" : "ami-0da96764" },
      "us-west-2"      : { "32" : "ami-38fe7308", "64" : "ami-30fe7300", "64HVM" : "NOT_YET_SUPPORTED" },
      "us-west-1"      : { "32" : "ami-11d68a54", "64" : "ami-1bd68a5e", "64HVM" : "NOT_YET_SUPPORTED" },
      "eu-west-1"      : { "32" : "ami-973b06e3", "64" : "ami-953b06e1", "64HVM" : "NOT_YET_SUPPORTED" },
      "ap-southeast-1" : { "32" : "ami-b4b0cae6", "64" : "ami-beb0caec", "64HVM" : "NOT_YET_SUPPORTED" },
      "ap-southeast-2" : { "32" : "ami-b3990e89", "64" : "ami-bd990e87", "64HVM" : "NOT_YET_SUPPORTED" },
      "ap-northeast-1" : { "32" : "ami-0644f007", "64" : "ami-0a44f00b", "64HVM" : "NOT_YET_SUPPORTED" },
      "sa-east-1"      : { "32" : "ami-3e3be423", "64" : "ami-3c3be421", "64HVM" : "NOT_YET_SUPPORTED" }
    }
  },

  "Resources" : {

    "ElasticLoadBalancer": {
      "Type": "AWS::ElasticLoadBalancing::LoadBalancer",
      "Properties": {
        "Listeners": [
          { "InstancePort": 80,
            "Protocol": "HTTP",
            "LoadBalancerPort": "80"
          }
        ],
        "HealthCheck": {
          "HealthyThreshold": "2",
          "Timeout": "5",
          "Interval": "10",
          "UnhealthyThreshold": "5",
          "Target": "HTTP:80/wp-admin/install.php"
        },
        "AvailabilityZones": {
          "Fn::GetAZs": { "Ref": "AWS::Region"}
        }
      }
    },

    "WebServerGroup": {
      "Type": "AWS::AutoScaling::AutoScalingGroup",
      "Properties": {
        "LoadBalancerNames": [{ "Ref": "ElasticLoadBalancer" }],
        "LaunchConfigurationName": {"Ref": "LaunchConfig"},
        "AvailabilityZones": {
          "Fn::GetAZs": { "Ref": "AWS::Region" }
        },
        "MinSize": "0",
        "MaxSize": { "Ref" : "MaxSize" },
        "DesiredCapacity" : { "Ref" : "GroupSize" }
      }
    },

    "LaunchConfig": {
      "Type": "AWS::AutoScaling::LaunchConfiguration",
      "Metadata" : {
        "AWS::CloudFormation::Init" : {
          "configSets" : {
          		"order"	: ["gems","chefversion"]
          	},
            "gems" : {
          		"packages" : {
          			  "rubygems" : {
              	 			"net-ssh"	  		: ["2.2.2"],
                 			"net-ssh-gateway"  : ["1.1.0"]

                 	}
                }
          	},
          	 "chefversion" : {
          		"packages" : {
          	  		"rubygems" : {

                 			"chef" 			: ["10.18.2"]
              },
              		"yum" : {
                 		"gcc-c++"    : [],
                 		"ruby-devel" : [],
                 		"make"       : [],
                 		"autoconf"   : [],
                 		"automake"   : [],
                 		"rubygems"   : []
             	 	}
            	},
            	"files" : {
             	 	"/etc/chef/solo.rb" : {
                	"content" : { "Fn::Join" : ["\n", [
                	  "log_level :info",
                  	"log_location STDOUT",
                  	"file_cache_path \"/var/chef-solo\"",
                  	"cookbook_path \"/var/chef-solo/cookbooks\"",
                  	"json_attribs \"/etc/chef/node.json\"",
                  	"recipe_url \"https://s3.amazonaws.com/cloudformation-examples/wordpress.tar.gz\""
                	]] },
                	"mode" : "000644",
                	"owner" : "root",
                	"group" : "wheel"
             	 },
              	"/etc/chef/node.json" : {
               	 "content" : {
                 	 "wordpress" : {
                 	   "db" : {
                   	   "database" : {"Ref" : "DBName"},
                   	   "user"     : {"Ref" : "DBUser"},
                    	  "host"     : {"Fn::GetAtt" : ["DBInstance", "Endpoint.Address"]},
                    	  "password" : {"Ref" : "DBPassword" }
                    	}
                  	},
                  	"run_list": [ "recipe[wordpress]" ]
                	},
                "mode" : "000644",
                "owner" : "root",
                "group" : "wheel"
              }
            }
          }
        }
      },
      "Properties": {
        "InstanceType" : { "Ref" : "FrontendType" },
        "SecurityGroups" : [ { "Ref" : "SSHGroup" }, {"Ref" : "FrontendGroup"} ],
        "ImageId" : { "Fn::FindInMap" : [ "AWSRegionArch2AMI", { "Ref" : "AWS::Region" },
                    { "Fn::FindInMap" : [ "AWSInstanceType2Arch", { "Ref" : "FrontendType" }, "Arch" ] } ] },
        "KeyName" : { "Ref" : "KeyName" },
        "UserData" : { "Fn::Base64" : { "Fn::Join" : ["", [
          "#!/bin/bash\n",
          "yum update -y aws-cfn-bootstrap\n",

          "/opt/aws/bin/cfn-init -s ", { "Ref" : "AWS::StackId" }, " -r LaunchConfig ",
          "         --region ", { "Ref" : "AWS::Region" }, " && ",
          "chef-solo\n",
          "/opt/aws/bin/cfn-signal -e $? '", { "Ref" : "WaitHandle" }, "'\n"
        ]]}}
      }
    },

    "WaitHandle" : {
      "Type" : "AWS::CloudFormation::WaitConditionHandle"
    },

    "WaitCondition" : {
      "Type" : "AWS::CloudFormation::WaitCondition",
      "DependsOn" : "WebServerGroup",
      "Properties" : {
        "Handle" : {"Ref" : "WaitHandle"},
        "Timeout" : "600"
      }
    },

    "DBInstance" : {
      "Type": "AWS::RDS::DBInstance",
      "Properties": {
        "Engine"            : "MySQL",
        "DBName"            : { "Ref": "DBName" },
        "Port"              : "3306",
        "MultiAZ"           : { "Ref" : "MultiAZDatabase" },
        "MasterUsername"    : { "Ref": "DBUser" },
        "DBInstanceClass"   : { "Ref" : "DBClass" },
        "DBSecurityGroups"  : [{ "Ref": "DBSecurityGroup" }],
        "AllocatedStorage"  : "5",
        "MasterUserPassword": { "Ref": "DBPassword" }
      }
    },

    "DBSecurityGroup": {
      "Type": "AWS::RDS::DBSecurityGroup",
      "Properties": {
        "DBSecurityGroupIngress": { "EC2SecurityGroupName": { "Ref": "FrontendGroup"} },
        "GroupDescription": "Frontend Access"
      }
    },

    "SSHGroup" : {
      "Type" : "AWS::EC2::SecurityGroup",
      "Properties" : {
        "GroupDescription" : "Enable SSH access",
        "SecurityGroupIngress" : [ {"IpProtocol" : "tcp", "FromPort" : "22", "ToPort" : "22", "CidrIp" : { "Ref" : "SSHLocation"}}]
      }
    },

    "FrontendGroup" : {
      "Type" : "AWS::EC2::SecurityGroup",
      "Properties" : {
        "GroupDescription" : "Enable HTTP access via port 80",
        "SecurityGroupIngress" : [ { "IpProtocol" : "tcp", "FromPort" : "80", "ToPort" : "80",
          "SourceSecurityGroupOwnerId" : {"Fn::GetAtt" : ["ElasticLoadBalancer", "SourceSecurityGroup.OwnerAlias"]},
          "SourceSecurityGroupName"    : {"Fn::GetAtt" : ["ElasticLoadBalancer", "SourceSecurityGroup.GroupName"]}
        } ]
      }
    }
  },

  "Outputs" : {
    "WebsiteURL" : {
      "Value" : { "Fn::Join" : ["", ["http://", { "Fn::GetAtt" : [ "ElasticLoadBalancer", "DNSName" ]}, "/"]]},
      "Description" : "URL to install WordPress"
    },
    "InstallURL" : {
      "Value" : { "Fn::Join" : ["", ["http://", { "Fn::GetAtt" : [ "ElasticLoadBalancer", "DNSName" ]}, "/wp-admin/install.php"]]},
      "Description" : "URL to install WordPress"
    }
  }
}
