Skip to content

Instantly share code, notes, and snippets.

@totutote
Created February 17, 2012 07:21
Show Gist options
  • Save totutote/1851520 to your computer and use it in GitHub Desktop.
Save totutote/1851520 to your computer and use it in GitHub Desktop.
サーバを起動するCloudFormationテンプレート
{
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "Bring up an Opscode Chef Client using the BootStrap Chef RubyGems installation. A WaitCondition is used to hold up the stack creation until the application is deployed. **WARNING** This template creates one or more Amazon EC2 instances. You will be billed for the AWS resources used if you create a stack from this template.",
"Parameters": {
"KeyName": {
"Type": "String",
"Description" : "Name of an existing EC2 KeyPair to enable SSH access to the web server"
},
"ChefServerURL" : {
"Description" : "URL of Chef Server",
"Type": "String"
},
"OperatorEmail": {
"Description": "Email address to notify if there are any operational issues",
"Type": "String"
},
"ChefServerPrivateKeyBucket" : {
"Description" : "S3 bucket containing validation private key for Chef Server",
"Type": "String"
},
"PackageDownloadURI" : {
"Description" : "S3 bucket containing static packages",
"Type": "String"
},
"ChefServerSecurityGroup" : {
"Description" : "Security group to get access to Opscode Chef Server",
"Type": "String"
},
"WebFpInstanceType": {
"Default": "c1.xlarge",
"Description" : "Type of EC2 instance for feature phone web server",
"Type": "String",
"AllowedValues" : [ "t1.micro", "m1.small", "m1.large", "m1.xlarge", "m2.xlarge", "m2.2xlarge", "m2.4xlarge", "c1.medium", "c1.xlarge", "cc1.4xlarge" ],
"ConstraintDescription" : "must contain only alphanumeric characters."
},
"WebSpInstanceType": {
"Default": "c1.xlarge",
"Description" : "Type of EC2 instance for smartphone web server",
"Type": "String",
"AllowedValues" : [ "t1.micro", "m1.small", "m1.large", "m1.xlarge", "m2.xlarge", "m2.2xlarge", "m2.4xlarge", "c1.medium", "c1.xlarge", "cc1.4xlarge" ],
"ConstraintDescription" : "must contain only alphanumeric characters."
},
"ElastiCacheInstanceType": {
"Default": "m1.large",
"Description" : "Type of EC2 instance for ElastiCache server",
"Type": "String",
"AllowedValues" : [ "t1.micro", "m1.small", "m1.large", "m1.xlarge", "m2.xlarge", "m2.2xlarge", "m2.4xlarge", "c1.medium", "c1.xlarge", "cc1.4xlarge" ],
"ConstraintDescription" : "must contain only alphanumeric characters."
},
"MemcachedInstanceType": {
"Default": "m1.large",
"Description" : "Type of EC2 instance for Memcached server",
"Type": "String",
"AllowedValues" : [ "t1.micro", "m1.small", "m1.large", "m1.xlarge", "m2.xlarge", "m2.2xlarge", "m2.4xlarge", "c1.medium", "c1.xlarge", "cc1.4xlarge" ],
"ConstraintDescription" : "must contain only alphanumeric characters."
},
"TokyoTyrantInstanceType": {
"Default": "m2.xlarge",
"Description" : "Type of EC2 instance for TokyoTyrant server",
"Type": "String",
"AllowedValues" : [ "t1.micro", "m1.small", "m1.large", "m1.xlarge", "m2.xlarge", "m2.2xlarge", "m2.4xlarge", "c1.medium", "c1.xlarge", "cc1.4xlarge" ],
"ConstraintDescription" : "must contain only alphanumeric characters."
},
"MysqlInstanceType": {
"Default": "m2.4xlarge",
"Description" : "Type of EC2 instance for web server",
"Type": "String",
"AllowedValues" : [ "t1.micro", "m1.small", "m1.large", "m1.xlarge", "m2.xlarge", "m2.2xlarge", "m2.4xlarge", "c1.medium", "c1.xlarge", "cc1.4xlarge" ],
"ConstraintDescription" : "must contain only alphanumeric characters."
},
"LogInstanceType": {
"Default": "c1.medium",
"Description" : "Type of EC2 instance for web server",
"Type": "String",
"AllowedValues" : [ "t1.micro", "m1.small", "m1.large", "m1.xlarge", "m2.xlarge", "m2.2xlarge", "m2.4xlarge", "c1.medium", "c1.xlarge", "cc1.4xlarge" ],
"ConstraintDescription" : "must contain only alphanumeric characters."
}
},
"Mappings" : {
"AWSInstanceType2Arch" : {
"t1.micro" : { "Arch" : "64" },
"m1.small" : { "Arch" : "32" },
"m1.large" : { "Arch" : "64" },
"m1.xlarge" : { "Arch" : "64" },
"m2.xlarge" : { "Arch" : "64" },
"m2.2xlarge" : { "Arch" : "64" },
"m2.4xlarge" : { "Arch" : "64" },
"c1.medium" : { "Arch" : "32" },
"c1.xlarge" : { "Arch" : "64" },
"cc1.4xlarge" : { "Arch" : "64" }
},
"AWSRegionArch2AMI" : {
"us-east-1" : { "32" : "ami-a7f539ce", "64" : "ami-bbf539d2" },
"us-west-1" : { "32" : "ami-79772b3c", "64" : "ami-7b772b3e" },
"eu-west-1" : { "32" : "ami-65b28011", "64" : "ami-61b28015" },
"ap-southeast-1" : { "32" : "ami-76057f24", "64" : "ami-7a057f28" },
"ap-northeast-1" : { "32" : "ami-2e90242f", "64" : "ami-30902431" }
}
},
"Resources" : {
"AlarmTopic": {
"Properties": {
"Subscription": [
{
"Endpoint": {
"Ref": "OperatorEmail"
},
"Protocol": "email"
}
]
},
"Type": "AWS::SNS::Topic"
},
"ChefClientUser" : {
"Type" : "AWS::IAM::User",
"Properties" : {
"Path": "/",
"Policies": [{
"PolicyName": "root",
"PolicyDocument": { "Statement":[{
"Effect":"Allow",
"Action": [
"cloudformation:DescribeStackResource",
"s3:Get"
],
"Resource":"*"
}]}
}]
}
},
"HostKeys" : {
"Type" : "AWS::IAM::AccessKey",
"Properties" : {
"UserName" : {"Ref": "ChefClientUser"}
}
},
"BucketPolicy" : {
"Type" : "AWS::S3::BucketPolicy",
"Properties" : {
"PolicyDocument": {
"Version" : "2008-10-17",
"Id" : "ReadPolicy",
"Statement" : [{
"Sid" : "ReadAccess",
"Action" : ["s3:GetObject"],
"Effect" : "Allow",
"Resource" : { "Fn::Join" : ["", ["arn:aws:s3:::", {"Ref" : "ChefServerPrivateKeyBucket"} , "/*"]]},
"Principal" : { "AWS": {"Fn::GetAtt" : ["ChefClientUser", "Arn"]} }
}]
},
"Bucket" : {"Ref" : "ChefServerPrivateKeyBucket"}
}
},
"MysqlInstance": {
"Type": "AWS::EC2::Instance",
"DependsOn" : "BucketPolicy",
"Metadata" : {
"AWS::CloudFormation::Init" : {
"config" : {
"packages" : {
"rubygems" : {
"chef" : []
},
"apt" : {
"ruby1.9.2-full" : [],
"build-essential" : [],
"wget" : [],
"ssl-cert" : [],
"rubygems1.9.1" : [],
"s3cmd" : []
}
},
"files" : {
"/etc/chef/solo.rb" : {
"content" : { "Fn::Join" : ["\n", [
"file_cache_path \"/tmp/chef-solo\"",
"cookbook_path \"/tmp/chef-solo/cookbooks\""
]]},
"mode" : "000644",
"owner" : "root",
"group" : "root"
},
"/etc/chef/chef.json" : {
"content" : {
"chef_client": {
"server_url": { "Ref" : "ChefServerURL" }
},
"run_list": [ "recipe[chef-client::config]", "recipe[chef-client]" ]
},
"mode" : "000644",
"owner" : "root",
"group" : "root"
},
"/etc/profile.d/chefclientenv.sh" : {
"content" : { "Fn::Join" : ["\n", [
"export PATH=$PATH:/var/lib/gems/1.8/bin"
]]},
"mode" : "000644",
"owner" : "root",
"group" : "root"
},
"/etc/chef/roles.json" : {
"content" : {
"run_list": [ "role[mysql_server]" ]
},
"mode" : "000644",
"owner" : "root",
"group" : "root"
},
"/home/ubuntu/.s3cfg" : {
"content" : { "Fn::Join" : ["", [
"[default]\n",
"access_key = ", { "Ref" : "HostKeys" }, "\n",
"secret_key = ", {"Fn::GetAtt": ["HostKeys", "SecretAccessKey"]}, "\n",
"use_https = True\n"
]]},
"mode" : "000644",
"owner" : "ubuntu",
"group" : "ubuntu"
},
"/var/lib/gems/1.8/gems/ohai-0.6.4/lib/ohai/plugins/cfn.rb" : {
"source" : { "Fn::Join" : ["", [ { "Ref" : "PackageDownloadURI" }, "/cfn.rb"]]},
"mode" : "000644",
"owner" : "root",
"group" : "root"
}
}
}
}
},
"Properties": {
"SecurityGroups": [ { "Ref" : "MysqlEC2SecurityGroup" }, { "Ref": "ChefServerSecurityGroup" } ],
"ImageId": { "Fn::FindInMap": [ "AWSRegionArch2AMI", { "Ref": "AWS::Region" }, { "Fn::FindInMap": [ "AWSInstanceType2Arch", { "Ref": "MysqlInstanceType" }, "Arch" ] } ]
},
"UserData" : { "Fn::Base64" : { "Fn::Join" : ["", [
"#!/bin/bash -v\n",
"function error_exit\n",
"{\n",
" cfn-signal -e 1 -r \"$1\" '", { "Ref" : "MysqlChefClientWaitHandle" }, "'\n",
" exit 1\n",
"}\n",
"sed -i 's|# deb|deb|g' /etc/apt/sources.list\n",
"apt-get -y update\n",
"apt-get -y install python-setuptools unzip\n",
"#s3cmd -c /home/ubuntu/.s3cfg get s3://", { "Ref" : "ChefServerPrivateKeyBucket" }, "/aws-cfn-bootstrap-1.0-6.zip > /tmp/get_aws-cnf-bootstrap.log 2>&1 || error_exit 'Failed to get Chef Server validation key'\n",
"wget ", { "Ref" : "PackageDownloadURI" }, "/aws-cfn-bootstrap-1.0-6.zip\n",
"#wget https://s3-ap-northeast-1.amazonaws.com/test-gv-common-chefserverprivatekeybucket/aws-cfn-bootstrap-1.0-6.zip --no-check-certificate\n",
"unzip aws-cfn-bootstrap-1.0-6.zip && cd aws-cfn-bootstrap-1.0 && chmod 755 setup.py && ./setup.py install\n",
"# easy_install https://s3.amazonaws.com/cfn-init-demo/aws-cfn-bootstrap-1.0-6.tar.gz\n",
"cfn-init --region ", { "Ref" : "AWS::Region" },
" -s ", { "Ref" : "AWS::StackName" }, " -r MysqlInstance ",
" --access-key ", { "Ref" : "HostKeys" },
" --secret-key ", {"Fn::GetAtt": ["HostKeys", "SecretAccessKey"]},
" --region ", { "Ref" : "AWS::Region" }, " || error_exit 'Failed to run cfn-init'\n",
"apt-get -y install mdadm",
"# mdadm -C /dev/md0 --chunk=256 -n 4 -l 0 /dev/xvdk /dev/xvdl /dev/xvdm /dev/xvdn",
"# mkfs -t ext4 /dev/md0\n",
"# mkdir -p /mnt/mysql\n",
"# mount /dev/md0 /mnt/mysql\n",
"# Fixup path and links for the bootstrap script\n",
"export PATH=$PATH:/var/lib/gems/1.8/bin\n",
"# Bootstrap chef\n",
"chef-solo -c /etc/chef/solo.rb -j /etc/chef/chef.json -r http://s3.amazonaws.com/chef-solo/bootstrap-latest.tar.gz > /tmp/chef_solo.log 2>&1 || error_exit 'Failed to bootstrap chef client'\n",
"# Fixup the server URL in client.rb\n",
"s3cmd -c /home/ubuntu/.s3cfg get s3://", { "Ref" : "ChefServerPrivateKeyBucket" }, "/validation.pem /etc/chef/validation.pem > /tmp/get_validation_key.log 2>&1 || error_exit 'Failed to get Chef Server validation key'\n",
"#wget https://s3-ap-northeast-1.amazonaws.com/", { "Ref" : "ChefServerPrivateKeyBucket" }, "/validation.pem -P /etc/chef/ --no-check-certificate || error_exit 'Failed to get Chef Server validation key'\n",
"sed -i 's|http://localhost:4000|", { "Ref" : "ChefServerURL" }, "|g' /etc/chef/client.rb\n",
"echo node_name \\\"`curl http://169.254.169.254/latest/meta-data/instance-id`\\\" >> /etc/chef/client.rb\n",
"chef-client -j /etc/chef/roles.json > /tmp/initialize_client.log 2>&1 || error_exit 'Failed to initialize host via chef client' \n",
"# If all went well, signal success\n",
"cfn-signal -e $? -r 'Chef Server configuration' '", { "Ref" : "MysqlChefClientWaitHandle" }, "'\n"
]]}},
"Tags" : [
{ "Key" : "Name",
"Value" : "MySQL"
}
],
"KeyName": { "Ref": "KeyName" },
"AvailabilityZone" : "ap-northeast-1b",
"InstanceType": { "Ref": "MysqlInstanceType" }
}
},
"MysqlDataVolume1" : {
"Type" : "AWS::EC2::Volume",
"Properties" : {
"Size" : "50",
"AvailabilityZone" : { "Fn::GetAtt" : [ "MysqlInstance", "AvailabilityZone" ]},
"Tags" : [
{ "Key" : "Name",
"Value" : "MySQL RAID0 id1"
}
]
}
},
"MountPoint" : {
"Type" : "AWS::EC2::VolumeAttachment",
"Properties" : {
"InstanceId" : { "Ref" : "MysqlInstance" },
"VolumeId" : { "Ref" : "MysqlDataVolume1" },
"Device" : "/dev/sdk"
}
},
"MysqlDataVolume2" : {
"Type" : "AWS::EC2::Volume",
"Properties" : {
"Size" : "50",
"AvailabilityZone" : { "Fn::GetAtt" : [ "MysqlInstance", "AvailabilityZone" ]},
"Tags" : [
{ "Key" : "Name",
"Value" : "MySQL RAID0 id2"
}
]
}
},
"MountPoint" : {
"Type" : "AWS::EC2::VolumeAttachment",
"Properties" : {
"InstanceId" : { "Ref" : "MysqlInstance" },
"VolumeId" : { "Ref" : "MysqlDataVolume2" },
"Device" : "/dev/sdl"
}
},
"MysqlDataVolume3" : {
"Type" : "AWS::EC2::Volume",
"Properties" : {
"Size" : "50",
"AvailabilityZone" : { "Fn::GetAtt" : [ "MysqlInstance", "AvailabilityZone" ]},
"Tags" : [
{ "Key" : "Name",
"Value" : "MySQL RAID0 id3"
}
]
}
},
"MountPoint" : {
"Type" : "AWS::EC2::VolumeAttachment",
"Properties" : {
"InstanceId" : { "Ref" : "MysqlInstance" },
"VolumeId" : { "Ref" : "MysqlDataVolume3" },
"Device" : "/dev/sdm"
}
},
"MysqlDataVolume4" : {
"Type" : "AWS::EC2::Volume",
"Properties" : {
"Size" : "50",
"AvailabilityZone" : { "Fn::GetAtt" : [ "MysqlInstance", "AvailabilityZone" ]},
"Tags" : [
{ "Key" : "Name",
"Value" : "MySQL RAID0 id4"
}
]
}
},
"MountPoint" : {
"Type" : "AWS::EC2::VolumeAttachment",
"Properties" : {
"InstanceId" : { "Ref" : "MysqlInstance" },
"VolumeId" : { "Ref" : "MysqlDataVolume4" },
"Device" : "/dev/sdn"
}
},
"MysqlLogVolume" : {
"Type" : "AWS::EC2::Volume",
"Properties" : {
"Size" : "300",
"AvailabilityZone" : { "Fn::GetAtt" : [ "MysqlInstance", "AvailabilityZone" ]},
"Tags" : [
{ "Key" : "Name",
"Value" : "MySQL Log"
}
]
}
},
"MountPoint" : {
"Type" : "AWS::EC2::VolumeAttachment",
"Properties" : {
"InstanceId" : { "Ref" : "MysqlInstance" },
"VolumeId" : { "Ref" : "MysqlLogVolume" },
"Device" : "/dev/sdo"
}
},
"MysqlEC2SecurityGroup" : {
"Type" : "AWS::EC2::SecurityGroup",
"Properties" : {
"GroupDescription" : "Open up SSH access, HTTP over port 80 and mysql connection",
"SecurityGroupIngress" : [
{ "IpProtocol": "tcp", "FromPort": "22", "ToPort": "22", "CidrIp": "0.0.0.0/0" },
{ "IpProtocol" : "tcp", "FromPort" : "3306", "ToPort" : "3306", "SourceSecurityGroupName": { "Ref": "WebFpEC2SecurityGroup" } },
{ "IpProtocol" : "tcp", "FromPort" : "3306", "ToPort" : "3306", "SourceSecurityGroupName": { "Ref": "WebSpEC2SecurityGroup" } },
{ "IpProtocol" : "tcp", "FromPort" : "3306", "ToPort" : "3306", "SourceSecurityGroupName": { "Ref": "LogEC2SecurityGroup" } }
]
}
},
"MysqlEIP" : {
"Type" : "AWS::EC2::EIP",
"Properties" : {
"InstanceId" : { "Ref" : "MysqlInstance" }
}
},
"CPUAlarmHigh": {
"Type" : "AWS::CloudWatch::Alarm",
"Properties": {
"EvaluationPeriods": "10",
"Statistic": "Average",
"Threshold": "50",
"AlarmDescription": "Alarm if CPU too high or metric disappears indicating the Mysql instance is having issues",
"Period": "60",
"Namespace": "AWS/EC2",
"MetricName": "CPUUtilization",
"Dimensions": [ {
"Name": "InstanceIdentifier",
"Value": { "Ref": "MysqlInstance" }
} ],
"ComparisonOperator": "GreaterThanThreshold",
"AlarmActions": [ { "Ref": "AlarmTopic" } ],
"InsufficientDataActions": [ { "Ref": "AlarmTopic" } ]
}
},
"MysqlChefClientWaitHandle" : {
"Type" : "AWS::CloudFormation::WaitConditionHandle"
},
"MysqlChefClientWaitCondition" : {
"Type" : "AWS::CloudFormation::WaitCondition",
"DependsOn" : "MysqlInstance",
"Properties" : {
"Handle" : { "Ref" : "MysqlChefClientWaitHandle" },
"Timeout" : "2400"
}
},
"TokyoTyrantInstance": {
"Type": "AWS::EC2::Instance",
"DependsOn" : "BucketPolicy",
"Metadata" : {
"AWS::CloudFormation::Init" : {
"config" : {
"packages" : {
"rubygems" : {
"chef" : []
},
"apt" : {
"ruby1.9.2-full" : [],
"build-essential" : [],
"wget" : [],
"ssl-cert" : [],
"rubygems1.9.1" : [],
"s3cmd" : []
}
},
"files" : {
"/etc/chef/solo.rb" : {
"content" : { "Fn::Join" : ["\n", [
"file_cache_path \"/tmp/chef-solo\"",
"cookbook_path \"/tmp/chef-solo/cookbooks\""
]]},
"mode" : "000644",
"owner" : "root",
"group" : "root"
},
"/etc/chef/chef.json" : {
"content" : {
"chef_client": {
"server_url": { "Ref" : "ChefServerURL" }
},
"run_list": [ "recipe[chef-client::config]", "recipe[chef-client]" ]
},
"mode" : "000644",
"owner" : "root",
"group" : "root"
},
"/etc/profile.d/chefclientenv.sh" : {
"content" : { "Fn::Join" : ["\n", [
"export PATH=$PATH:/var/lib/gems/1.8/bin"
]]},
"mode" : "000644",
"owner" : "root",
"group" : "root"
},
"/etc/chef/roles.json" : {
"content" : {
"run_list": ["role[tokyotyrant_server]" ]
},
"mode" : "000644",
"owner" : "root",
"group" : "root"
},
"/home/ubuntu/.s3cfg" : {
"content" : { "Fn::Join" : ["", [
"[default]\n",
"access_key = ", { "Ref" : "HostKeys" }, "\n",
"secret_key = ", {"Fn::GetAtt": ["HostKeys", "SecretAccessKey"]}, "\n",
"use_https = True\n"
]]},
"mode" : "000644",
"owner" : "ubuntu",
"group" : "ubuntu"
},
"/var/lib/gems/1.8/gems/ohai-0.6.4/lib/ohai/plugins/cfn.rb" : {
"source" : { "Fn::Join" : ["", [ { "Ref" : "PackageDownloadURI" }, "/cfn.rb"]]},
"mode" : "000644",
"owner" : "root",
"group" : "root"
}
}
}
}
},
"Properties": {
"SecurityGroups": [ { "Ref" : "TokyoTyrantEC2SecurityGroup" }, { "Ref": "ChefServerSecurityGroup" } ],
"ImageId": { "Fn::FindInMap": [ "AWSRegionArch2AMI", { "Ref": "AWS::Region" }, { "Fn::FindInMap": [ "AWSInstanceType2Arch", { "Ref": "TokyoTyrantInstanceType" }, "Arch" ] } ]
},
"UserData" : { "Fn::Base64" : { "Fn::Join" : ["", [
"#!/bin/bash -v\n",
"function error_exit\n",
"{\n",
" cfn-signal -e 1 -r \"$1\" '", { "Ref" : "TokyoTyrantChefClientWaitHandle" }, "'\n",
" exit 1\n",
"}\n",
"sed -i 's|# deb|deb|g' /etc/apt/sources.list\n",
"apt-get -y update\n",
"apt-get -y install python-setuptools unzip\n",
"#s3cmd -c /home/ubuntu/.s3cfg get s3://", { "Ref" : "ChefServerPrivateKeyBucket" }, "/aws-cfn-bootstrap-1.0-6.zip > /tmp/get_aws-cnf-bootstrap.log 2>&1 || error_exit 'Failed to get Chef Server validation key'\n",
"wget ", { "Ref" : "PackageDownloadURI" }, "/aws-cfn-bootstrap-1.0-6.zip\n",
"#wget https://s3-ap-northeast-1.amazonaws.com/test-gv-common-chefserverprivatekeybucket/aws-cfn-bootstrap-1.0-6.zip --no-check-certificate\n",
"unzip aws-cfn-bootstrap-1.0-6.zip && cd aws-cfn-bootstrap-1.0 && chmod 755 setup.py && ./setup.py install\n",
"# easy_install https://s3.amazonaws.com/cfn-init-demo/aws-cfn-bootstrap-1.0-6.tar.gz\n",
"cfn-init --region ", { "Ref" : "AWS::Region" },
" -s ", { "Ref" : "AWS::StackName" }, " -r TokyoTyrantInstance ",
" --access-key ", { "Ref" : "HostKeys" },
" --secret-key ", {"Fn::GetAtt": ["HostKeys", "SecretAccessKey"]},
" --region ", { "Ref" : "AWS::Region" }, " || error_exit 'Failed to run cfn-init'\n",
"# Fixup path and links for the bootstrap script\n",
"export PATH=$PATH:/var/lib/gems/1.8/bin\n",
"# Bootstrap chef\n",
"chef-solo -c /etc/chef/solo.rb -j /etc/chef/chef.json -r http://s3.amazonaws.com/chef-solo/bootstrap-latest.tar.gz > /tmp/chef_solo.log 2>&1 || error_exit 'Failed to bootstrap chef client'\n",
"# Fixup the server URL in client.rb\n",
"s3cmd -c /home/ubuntu/.s3cfg get s3://", { "Ref" : "ChefServerPrivateKeyBucket" }, "/validation.pem /etc/chef/validation.pem > /tmp/get_validation_key.log 2>&1 || error_exit 'Failed to get Chef Server validation key'\n",
"#wget https://s3-ap-northeast-1.amazonaws.com/", { "Ref" : "ChefServerPrivateKeyBucket" }, "/validation.pem -P /etc/chef/ --no-check-certificate || error_exit 'Failed to get Chef Server validation key'\n",
"sed -i 's|http://localhost:4000|", { "Ref" : "ChefServerURL" }, "|g' /etc/chef/client.rb\n",
"echo node_name \\\"`curl http://169.254.169.254/latest/meta-data/instance-id`\\\" >> /etc/chef/client.rb\n",
"chef-client -j /etc/chef/roles.json > /tmp/initialize_client.log 2>&1 || error_exit 'Failed to initialize host via chef client' \n",
"# If all went well, signal success\n",
"cfn-signal -e $? -r 'Chef Server configuration' '", { "Ref" : "TokyoTyrantChefClientWaitHandle" }, "'\n"
]]}},
"Tags" : [
{ "Key" : "Name",
"Value" : "TokyoTyrant"
}
],
"KeyName": { "Ref": "KeyName" },
"AvailabilityZone" : "ap-northeast-1b",
"InstanceType": { "Ref": "TokyoTyrantInstanceType" }
}
},
"TyrantVolume" : {
"Type" : "AWS::EC2::Volume",
"Properties" : {
"Size" : "20",
"AvailabilityZone" : { "Fn::GetAtt" : [ "TokyoTyrantInstance", "AvailabilityZone" ]},
"Tags" : [
{ "Key" : "Name",
"Value" : "TokyoTyrant"
}
]
}
},
"MountPoint" : {
"Type" : "AWS::EC2::VolumeAttachment",
"Properties" : {
"InstanceId" : { "Ref" : "TokyoTyrantInstance" },
"VolumeId" : { "Ref" : "TyrantVolume" },
"Device" : "/dev/sdk"
}
},
"TokyoTyrantEC2SecurityGroup" : {
"Type" : "AWS::EC2::SecurityGroup",
"Properties" : {
"GroupDescription" : "Open up SSH access and TokyoTyrant over port 1978",
"SecurityGroupIngress" : [
{ "IpProtocol": "tcp", "FromPort": "22", "ToPort": "22", "CidrIp": "0.0.0.0/0" },
{ "IpProtocol" : "tcp", "FromPort" : "1978", "ToPort" : "1978", "SourceSecurityGroupName": { "Ref": "WebFpEC2SecurityGroup" } },
{ "IpProtocol" : "tcp", "FromPort" : "1978", "ToPort" : "1978", "SourceSecurityGroupName": { "Ref": "WebSpEC2SecurityGroup" } }
]
}
},
"TokyoTyrantEIP" : {
"Type" : "AWS::EC2::EIP",
"Properties" : {
"InstanceId" : { "Ref" : "TokyoTyrantInstance" }
}
},
"TokyoTyrantCPUAlarmHigh": {
"Type" : "AWS::CloudWatch::Alarm",
"Properties": {
"EvaluationPeriods": "10",
"Statistic": "Average",
"Threshold": "50",
"AlarmDescription": "Alarm if CPU too high or metric disappears indicating the Tyrant instance is having issues",
"Period": "60",
"Namespace": "AWS/EC2",
"MetricName": "CPUUtilization",
"Dimensions": [ {
"Name": "InstanceIdentifier",
"Value": { "Ref": "TokyoTyrantInstance" }
} ],
"ComparisonOperator": "GreaterThanThreshold",
"AlarmActions": [ { "Ref": "AlarmTopic" } ],
"InsufficientDataActions": [ { "Ref": "AlarmTopic" } ]
}
},
"TokyoTyrantChefClientWaitHandle" : {
"Type" : "AWS::CloudFormation::WaitConditionHandle"
},
"TokyoTyrantChefClientWaitCondition" : {
"Type" : "AWS::CloudFormation::WaitCondition",
"DependsOn" : "TokyoTyrantInstance",
"Properties" : {
"Handle" : { "Ref" : "TokyoTyrantChefClientWaitHandle" },
"Timeout" : "1200"
}
},
"MemcachedInstance": {
"Type": "AWS::EC2::Instance",
"DependsOn" : "BucketPolicy",
"Metadata" : {
"AWS::CloudFormation::Init" : {
"config" : {
"packages" : {
"rubygems" : {
"chef" : []
},
"apt" : {
"ruby1.9.2-full" : [],
"build-essential" : [],
"wget" : [],
"ssl-cert" : [],
"rubygems1.9.1" : [],
"s3cmd" : []
}
},
"files" : {
"/etc/chef/solo.rb" : {
"content" : { "Fn::Join" : ["\n", [
"file_cache_path \"/tmp/chef-solo\"",
"cookbook_path \"/tmp/chef-solo/cookbooks\""
]]},
"mode" : "000644",
"owner" : "root",
"group" : "root"
},
"/etc/chef/chef.json" : {
"content" : {
"chef_client": {
"server_url": { "Ref" : "ChefServerURL" }
},
"run_list": [ "recipe[chef-client::config]", "recipe[chef-client]" ]
},
"mode" : "000644",
"owner" : "root",
"group" : "root"
},
"/etc/profile.d/chefclientenv.sh" : {
"content" : { "Fn::Join" : ["\n", [
"export PATH=$PATH:/var/lib/gems/1.8/bin"
]]},
"mode" : "000644",
"owner" : "root",
"group" : "root"
},
"/etc/chef/roles.json" : {
"content" : {
"run_list": [ "role[memcached_server_source]", "role[tokyotyrant_server]" ]
},
"mode" : "000644",
"owner" : "root",
"group" : "root"
},
"/home/ubuntu/.s3cfg" : {
"content" : { "Fn::Join" : ["", [
"[default]\n",
"access_key = ", { "Ref" : "HostKeys" }, "\n",
"secret_key = ", {"Fn::GetAtt": ["HostKeys", "SecretAccessKey"]}, "\n",
"use_https = True\n"
]]},
"mode" : "000644",
"owner" : "ubuntu",
"group" : "ubuntu"
},
"/var/lib/gems/1.8/gems/ohai-0.6.4/lib/ohai/plugins/cfn.rb" : {
"source" : { "Fn::Join" : ["", [ { "Ref" : "PackageDownloadURI" }, "/cfn.rb"]]},
"mode" : "000644",
"owner" : "root",
"group" : "root"
}
}
}
}
},
"Properties": {
"SecurityGroups": [ { "Ref" : "MemcachedEC2SecurityGroup" }, { "Ref": "ChefServerSecurityGroup" } ],
"ImageId": { "Fn::FindInMap": [ "AWSRegionArch2AMI", { "Ref": "AWS::Region" }, { "Fn::FindInMap": [ "AWSInstanceType2Arch", { "Ref": "MemcachedInstanceType" }, "Arch" ] } ]
},
"UserData" : { "Fn::Base64" : { "Fn::Join" : ["", [
"#!/bin/bash -v\n",
"function error_exit\n",
"{\n",
" cfn-signal -e 1 -r \"$1\" '", { "Ref" : "MemcachedChefClientWaitHandle" }, "'\n",
" exit 1\n",
"}\n",
"sed -i 's|# deb|deb|g' /etc/apt/sources.list\n",
"apt-get -y update\n",
"apt-get -y install python-setuptools unzip\n",
"#s3cmd -c /home/ubuntu/.s3cfg get s3://", { "Ref" : "ChefServerPrivateKeyBucket" }, "/aws-cfn-bootstrap-1.0-6.zip > /tmp/get_aws-cnf-bootstrap.log 2>&1 || error_exit 'Failed to get Chef Server validation key'\n",
"wget ", { "Ref" : "PackageDownloadURI" }, "/aws-cfn-bootstrap-1.0-6.zip\n",
"#wget https://s3-ap-northeast-1.amazonaws.com/test-gv-common-chefserverprivatekeybucket/aws-cfn-bootstrap-1.0-6.zip --no-check-certificate\n",
"unzip aws-cfn-bootstrap-1.0-6.zip && cd aws-cfn-bootstrap-1.0 && chmod 755 setup.py && ./setup.py install\n",
"# easy_install https://s3.amazonaws.com/cfn-init-demo/aws-cfn-bootstrap-1.0-6.tar.gz\n",
"cfn-init --region ", { "Ref" : "AWS::Region" },
" -s ", { "Ref" : "AWS::StackName" }, " -r MemcachedInstance ",
" --access-key ", { "Ref" : "HostKeys" },
" --secret-key ", {"Fn::GetAtt": ["HostKeys", "SecretAccessKey"]},
" --region ", { "Ref" : "AWS::Region" }, " || error_exit 'Failed to run cfn-init'\n",
"# Fixup path and links for the bootstrap script\n",
"export PATH=$PATH:/var/lib/gems/1.8/bin\n",
"# Bootstrap chef\n",
"chef-solo -c /etc/chef/solo.rb -j /etc/chef/chef.json -r http://s3.amazonaws.com/chef-solo/bootstrap-latest.tar.gz > /tmp/chef_solo.log 2>&1 || error_exit 'Failed to bootstrap chef client'\n",
"# Fixup the server URL in client.rb\n",
"s3cmd -c /home/ubuntu/.s3cfg get s3://", { "Ref" : "ChefServerPrivateKeyBucket" }, "/validation.pem /etc/chef/validation.pem > /tmp/get_validation_key.log 2>&1 || error_exit 'Failed to get Chef Server validation key'\n",
"#wget https://s3-ap-northeast-1.amazonaws.com/", { "Ref" : "ChefServerPrivateKeyBucket" }, "/validation.pem -P /etc/chef/ --no-check-certificate || error_exit 'Failed to get Chef Server validation key'\n",
"sed -i 's|http://localhost:4000|", { "Ref" : "ChefServerURL" }, "|g' /etc/chef/client.rb\n",
"echo node_name \\\"`curl http://169.254.169.254/latest/meta-data/instance-id`\\\" >> /etc/chef/client.rb\n",
"chef-client -j /etc/chef/roles.json > /tmp/initialize_client.log 2>&1 || error_exit 'Failed to initialize host via chef client' \n",
"# If all went well, signal success\n",
"cfn-signal -e $? -r 'Chef Server configuration' '", { "Ref" : "MemcachedChefClientWaitHandle" }, "'\n"
]]}},
"Tags" : [
{ "Key" : "Name",
"Value" : "Memcached"
}
],
"KeyName": { "Ref": "KeyName" },
"AvailabilityZone" : "ap-northeast-1b",
"InstanceType": { "Ref": "MemcachedInstanceType" }
}
},
"MemcachedEC2SecurityGroup" : {
"Type" : "AWS::EC2::SecurityGroup",
"Properties" : {
"GroupDescription" : "Open up SSH access and Memcached over port 11211",
"SecurityGroupIngress" : [
{ "IpProtocol": "tcp", "FromPort": "22", "ToPort": "22", "CidrIp": "0.0.0.0/0" },
{ "IpProtocol" : "tcp", "FromPort" : "11211", "ToPort" : "11211", "SourceSecurityGroupName": { "Ref": "WebFpEC2SecurityGroup" } },
{ "IpProtocol" : "tcp", "FromPort" : "11211", "ToPort" : "11211", "SourceSecurityGroupName": { "Ref": "WebSpEC2SecurityGroup" } }
]
}
},
"MemcachedEIP" : {
"Type" : "AWS::EC2::EIP",
"Properties" : {
"InstanceId" : { "Ref" : "MemcachedInstance" }
}
},
"MemcachedCPUAlarmHigh": {
"Type" : "AWS::CloudWatch::Alarm",
"Properties": {
"EvaluationPeriods": "10",
"Statistic": "Average",
"Threshold": "50",
"AlarmDescription": "Alarm if CPU too high or metric disappears indicating the Memcached Tyrant instance is having issues",
"Period": "60",
"Namespace": "AWS/EC2",
"MetricName": "CPUUtilization",
"Dimensions": [ {
"Name": "InstanceIdentifier",
"Value": { "Ref": "MemcachedInstance" }
} ],
"ComparisonOperator": "GreaterThanThreshold",
"AlarmActions": [ { "Ref": "AlarmTopic" } ],
"InsufficientDataActions": [ { "Ref": "AlarmTopic" } ]
}
},
"MemcachedChefClientWaitHandle" : {
"Type" : "AWS::CloudFormation::WaitConditionHandle"
},
"MemcachedChefClientWaitCondition" : {
"Type" : "AWS::CloudFormation::WaitCondition",
"DependsOn" : "MemcachedInstance",
"Properties" : {
"Handle" : { "Ref" : "MemcachedChefClientWaitHandle" },
"Timeout" : "1200"
}
},
"LogInstance": {
"Type": "AWS::EC2::Instance",
"DependsOn" : "BucketPolicy",
"Metadata" : {
"AWS::CloudFormation::Init" : {
"config" : {
"packages" : {
"rubygems" : {
"chef" : []
},
"apt" : {
"ruby1.9.2-full" : [],
"build-essential" : [],
"wget" : [],
"ssl-cert" : [],
"rubygems1.9.1" : [],
"s3cmd" : []
}
},
"files" : {
"/etc/chef/solo.rb" : {
"content" : { "Fn::Join" : ["\n", [
"file_cache_path \"/tmp/chef-solo\"",
"cookbook_path \"/tmp/chef-solo/cookbooks\""
]]},
"mode" : "000644",
"owner" : "root",
"group" : "root"
},
"/etc/chef/chef.json" : {
"content" : {
"chef_client": {
"server_url": { "Ref" : "ChefServerURL" }
},
"run_list": [ "recipe[chef-client::config]", "recipe[chef-client]" ]
},
"mode" : "000644",
"owner" : "root",
"group" : "root"
},
"/etc/profile.d/chefclientenv.sh" : {
"content" : { "Fn::Join" : ["\n", [
"export PATH=$PATH:/var/lib/gems/1.8/bin"
]]},
"mode" : "000644",
"owner" : "root",
"group" : "root"
},
"/etc/chef/roles.json" : {
"content" : {
"run_list": [ "role[rsyslog_server]", "role[mysql_server]", "role[tokyotyrant_server]" ]
},
"mode" : "000644",
"owner" : "root",
"group" : "root"
},
"/home/ubuntu/.s3cfg" : {
"content" : { "Fn::Join" : ["", [
"[default]\n",
"access_key = ", { "Ref" : "HostKeys" }, "\n",
"secret_key = ", {"Fn::GetAtt": ["HostKeys", "SecretAccessKey"]}, "\n",
"use_https = True\n"
]]},
"mode" : "000644",
"owner" : "ubuntu",
"group" : "ubuntu"
},
"/var/lib/gems/1.8/gems/ohai-0.6.4/lib/ohai/plugins/cfn.rb" : {
"source" : { "Fn::Join" : ["", [ { "Ref" : "PackageDownloadURI" }, "/cfn.rb"]]},
"mode" : "000644",
"owner" : "root",
"group" : "root"
}
}
}
}
},
"Properties": {
"SecurityGroups": [ { "Ref" : "LogEC2SecurityGroup" }, { "Ref": "ChefServerSecurityGroup" } ],
"ImageId": { "Fn::FindInMap": [ "AWSRegionArch2AMI", { "Ref": "AWS::Region" }, { "Fn::FindInMap": [ "AWSInstanceType2Arch", { "Ref": "LogInstanceType" }, "Arch" ] } ]
},
"UserData" : { "Fn::Base64" : { "Fn::Join" : ["", [
"#!/bin/bash -v\n",
"function error_exit\n",
"{\n",
" cfn-signal -e 1 -r \"$1\" '", { "Ref" : "LogChefClientWaitHandle" }, "'\n",
" exit 1\n",
"}\n",
"sed -i 's|# deb|deb|g' /etc/apt/sources.list\n",
"apt-get -y update\n",
"apt-get -y install python-setuptools unzip\n",
"#s3cmd -c /home/ubuntu/.s3cfg get s3://", { "Ref" : "ChefServerPrivateKeyBucket" }, "/aws-cfn-bootstrap-1.0-6.zip > /tmp/get_aws-cnf-bootstrap.log 2>&1 || error_exit 'Failed to get Chef Server validation key'\n",
"wget ", { "Ref" : "PackageDownloadURI" }, "/aws-cfn-bootstrap-1.0-6.zip\n",
"#wget https://s3-ap-northeast-1.amazonaws.com/test-gv-common-chefserverprivatekeybucket/aws-cfn-bootstrap-1.0-6.zip --no-check-certificate\n",
"unzip aws-cfn-bootstrap-1.0-6.zip && cd aws-cfn-bootstrap-1.0 && chmod 755 setup.py && ./setup.py install\n",
"# easy_install https://s3.amazonaws.com/cfn-init-demo/aws-cfn-bootstrap-1.0-6.tar.gz\n",
"cfn-init --region ", { "Ref" : "AWS::Region" },
" -s ", { "Ref" : "AWS::StackName" }, " -r LogInstance ",
" --access-key ", { "Ref" : "HostKeys" },
" --secret-key ", {"Fn::GetAtt": ["HostKeys", "SecretAccessKey"]},
" --region ", { "Ref" : "AWS::Region" }, " || error_exit 'Failed to run cfn-init'\n",
"#mkfs -t ext4 /dev/xvdk\n",
"#mkdir -p /mnt/mysql\n",
"#mount /dev/xvdk /mnt\n",
"#mkfs -t ext4 /dev/xvdl\n",
"#mkdir -p /mnt/tyrant\n",
"#mount /dev/xvdk /mnt/tyrant\n",
"# Fixup path and links for the bootstrap script\n",
"export PATH=$PATH:/var/lib/gems/1.8/bin\n",
"# Bootstrap chef\n",
"chef-solo -c /etc/chef/solo.rb -j /etc/chef/chef.json -r http://s3.amazonaws.com/chef-solo/bootstrap-latest.tar.gz > /tmp/chef_solo.log 2>&1 || error_exit 'Failed to bootstrap chef client'\n",
"# Fixup the server URL in client.rb\n",
"s3cmd -c /home/ubuntu/.s3cfg get s3://", { "Ref" : "ChefServerPrivateKeyBucket" }, "/validation.pem /etc/chef/validation.pem > /tmp/get_validation_key.log 2>&1 || error_exit 'Failed to get Chef Server validation key'\n",
"#wget https://s3-ap-northeast-1.amazonaws.com/", { "Ref" : "ChefServerPrivateKeyBucket" }, "/validation.pem -P /etc/chef/ --no-check-certificate || error_exit 'Failed to get Chef Server validation key'\n",
"sed -i 's|http://localhost:4000|", { "Ref" : "ChefServerURL" }, "|g' /etc/chef/client.rb\n",
"echo node_name \\\"`curl http://169.254.169.254/latest/meta-data/instance-id`\\\" >> /etc/chef/client.rb\n",
"chef-client -j /etc/chef/roles.json > /tmp/initialize_client.log 2>&1 || error_exit 'Failed to initialize host via chef client' \n",
"# If all went well, signal success\n",
"cfn-signal -e $? -r 'Chef Server configuration' '", { "Ref" : "LogChefClientWaitHandle" }, "'\n"
]]}},
"Tags" : [
{ "Key" : "Name",
"Value" : "Log"
}
],
"KeyName": { "Ref": "KeyName" },
"AvailabilityZone" : "ap-northeast-1a",
"InstanceType": { "Ref": "LogInstanceType" }
}
},
"LogCPUAlarmHigh": {
"Type" : "AWS::CloudWatch::Alarm",
"Properties": {
"EvaluationPeriods": "20",
"Statistic": "Average",
"Threshold": "80",
"AlarmDescription": "Alarm if CPU too high or metric disappears indicating the Log instance is having issues",
"Period": "60",
"Namespace": "AWS/EC2",
"MetricName": "CPUUtilization",
"Dimensions": [ {
"Name": "InstanceIdentifier",
"Value": { "Ref": "LogInstance" }
} ],
"ComparisonOperator": "GreaterThanThreshold",
"AlarmActions": [ { "Ref": "AlarmTopic" } ],
"InsufficientDataActions": [ { "Ref": "AlarmTopic" } ]
}
},
"LogMysqlVolume" : {
"Type" : "AWS::EC2::Volume",
"Properties" : {
"Size" : "100",
"AvailabilityZone" : { "Fn::GetAtt" : [ "LogInstance", "AvailabilityZone" ]},
"Tags" : [
{ "Key" : "Name",
"Value" : "Log MySQL"
}
]
}
},
"MountPoint" : {
"Type" : "AWS::EC2::VolumeAttachment",
"Properties" : {
"InstanceId" : { "Ref" : "LogInstance" },
"VolumeId" : { "Ref" : "LogMysqlVolume" },
"Device" : "/dev/sdk"
}
},
"LogTyrantVolume" : {
"Type" : "AWS::EC2::Volume",
"Properties" : {
"Size" : "20",
"AvailabilityZone" : { "Fn::GetAtt" : [ "LogInstance", "AvailabilityZone" ]},
"Tags" : [
{ "Key" : "Name",
"Value" : "Log Tyrant"
}
]
}
},
"MountPoint" : {
"Type" : "AWS::EC2::VolumeAttachment",
"Properties" : {
"InstanceId" : { "Ref" : "TokyoTyrantInstance" },
"VolumeId" : { "Ref" : "TyrantVolume" },
"Device" : "/dev/sdl"
}
},
"LogEC2SecurityGroup" : {
"Type" : "AWS::EC2::SecurityGroup",
"Properties" : {
"GroupDescription" : "Open up SSH access and Rsyslog over port 514",
"SecurityGroupIngress" : [
{ "IpProtocol": "tcp", "FromPort": "22", "ToPort": "22", "CidrIp": "0.0.0.0/0" },
{ "IpProtocol": "tcp", "FromPort": "514", "ToPort": "514", "CidrIp": "0.0.0.0/0" }
]
}
},
"LogEIP" : {
"Type" : "AWS::EC2::EIP",
"Properties" : {
"InstanceId" : { "Ref" : "LogInstance" }
}
},
"LogChefClientWaitHandle" : {
"Type" : "AWS::CloudFormation::WaitConditionHandle"
},
"LogChefClientWaitCondition" : {
"Type" : "AWS::CloudFormation::WaitCondition",
"DependsOn" : "LogInstance",
"Properties" : {
"Handle" : { "Ref" : "LogChefClientWaitHandle" },
"Timeout" : "3000"
}
},
"WebFpServerGroup" : {
"Type" : "AWS::AutoScaling::AutoScalingGroup",
"DependsOn" : "LogInstance",
"Properties" : {
"AvailabilityZones" : ["ap-northeast-1b"],
"LaunchConfigurationName" : { "Ref" : "WebFpLaunchConfig" },
"MinSize" : "1",
"MaxSize" : "1",
"LoadBalancerNames" : [ { "Ref" : "WebFpElasticLoadBalancer" } ]
}
},
"WebFpLaunchConfig" : {
"Type" : "AWS::AutoScaling::LaunchConfiguration",
"DependsOn" : "BucketPolicy",
"Metadata" : {
"AWS::CloudFormation::Init" : {
"config" : {
"packages" : {
"rubygems" : {
"chef" : []
},
"apt" : {
"ruby1.9.2-full" : [],
"build-essential" : [],
"wget" : [],
"ssl-cert" : [],
"rubygems1.9.1" : [],
"s3cmd" : []
}
},
"files" : {
"/etc/chef/solo.rb" : {
"content" : { "Fn::Join" : ["\n", [
"file_cache_path \"/tmp/chef-solo\"",
"cookbook_path \"/tmp/chef-solo/cookbooks\""
]]},
"mode" : "000644",
"owner" : "root",
"group" : "root"
},
"/etc/chef/chef.json" : {
"content" : {
"chef_client": {
"server_url": { "Ref" : "ChefServerURL" }
},
"run_list": [ "recipe[chef-client::config]", "recipe[chef-client]" ]
},
"mode" : "000644",
"owner" : "root",
"group" : "root"
},
"/etc/profile.d/chefclientenv.sh" : {
"content" : { "Fn::Join" : ["\n", [
"export PATH=$PATH:/var/lib/gems/1.8/bin"
]]},
"mode" : "000644",
"owner" : "root",
"group" : "root"
},
"/etc/chef/roles.json" : {
"content" : {
"run_list": [ "role[fpwebapp_server]" ]
},
"mode" : "000644",
"owner" : "root",
"group" : "root"
},
"/home/ubuntu/.s3cfg" : {
"content" : { "Fn::Join" : ["", [
"[default]\n",
"access_key = ", { "Ref" : "HostKeys" }, "\n",
"secret_key = ", {"Fn::GetAtt": ["HostKeys", "SecretAccessKey"]}, "\n",
"use_https = True\n"
]]},
"mode" : "000644",
"owner" : "ubuntu",
"group" : "ubuntu"
},
"/var/lib/gems/1.8/gems/ohai-0.6.4/lib/ohai/plugins/cfn.rb" : {
"source" : { "Fn::Join" : ["", [ { "Ref" : "PackageDownloadURI" }, "/cfn.rb"]]},
"mode" : "000644",
"owner" : "root",
"group" : "root"
}
}
}
}
},
"Properties": {
"SecurityGroups": [ { "Ref" : "WebFpEC2SecurityGroup" }, { "Ref": "ChefServerSecurityGroup" } ],
"ImageId": { "Fn::FindInMap": [ "AWSRegionArch2AMI", { "Ref": "AWS::Region" }, { "Fn::FindInMap": [ "AWSInstanceType2Arch", { "Ref": "WebFpInstanceType" }, "Arch" ] } ]
},
"UserData" : { "Fn::Base64" : { "Fn::Join" : ["", [
"#!/bin/bash -v\n",
"function error_exit\n",
"{\n",
" cfn-signal -e 1 -r \"$1\" '", { "Ref" : "WebFpChefClientWaitHandle" }, "'\n",
" exit 1\n",
"}\n",
"sed -i 's|# deb|deb|g' /etc/apt/sources.list\n",
"apt-get -y update\n",
"apt-get -y install python-setuptools unzip\n",
"#s3cmd -c /home/ubuntu/.s3cfg get s3://", { "Ref" : "ChefServerPrivateKeyBucket" }, "/aws-cfn-bootstrap-1.0-6.zip > /tmp/get_aws-cnf-bootstrap.log 2>&1 || error_exit 'Failed to get Chef Server validation key'\n",
"wget ", { "Ref" : "PackageDownloadURI" }, "/aws-cfn-bootstrap-1.0-6.zip\n",
"#wget https://s3-ap-northeast-1.amazonaws.com/test-gv-common-chefserverprivatekeybucket/aws-cfn-bootstrap-1.0-6.zip --no-check-certificate\n",
"unzip aws-cfn-bootstrap-1.0-6.zip && cd aws-cfn-bootstrap-1.0 && chmod 755 setup.py && ./setup.py install\n",
"# easy_install https://s3.amazonaws.com/cfn-init-demo/aws-cfn-bootstrap-1.0-6.tar.gz\n",
"cfn-init --region ", { "Ref" : "AWS::Region" },
" -s ", { "Ref" : "AWS::StackName" }, " -r WebFpLaunchConfig ",
" --access-key ", { "Ref" : "HostKeys" },
" --secret-key ", {"Fn::GetAtt": ["HostKeys", "SecretAccessKey"]},
" --region ", { "Ref" : "AWS::Region" }, " || error_exit 'Failed to run cfn-init'\n",
"# Fixup path and links for the bootstrap script\n",
"export PATH=$PATH:/var/lib/gems/1.8/bin || error_exit 'Failed to export PATH gem'\n",
"# Bootstrap chef\n",
"chef-solo -c /etc/chef/solo.rb -j /etc/chef/chef.json -r http://s3.amazonaws.com/chef-solo/bootstrap-latest.tar.gz > /tmp/chef_solo.log 2>&1 || error_exit 'Failed to bootstrap chef client'\n",
"# Fixup the server URL in client.rb\n",
"s3cmd -c /home/ubuntu/.s3cfg get s3://", { "Ref" : "ChefServerPrivateKeyBucket" }, "/validation.pem /etc/chef/validation.pem > /tmp/get_validation_key.log 2>&1 || error_exit 'Failed to get Chef Server validation key'\n",
"#wget https://s3-ap-northeast-1.amazonaws.com/", { "Ref" : "ChefServerPrivateKeyBucket" }, "/validation.pem -P /etc/chef/ --no-check-certificate || error_exit 'Failed to get Chef Server validation key'\n",
"sed -i 's|http://localhost:4000|", { "Ref" : "ChefServerURL" }, "|g' /etc/chef/client.rb\n",
"echo node_name \\\"`curl http://169.254.169.254/latest/meta-data/instance-id`\\\" >> /etc/chef/client.rb\n",
"#chef-client -j /etc/chef/roles.json > /tmp/initialize_client.log 2>&1 || error_exit 'Failed to initialize host via chef client' \n",
"chef-client -j /etc/chef/roles.json > /tmp/initialize_client.log 2>&1 || echo 'Failed to initialize host via chef client' \n",
"# If all went well, signal success\n",
"cfn-signal -e $? -r 'Chef Server configuration' '", { "Ref" : "WebFpChefClientWaitHandle" }, "'\n"
]]}},
"KeyName": { "Ref": "KeyName" },
"InstanceType": { "Ref": "WebFpInstanceType" }
}
},
"WebFpServerScaleUpPolicy" : {
"Type" : "AWS::AutoScaling::ScalingPolicy",
"Properties" : {
"AdjustmentType" : "ChangeInCapacity",
"AutoScalingGroupName" : { "Ref" : "WebFpServerGroup" },
"Cooldown" : "60",
"ScalingAdjustment" : "1"
}
},
"WebFpServerScaleDownPolicy" : {
"Type" : "AWS::AutoScaling::ScalingPolicy",
"Properties" : {
"AdjustmentType" : "ChangeInCapacity",
"AutoScalingGroupName" : { "Ref" : "WebFpServerGroup" },
"Cooldown" : "60",
"ScalingAdjustment" : "-1"
}
},
"WebFpAutoScalingCPUAlarmHigh": {
"Type": "AWS::CloudWatch::Alarm",
"Properties": {
"AlarmDescription": "Scale-up if CPU > 50% for 10 minutes",
"MetricName": "CPUUtilization",
"Namespace": "AWS/EC2",
"Statistic": "Average",
"Period": "300",
"EvaluationPeriods": "2",
"Threshold": "50",
"AlarmActions": [ { "Ref": "WebFpServerScaleUpPolicy" } ],
"Dimensions": [
{
"Name": "AutoScalingGroupName",
"Value": { "Ref": "WebFpServerGroup" }
}
],
"ComparisonOperator": "GreaterThanThreshold"
}
},
"WebFpAutoScalingCPUAlarmLow": {
"Type": "AWS::CloudWatch::Alarm",
"Properties": {
"AlarmDescription": "Scale-down if CPU < 25% for 10 minutes",
"MetricName": "CPUUtilization",
"Namespace": "AWS/EC2",
"Statistic": "Average",
"Period": "300",
"EvaluationPeriods": "2",
"Threshold": "25",
"AlarmActions": [ { "Ref": "WebFpServerScaleDownPolicy" } ],
"Dimensions": [
{
"Name": "AutoScalingGroupName",
"Value": { "Ref": "WebFpServerGroup" }
}
],
"ComparisonOperator": "LessThanThreshold"
}
},
"WebFpElasticLoadBalancer" : {
"Type" : "AWS::ElasticLoadBalancing::LoadBalancer",
"Properties" : {
"AvailabilityZones" : { "Fn::GetAZs" : "" },
"Listeners" : [ {
"LoadBalancerPort" : "80",
"InstancePort" : "80",
"Protocol" : "HTTP"
} ],
"HealthCheck" : {
"Target" : { "Fn::Join" : [ "", ["HTTP:", "80", "/"]]},
"HealthyThreshold" : "3",
"UnhealthyThreshold" : "5",
"Interval" : "30",
"Timeout" : "5"
}
}
},
"WebFpCPUAlarmHigh": {
"Type" : "AWS::CloudWatch::Alarm",
"Properties": {
"EvaluationPeriods": "10",
"Statistic": "Average",
"Threshold": "70",
"AlarmDescription": "Alarm if CPU too high or metric disappears indicating the WebFpapp instance is having issues",
"Period": "60",
"Namespace": "AWS/EC2",
"MetricName": "CPUUtilization",
"Dimensions": [ {
"Name": "WebFpappInstanceIdentifier",
"Value": { "Ref": "WebFpServerGroup" }
} ],
"ComparisonOperator": "GreaterThanThreshold",
"AlarmActions": [ { "Ref": "AlarmTopic" } ],
"InsufficientDataActions": [ { "Ref": "AlarmTopic" } ]
}
},
"WebFpTooManyUnhealthyHostsAlarm": {
"Properties": {
"EvaluationPeriods": "10",
"Statistic": "Average",
"Threshold": "0",
"AlarmDescription": "Alarm if there are too many unhealthy hosts.",
"Period": "60",
"AlarmActions": [
{
"Ref": "AlarmTopic"
}
],
"Namespace": "AWS/ELB",
"InsufficientDataActions": [
{
"Ref": "AlarmTopic"
}
],
"Dimensions": [
{
"Name": "LoadBalancerName",
"Value": {
"Ref": "WebFpElasticLoadBalancer"
}
}
],
"ComparisonOperator": "GreaterThanThreshold",
"MetricName": "UnHealthyHostCount"
},
"Type": "AWS::CloudWatch::Alarm"
},
"WebFpRequestLatencyAlarmHigh": {
"Properties": {
"EvaluationPeriods": "5",
"Statistic": "Average",
"Threshold": "1",
"AlarmDescription": "Alarm if there aren't any requests coming through",
"Period": "60",
"Namespace": "AWS/ELB",
"MetricName": "Latency",
"ComparisonOperator": "GreaterThanThreshold",
"AlarmActions": [
{
"Ref": "AlarmTopic"
}
],
"Dimensions": [
{
"Name": "LoadBalancerName",
"Value": {
"Ref": "WebFpElasticLoadBalancer"
}
}
]
},
"Type": "AWS::CloudWatch::Alarm"
},
"WebFpTooMany5xxErrAlarm": {
"Properties": {
"EvaluationPeriods": "10",
"Statistic": "Sum",
"Threshold": "100",
"AlarmDescription": "Alarm if there are too many 5xx err.",
"Period": "60",
"AlarmActions": [
{
"Ref": "AlarmTopic"
}
],
"Namespace": "AWS/ELB",
"Dimensions": [
{
"Name": "LoadBalancerName",
"Value": {
"Ref": "WebFpElasticLoadBalancer"
}
}
],
"ComparisonOperator": "GreaterThanThreshold",
"MetricName": "HTTPCode_ELB_5XX"
},
"Type": "AWS::CloudWatch::Alarm"
},
"WebFpTooMany4xxErrAlarm": {
"Properties": {
"EvaluationPeriods": "10",
"Statistic": "Sum",
"Threshold": "100",
"AlarmDescription": "Alarm if there are too many 4xx err.",
"Period": "60",
"AlarmActions": [
{
"Ref": "AlarmTopic"
}
],
"Namespace": "AWS/ELB",
"Dimensions": [
{
"Name": "LoadBalancerName",
"Value": {
"Ref": "WebFpElasticLoadBalancer"
}
}
],
"ComparisonOperator": "GreaterThanThreshold",
"MetricName": "HTTPCode_ELB_4XX"
},
"Type": "AWS::CloudWatch::Alarm"
},
"WebFpEC2SecurityGroup" : {
"Type" : "AWS::EC2::SecurityGroup",
"Properties" : {
"GroupDescription" : "Open up SSH access and HTTP over port 80",
"SecurityGroupIngress" : [
{ "IpProtocol": "tcp", "FromPort": "22", "ToPort": "22", "CidrIp": "0.0.0.0/0" },
{ "IpProtocol": "tcp", "FromPort": "80", "ToPort": "80", "CidrIp": "0.0.0.0/0" }
]
}
},
"WebFpChefClientWaitHandle" : {
"Type" : "AWS::CloudFormation::WaitConditionHandle"
},
"WebFpChefClientWaitCondition" : {
"Type" : "AWS::CloudFormation::WaitCondition",
"DependsOn" : "WebFpServerGroup",
"Properties" : {
"Handle" : { "Ref" : "WebFpChefClientWaitHandle" },
"Timeout" : "1200"
}
},
"WebSpServerGroup" : {
"Type" : "AWS::AutoScaling::AutoScalingGroup",
"DependsOn" : "LogInstance",
"Properties" : {
"AvailabilityZones" : ["ap-northeast-1b"],
"LaunchConfigurationName" : { "Ref" : "WebSpLaunchConfig" },
"MinSize" : "1",
"MaxSize" : "1",
"LoadBalancerNames" : [ { "Ref" : "WebSpElasticLoadBalancer" } ]
}
},
"WebSpLaunchConfig" : {
"Type" : "AWS::AutoScaling::LaunchConfiguration",
"DependsOn" : "BucketPolicy",
"Metadata" : {
"AWS::CloudFormation::Init" : {
"config" : {
"packages" : {
"rubygems" : {
"chef" : []
},
"apt" : {
"ruby1.9.2-full" : [],
"build-essential" : [],
"wget" : [],
"ssl-cert" : [],
"rubygems1.9.1" : [],
"s3cmd" : []
}
},
"files" : {
"/etc/chef/solo.rb" : {
"content" : { "Fn::Join" : ["\n", [
"file_cache_path \"/tmp/chef-solo\"",
"cookbook_path \"/tmp/chef-solo/cookbooks\""
]]},
"mode" : "000644",
"owner" : "root",
"group" : "root"
},
"/etc/chef/chef.json" : {
"content" : {
"chef_client": {
"server_url": { "Ref" : "ChefServerURL" }
},
"run_list": [ "recipe[chef-client::config]", "recipe[chef-client]" ]
},
"mode" : "000644",
"owner" : "root",
"group" : "root"
},
"/etc/profile.d/chefclientenv.sh" : {
"content" : { "Fn::Join" : ["\n", [
"export PATH=$PATH:/var/lib/gems/1.8/bin"
]]},
"mode" : "000644",
"owner" : "root",
"group" : "root"
},
"/etc/chef/roles.json" : {
"content" : {
"run_list": [ "role[spwebapp_server]" ]
},
"mode" : "000644",
"owner" : "root",
"group" : "root"
},
"/home/ubuntu/.s3cfg" : {
"content" : { "Fn::Join" : ["", [
"[default]\n",
"access_key = ", { "Ref" : "HostKeys" }, "\n",
"secret_key = ", {"Fn::GetAtt": ["HostKeys", "SecretAccessKey"]}, "\n",
"use_https = True\n"
]]},
"mode" : "000644",
"owner" : "ubuntu",
"group" : "ubuntu"
},
"/var/lib/gems/1.8/gems/ohai-0.6.4/lib/ohai/plugins/cfn.rb" : {
"source" : { "Fn::Join" : ["", [ { "Ref" : "PackageDownloadURI" }, "/cfn.rb"]]},
"mode" : "000644",
"owner" : "root",
"group" : "root"
}
}
}
}
},
"Properties": {
"SecurityGroups": [ { "Ref" : "WebSpEC2SecurityGroup" }, { "Ref": "ChefServerSecurityGroup" } ],
"ImageId": { "Fn::FindInMap": [ "AWSRegionArch2AMI", { "Ref": "AWS::Region" }, { "Fn::FindInMap": [ "AWSInstanceType2Arch", { "Ref": "WebSpInstanceType" }, "Arch" ] } ]
},
"UserData" : { "Fn::Base64" : { "Fn::Join" : ["", [
"#!/bin/bash -v\n",
"function error_exit\n",
"{\n",
" cfn-signal -e 1 -r \"$1\" '", { "Ref" : "WebSpChefClientWaitHandle" }, "'\n",
" exit 1\n",
"}\n",
"sed -i 's|# deb|deb|g' /etc/apt/sources.list\n",
"apt-get -y update\n",
"apt-get -y install python-setuptools ec2-ami-tools ec2-api-tools ec2-init unzip\n",
"#s3cmd -c /home/ubuntu/.s3cfg get s3://", { "Ref" : "ChefServerPrivateKeyBucket" }, "/aws-cfn-bootstrap-1.0-6.zip > /tmp/get_aws-cnf-bootstrap.log 2>&1 || error_exit 'Failed to get Chef Server validation key'\n",
"wget ", { "Ref" : "PackageDownloadURI" }, "/aws-cfn-bootstrap-1.0-6.zip\n",
"#wget https://s3-ap-northeast-1.amazonaws.com/test-gv-common-chefserverprivatekeybucket/aws-cfn-bootstrap-1.0-6.zip --no-check-certificate\n",
"unzip aws-cfn-bootstrap-1.0-6.zip && cd aws-cfn-bootstrap-1.0 && chmod 755 setup.py && ./setup.py install\n",
"# easy_install https://s3.amazonaws.com/cfn-init-demo/aws-cfn-bootstrap-1.0-6.tar.gz\n",
"cfn-init --region ", { "Ref" : "AWS::Region" },
" -s ", { "Ref" : "AWS::StackName" }, " -r WebSpLaunchConfig ",
" --access-key ", { "Ref" : "HostKeys" },
" --secret-key ", {"Fn::GetAtt": ["HostKeys", "SecretAccessKey"]},
" --region ", { "Ref" : "AWS::Region" }, " || error_exit 'Failed to run cfn-init'\n",
"# Fixup path and links for the bootstrap script\n",
"export PATH=$PATH:/var/lib/gems/1.8/bin || error_exit 'Failed to export PATH gem'\n",
"# Bootstrap chef\n",
"chef-solo -c /etc/chef/solo.rb -j /etc/chef/chef.json -r http://s3.amazonaws.com/chef-solo/bootstrap-latest.tar.gz > /tmp/chef_solo.log 2>&1 || error_exit 'Failed to bootstrap chef client'\n",
"# Fixup the server URL in client.rb\n",
"s3cmd -c /home/ubuntu/.s3cfg get s3://", { "Ref" : "ChefServerPrivateKeyBucket" }, "/validation.pem /etc/chef/validation.pem > /tmp/get_validation_key.log 2>&1 || error_exit 'Failed to get Chef Server validation key'\n",
"#wget https://s3-ap-northeast-1.amazonaws.com/", { "Ref" : "ChefServerPrivateKeyBucket" }, "/validation.pem -P /etc/chef/ --no-check-certificate || error_exit 'Failed to get Chef Server validation key'\n",
"sed -i 's|http://localhost:4000|", { "Ref" : "ChefServerURL" }, "|g' /etc/chef/client.rb\n",
"echo node_name \\\"`curl http://169.254.169.254/latest/meta-data/instance-id`\\\" >> /etc/chef/client.rb\n",
"#chef-client -j /etc/chef/roles.json > /tmp/initialize_client.log 2>&1 || error_exit 'Failed to initialize host via chef client' \n",
"chef-client -j /etc/chef/roles.json > /tmp/initialize_client.log 2>&1 || echo 'Failed to initialize host via chef client' \n",
"# If all went well, signal success\n",
"cfn-signal -e $? -r 'Chef Server configuration' '", { "Ref" : "WebSpChefClientWaitHandle" }, "'\n"
]]}},
"KeyName": { "Ref": "KeyName" },
"InstanceType": { "Ref": "WebSpInstanceType" }
}
},
"WebSpServerScaleUpPolicy" : {
"Type" : "AWS::AutoScaling::ScalingPolicy",
"Properties" : {
"AdjustmentType" : "ChangeInCapacity",
"AutoScalingGroupName" : { "Ref" : "WebSpServerGroup" },
"Cooldown" : "60",
"ScalingAdjustment" : "1"
}
},
"WebSpServerScaleDownPolicy" : {
"Type" : "AWS::AutoScaling::ScalingPolicy",
"Properties" : {
"AdjustmentType" : "ChangeInCapacity",
"AutoScalingGroupName" : { "Ref" : "WebSpServerGroup" },
"Cooldown" : "60",
"ScalingAdjustment" : "-1"
}
},
"WebSpAutoScalingCPUAlarmHigh": {
"Type": "AWS::CloudWatch::Alarm",
"Properties": {
"AlarmDescription": "Scale-up if CPU > 50% for 10 minutes",
"MetricName": "CPUUtilization",
"Namespace": "AWS/EC2",
"Statistic": "Average",
"Period": "300",
"EvaluationPeriods": "2",
"Threshold": "50",
"AlarmActions": [ { "Ref": "WebSpServerScaleUpPolicy" } ],
"Dimensions": [
{
"Name": "AutoScalingGroupName",
"Value": { "Ref": "WebSpServerGroup" }
}
],
"ComparisonOperator": "GreaterThanThreshold"
}
},
"WebSpAutoScalingCPUAlarmLow": {
"Type": "AWS::CloudWatch::Alarm",
"Properties": {
"AlarmDescription": "Scale-down if CPU < 25% for 10 minutes",
"MetricName": "CPUUtilization",
"Namespace": "AWS/EC2",
"Statistic": "Average",
"Period": "300",
"EvaluationPeriods": "2",
"Threshold": "25",
"AlarmActions": [ { "Ref": "WebSpServerScaleDownPolicy" } ],
"Dimensions": [
{
"Name": "AutoScalingGroupName",
"Value": { "Ref": "WebSpServerGroup" }
}
],
"ComparisonOperator": "LessThanThreshold"
}
},
"WebSpElasticLoadBalancer" : {
"Type" : "AWS::ElasticLoadBalancing::LoadBalancer",
"Properties" : {
"AvailabilityZones" : { "Fn::GetAZs" : "" },
"Listeners" : [ {
"LoadBalancerPort" : "80",
"InstancePort" : "80",
"Protocol" : "HTTP"
} ],
"HealthCheck" : {
"Target" : { "Fn::Join" : [ "", ["HTTP:", "80", "/"]]},
"HealthyThreshold" : "3",
"UnhealthyThreshold" : "5",
"Interval" : "30",
"Timeout" : "5"
}
}
},
"WebSpCPUAlarmHigh": {
"Type" : "AWS::CloudWatch::Alarm",
"Properties": {
"EvaluationPeriods": "10",
"Statistic": "Average",
"Threshold": "70",
"AlarmDescription": "Alarm if CPU too high or metric disappears indicating the WebSpapp instance is having issues",
"Period": "60",
"Namespace": "AWS/EC2",
"MetricName": "CPUUtilization",
"Dimensions": [ {
"Name": "WebSpappInstanceIdentifier",
"Value": { "Ref": "WebSpServerGroup" }
} ],
"ComparisonOperator": "GreaterThanThreshold",
"AlarmActions": [ { "Ref": "AlarmTopic" } ],
"InsufficientDataActions": [ { "Ref": "AlarmTopic" } ]
}
},
"WebSpTooManyUnhealthyHostsAlarm": {
"Properties": {
"EvaluationPeriods": "10",
"Statistic": "Average",
"Threshold": "0",
"AlarmDescription": "Alarm if there are too many unhealthy hosts.",
"Period": "60",
"AlarmActions": [
{
"Ref": "AlarmTopic"
}
],
"Namespace": "AWS/ELB",
"InsufficientDataActions": [
{
"Ref": "AlarmTopic"
}
],
"Dimensions": [
{
"Name": "LoadBalancerName",
"Value": {
"Ref": "WebSpElasticLoadBalancer"
}
}
],
"ComparisonOperator": "GreaterThanThreshold",
"MetricName": "UnHealthyHostCount"
},
"Type": "AWS::CloudWatch::Alarm"
},
"WebSpRequestLatencyAlarmHigh": {
"Properties": {
"EvaluationPeriods": "5",
"Statistic": "Average",
"Threshold": "1",
"AlarmDescription": "Alarm if there aren't any requests coming through",
"Period": "60",
"Namespace": "AWS/ELB",
"MetricName": "Latency",
"ComparisonOperator": "GreaterThanThreshold",
"AlarmActions": [
{
"Ref": "AlarmTopic"
}
],
"Dimensions": [
{
"Name": "LoadBalancerName",
"Value": {
"Ref": "WebSpElasticLoadBalancer"
}
}
]
},
"Type": "AWS::CloudWatch::Alarm"
},
"WebSpTooMany5xxErrAlarm": {
"Properties": {
"EvaluationPeriods": "10",
"Statistic": "Sum",
"Threshold": "100",
"AlarmDescription": "Alarm if there are too many 5xx err.",
"Period": "60",
"AlarmActions": [
{
"Ref": "AlarmTopic"
}
],
"Namespace": "AWS/ELB",
"Dimensions": [
{
"Name": "LoadBalancerName",
"Value": {
"Ref": "WebSpElasticLoadBalancer"
}
}
],
"ComparisonOperator": "GreaterThanThreshold",
"MetricName": "HTTPCode_ELB_5XX"
},
"Type": "AWS::CloudWatch::Alarm"
},
"WebSpTooMany4xxErrAlarm": {
"Properties": {
"EvaluationPeriods": "10",
"Statistic": "Sum",
"Threshold": "100",
"AlarmDescription": "Alarm if there are too many 4xx err.",
"Period": "60",
"AlarmActions": [
{
"Ref": "AlarmTopic"
}
],
"Namespace": "AWS/ELB",
"Dimensions": [
{
"Name": "LoadBalancerName",
"Value": {
"Ref": "WebSpElasticLoadBalancer"
}
}
],
"ComparisonOperator": "GreaterThanThreshold",
"MetricName": "HTTPCode_ELB_4XX"
},
"Type": "AWS::CloudWatch::Alarm"
},
"WebSpEC2SecurityGroup" : {
"Type" : "AWS::EC2::SecurityGroup",
"Properties" : {
"GroupDescription" : "Open up SSH access and HTTP over port 80",
"SecurityGroupIngress" : [
{ "IpProtocol": "tcp", "FromPort": "22", "ToPort": "22", "CidrIp": "0.0.0.0/0" },
{ "IpProtocol": "tcp", "FromPort": "80", "ToPort": "80", "CidrIp": "0.0.0.0/0" }
]
}
},
"WebSpChefClientWaitHandle" : {
"Type" : "AWS::CloudFormation::WaitConditionHandle"
},
"WebSpChefClientWaitCondition" : {
"Type" : "AWS::CloudFormation::WaitCondition",
"DependsOn" : "WebSpServerGroup",
"Properties" : {
"Handle" : { "Ref" : "WebSpChefClientWaitHandle" },
"Timeout" : "1200"
}
}
},
"Outputs": {
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment