ElastiCache.json 10.1 KB
Newer Older
John Jarvis committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235
{
  "AWSTemplateFormatVersion" : "2010-09-09",
  
  "Description" : "AWS CloudFormation Sample Template ElastiCache: Sample template showing how to create an Amazon ElastiCache Cache Cluster with Auto Discovery and access it from a very simple PHP application. **WARNING** This template creates an Amazon Ec2 Instance and an Amazon ElastiCache Cluster. You will be billed for the AWS resources used if you create a stack from this template.",
  
  "Parameters" : {

    "KeyName" : {
      "Description" : "Name of an existing Amazon EC2 KeyPair for SSH access to the Web Server",
      "Type" : "String"
    },
          
     "InstanceType" : {
      "Description" : "WebServer EC2 instance type",
      "Type" : "String",
      "Default" : "m1.small",
      "AllowedValues" : [ "t1.micro","m1.small","m1.medium","m1.large","m1.xlarge", "m3.xlarge", "m3.2xlarge", "m2.xlarge","m2.2xlarge","m2.4xlarge","c1.medium","c1.xlarge","cc1.4xlarge","cc2.8xlarge","cg1.4xlarge", "hi1.4xlarge", "hs1.8xlarge"],
      "ConstraintDescription" : "must be a valid EC2 instance type."
    },
 
    "CacheNodeType" : {
      "Default" : "cache.m1.small",
      "Description" : "The compute and memory capacity of the nodes in the Cache Cluster",
      "Type" : "String",
      "AllowedValues" : [ "cache.m1.small", "cache.m1.large", "cache.m1.xlarge", "cache.m2.xlarge", "cache.m2.2xlarge", "cache.m2.4xlarge", "cache.c1.xlarge" ],
      "ConstraintDescription" : "must select a valid Cache Node type."
    },
        
    "NumberOfCacheNodes" : {
      "Default": "1",
      "Description" : "The number of Cache Nodes the Cache Cluster should have",
      "Type": "Number",
      "MinValue": "1",
      "MaxValue": "10",
      "ConstraintDescription" : "must be between 5 and 10."
    },
    "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" : "PV64" },
      "m1.small"    : { "Arch" : "PV64" },
      "m1.medium"   : { "Arch" : "PV64" },
      "m1.large"    : { "Arch" : "PV64" },
      "m1.xlarge"   : { "Arch" : "PV64" },
      "m3.xlarge"   : { "Arch" : "PV64" },
      "m3.2xlarge"  : { "Arch" : "PV64" },
      "m2.xlarge"   : { "Arch" : "PV64" },
      "m2.2xlarge"  : { "Arch" : "PV64" },
      "m2.4xlarge"  : { "Arch" : "PV64" },
      "c1.medium"   : { "Arch" : "PV64" },
      "c1.xlarge"   : { "Arch" : "PV64" },
      "cc1.4xlarge" : { "Arch" : "CLU64" },
      "cc2.8xlarge" : { "Arch" : "CLU64" },
      "cg1.4xlarge" : { "Arch" : "GPU64" },
      "hi1.4xlarge" : { "Arch" : "PV64" },
      "hs1.8xlarge" : { "Arch" : "PV64" }
    },

    "AWSRegionArch2AMI" : {
      "us-east-1"      : { "PV64" : "ami-1624987f", "CLU64" : "ami-08249861",      "GPU64" : "ami-02f54a6b" },
      "us-west-2"      : { "PV64" : "ami-2a31bf1a", "CLU64" : "ami-2431bf14",      "GPU64" : "NOT_YET_SUPPORTED" },
      "us-west-1"      : { "PV64" : "ami-1bf9de5e", "CLU64" : "NOT_YET_SUPPORTED", "GPU64" : "NOT_YET_SUPPORTED" },
      "eu-west-1"      : { "PV64" : "ami-c37474b7", "CLU64" : "ami-d97474ad",      "GPU64" : "ami-1b02026f" },
      "ap-southeast-1" : { "PV64" : "ami-a6a7e7f4", "CLU64" : "NOT_YET_SUPPORTED", "GPU64" : "NOT_YET_SUPPORTED" },
      "ap-southeast-2" : { "PV64" : "ami-bd990e87", "CLU64" : "NOT_YET_SUPPORTED", "GPU64" : "NOT_YET_SUPPORTED" },
      "ap-northeast-1" : { "PV64" : "ami-4e6cd34f", "CLU64" : "NOT_YET_SUPPORTED", "GPU64" : "NOT_YET_SUPPORTED" },
      "sa-east-1"      : { "PV64" : "ami-1e08d103", "CLU64" : "NOT_YET_SUPPORTED", "GPU64" : "NOT_YET_SUPPORTED" }
    }
  },
    
  "Resources" : {   

    "CacheCluster" : {
      "Type": "AWS::ElastiCache::CacheCluster",
      "Properties": {
        "CacheNodeType"           : { "Ref" : "CacheNodeType" },
        "CacheSecurityGroupNames" : [ { "Ref" : "CacheSecurityGroup" } ],
        "Engine"                  : "memcached",
        "NumCacheNodes"           : { "Ref" : "NumberOfCacheNodes" }
      }
    },

    "CacheSecurityGroup": {
      "Type": "AWS::ElastiCache::SecurityGroup",
      "Properties": {
        "Description"  : "Lock cache down to Web Server access only"
      }
    },

    "CacheSecurityGroupIngress": {
      "Type": "AWS::ElastiCache::SecurityGroupIngress",
      "Properties": {
        "CacheSecurityGroupName"  : { "Ref" : "CacheSecurityGroup" },
        "EC2SecurityGroupName"    : { "Ref" : "WebServerSecurityGroup" }
      }        
    },

    "WebServerSecurityGroup" : {
      "Type" : "AWS::EC2::SecurityGroup",
      "Properties" : {
        "GroupDescription" : "Enable HTTP and SSH access",
        "SecurityGroupIngress" : [
          {"IpProtocol" : "tcp", "FromPort" : "22", "ToPort" : "22", "CidrIp" : { "Ref" : "SSHLocation"} },
          {"IpProtocol" : "tcp", "FromPort" : "80", "ToPort" : "80", "CidrIp" : "0.0.0.0/0"}
        ]
      }      
    },  
      
    "WebServerHost": {  
      "Type" : "AWS::EC2::Instance",
      "Metadata" : {
        "AWS::CloudFormation::Init" : {
          "config" : {
            "packages" : {
              "yum" : {
                "httpd"             : [],
                "gcc-c++"           : [],
                "php"               : [],
                "php-pear"          : []
              }
            },

            "files" : {
              "/var/www/html/index.php" : {
                "content" : { "Fn::Join" : ["", [
                  "<?php\n",
                  "echo '<h1>AWS CloudFormation sample application for Amazon ElastiCache</h1>';\n",
                  "\n",
                  "$server_endpoint = '", { "Fn::GetAtt" : [ "CacheCluster", "ConfigurationEndpoint.Address" ]}, "';\n",
                  "$server_port = ", { "Fn::GetAtt" : [ "CacheCluster", "ConfigurationEndpoint.Port" ]}, ";\n",
                  "\n",
                  "/**\n",
                  " * The following will initialize a Memcached client to utilize the Auto Discovery feature.\n",
                  " * \n",
                  " * By configuring the client with the Dynamic client mode with single endpoint, the\n",
                  " * client will periodically use the configuration endpoint to retrieve the current cache\n",
                  " * cluster configuration. This allows scaling the cache cluster up or down in number of nodes\n",
                  " * without requiring any changes to the PHP application. \n",
                  " */\n",
                  "\n",
                  "$dynamic_client = new Memcached();\n",
                  "$dynamic_client->setOption(Memcached::OPT_CLIENT_MODE, Memcached::DYNAMIC_CLIENT_MODE);\n",
                  "$dynamic_client->addServer($server_endpoint, $server_port);\n",
                  "\n",
                  "$tmp_object = new stdClass;\n",
                  "$tmp_object->str_attr = 'test';\n",
                  "$tmp_object->int_attr = 123;\n",
                  "\n",
                  "$dynamic_client->set('key', $tmp_object, 10) or die ('Failed to save data to the cache');\n",
                  "echo '<p>Store data in the cache (data will expire in 10 seconds)</p>';\n",
                  "\n",
                  "$get_result = $dynamic_client->get('key');\n",
                  "echo '<p>Data from the cache:<br/>';\n",
                  "\n",
                  "var_dump($get_result);\n",
                  "\n",
                  "echo '</p>';\n",
                  "?>\n"
                ]]},
                "mode"    : "000644",
                "owner"   : "apache",
                "group"   : "apache"
              }
            },

            "commands" : {
              "00_install_memcached_client" : {
                "command" : "pecl install https://s3.amazonaws.com/elasticache-downloads/ClusterClient/PHP/latest-64bit"
              },
              "01_enable_auto_discovery" : {
                "command" : "echo 'extension=amazon-elasticache-cluster-client.so' > /etc/php.d/memcached.ini"
              }
            },

            "services" : {
              "sysvinit" : {
                "httpd"    : { "enabled" : "true", "ensureRunning" : "true" },
                "sendmail" : { "enabled" : "false", "ensureRunning" : "false" }
              }
            }
          }
        }
      },
      "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 -v\n",
          "yum update -y aws-cfn-bootstrap\n",

          "# Setup the PHP sample application\n",
          "/opt/aws/bin/cfn-init ",
          "         --stack ", { "Ref" : "AWS::StackName" }, 
          "         --resource WebServerHost ",
          "         --region ", { "Ref" : "AWS::Region" }, "\n",

          "# Signal the status of cfn-init\n",
          "/opt/aws/bin/cfn-signal -e $? '", { "Ref" : "WebServerWaitHandle" }, "'\n"
        ]]}}        
      }
    },

    "WebServerWaitHandle" : {
      "Type" : "AWS::CloudFormation::WaitConditionHandle"
    },

    "WebServerWaitCondition" : {
      "Type" : "AWS::CloudFormation::WaitCondition",
      "DependsOn" : "WebServerHost",
      "Properties" : {
        "Handle" : {"Ref" : "WebServerWaitHandle"},
        "Timeout" : "300"
      }
    }
  },
  "Outputs" : {
    "WebsiteURL" : {
      "Value" : { "Fn::Join" : ["", ["http://", { "Fn::GetAtt" : [ "WebServerHost", "PublicDnsName" ]} ]] },
      "Description" : "Application URL"
    }
  }
}