Skip to content

Instantly share code, notes, and snippets.

@werdan
Created December 24, 2012 11:31
Show Gist options
  • Save werdan/4368906 to your computer and use it in GitHub Desktop.
Save werdan/4368906 to your computer and use it in GitHub Desktop.
Amazon CloudFormation Template (AutoScaling)
{
"Description" : "ProjectX scalable stack of frontal nodes",
"Parameters" : {
"InstanceType" : {
"Description" : "Type of EC2 instance to launch",
"Type" : "String",
"Default" : "m1.xlarge"
},
"SSHKeyName" : {
"Description" : "The EC2 Key Pair to allow SSH access to the instances",
"Type" : "String",
"Default" : "projectx"
},
"ChefAPIUrl" : {
"Description" : "Chef API Url",
"Type" : "String",
"Default" : "http://my-chefapi.com"
},
"FrontNodePEM" : {
"Description" : "Frontal node client.pem contents with double escaped new lines like \\\\n",
"Type" : "String",
"Default" : "-----BEGIN RSA PRIVATE KEY-----\\nMI...=\\n-----END RSA PRIVATE KEY-----"
},
"FrontNodeName" : {
"Description" : "Frontal node name in chef (node should be already created)",
"Type" : "String",
"Default" : "projectx-live-node"
},
"AWSRegion" : {
"Type" : "String",
"Default" : "eu-west-1"
},
"InstanceName" : {
"Description" : "Logical instance name seen in AWS console",
"Type" : "String",
"Default" : "ProjectX-Live-Node"
},
"AvailabilityZones" : {
"Type" : "CommaDelimitedList",
"Default" : "eu-west-1a"
}
},
"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-b89842d1", "64" : "ami-3c994355" },
"us-west-1" : { "32" : "ami-d5712a90", "64" : "ami-e7712aa2" },
"eu-west-1" : { "32" : "ami-25e8d351", "64" : "ami-3b65664f" }
}
},
"Resources" : {
"NodeGroup" : {
"Type" : "AWS::AutoScaling::AutoScalingGroup",
"Properties" : {
"AvailabilityZones" : {"Ref": "AvailabilityZones"},
"LaunchConfigurationName" : { "Ref" : "LaunchConfig" },
"MinSize" : "1",
"MaxSize" : "2",
"LoadBalancerNames" : [ { "Ref" : "ElasticLoadBalancer" } ],
"Tags" : [
{"Key" : "Client", "Value" : "ProjectX", "PropagateAtLaunch" : "true"},
{"Key" : "Type", "Value" : "Prod", "PropagateAtLaunch" : "true"},
{"Key" : "Use", "Value" : "Web", "PropagateAtLaunch" : "true"},
{"Key" : "Name", "Value" : {"Ref" : "InstanceName"}, "PropagateAtLaunch" : "true"}
]
}
},
"LaunchConfig" : {
"Type" : "AWS::AutoScaling::LaunchConfiguration",
"Properties" : {
"ImageId" : { "Fn::FindInMap" : [ "AWSRegionArch2AMI", { "Ref" : "AWS::Region" },
{ "Fn::FindInMap" : [ "AWSInstanceType2Arch", { "Ref" : "InstanceType" },
"Arch" ] } ] },
"UserData" : { "Fn::Base64" : { "Fn::Join":
[ "", [
"#!/bin/bash\n",
"echo \"deb http://apt.opscode.com/ `lsb_release -cs`-0.10 main\" | sudo tee /etc/apt/sources.list.d/opscode.list\n",
"sudo mkdir -p /etc/apt/trusted.gpg.d\n",
"gpg --keyserver keys.gnupg.net --recv-keys 83EF826A\n",
"gpg --export packages@opscode.com | sudo tee /etc/apt/trusted.gpg.d/opscode-keyring.gpg > /dev/null\n",
"apt-get -y update\n",
"apt-get -y install opscode-keyring\n",
"export DEBIAN_FRONTEND=noninteractive\n",
"apt-get -y upgrade\n",
"echo 'chef chef/chef_server_url string ",
{"Ref" : "ChefAPIUrl"},
"' | debconf-set-selections\n",
"apt-get -y install chef\n",
"echo -e \"", {"Ref": "FrontNodePEM"},"\" > /etc/chef/client.pem\n",
"echo 'node_name \t\"", {"Ref": "FrontNodeName"}, "\"' >> /etc/chef/client.rb\n",
"sudo dd if=/dev/zero of=/mnt/swap bs=1M count=8096\n",
"sudo chmod 600 /mnt/swap\n",
"sudo mkswap /mnt/swap\n",
"sudo swapon /mnt/swap\n",
"/usr/bin/chef-client"
]]
}
},
"SecurityGroups" : [{ "Ref" : "ProjectXNodeSecurityGroup" }],
"InstanceType" : {"Ref" : "InstanceType"},
"KeyName" : {"Ref": "SSHKeyName"}
}
},
"WebServerScaleUpPolicy" : {
"Type" : "AWS::AutoScaling::ScalingPolicy",
"Properties" : {
"AdjustmentType" : "PercentChangeInCapacity",
"AutoScalingGroupName" : { "Ref" : "NodeGroup" },
"Cooldown" : "300",
"ScalingAdjustment" : "100"
}
},
"WebServerScaleDownPolicy" : {
"Type" : "AWS::AutoScaling::ScalingPolicy",
"Properties" : {
"AdjustmentType" : "ChangeInCapacity",
"AutoScalingGroupName" : { "Ref" : "NodeGroup" },
"Cooldown" : "600",
"ScalingAdjustment" : "-1"
}
},
"CPUAlarmHigh": {
"Type": "AWS::CloudWatch::Alarm",
"Properties": {
"AlarmDescription": "Scale-up if CPU > 40% for 10 minutes",
"MetricName": "CPUUtilization",
"Namespace": "AWS/EC2",
"Statistic": "Average",
"Period": "120",
"EvaluationPeriods": "5",
"Threshold": "40",
"AlarmActions": [ { "Ref": "WebServerScaleUpPolicy" } ],
"Dimensions": [
{
"Name": "AutoScalingGroupName",
"Value": { "Ref": "NodeGroup" }
}
],
"ComparisonOperator": "GreaterThanThreshold"
}
},
"CPUAlarmLow": {
"Type": "AWS::CloudWatch::Alarm",
"Properties": {
"AlarmDescription": "Scale-down if CPU <20% for 60 min",
"MetricName": "CPUUtilization",
"Namespace": "AWS/EC2",
"Statistic": "Average",
"Period": "120",
"EvaluationPeriods": "30",
"Threshold": "20",
"AlarmActions": [ { "Ref": "WebServerScaleDownPolicy" } ],
"Dimensions": [
{
"Name": "AutoScalingGroupName",
"Value": { "Ref": "NodeGroup" }
}
],
"ComparisonOperator": "LessThanThreshold"
}
},
"ElasticLoadBalancer" : {
"Type" : "AWS::ElasticLoadBalancing::LoadBalancer",
"Properties" : {
"AvailabilityZones" : {"Ref": "AvailabilityZones"},
"Listeners" : [ {
"LoadBalancerPort" : "80",
"InstancePort" : "80",
"Protocol" : "HTTP"
} ],
"HealthCheck" : {
"Target" : { "Fn::Join" : [ "", ["HTTP:", "80", "/healthchecker.php"]]},
"HealthyThreshold" : "10",
"UnhealthyThreshold" : "5",
"Interval" : "20",
"Timeout" : "10"
}
}
},
"ProjectXNodeSecurityGroup" : {
"Type" : "AWS::EC2::SecurityGroup",
"Properties" : {
"GroupDescription" : "Enable SSH access and HTTP access on the inbound port",
"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" }
]
}
}
},
"Outputs" : {
"URL" : {
"Description" : "The URL of the website",
"Value" : { "Fn::Join" : [ "", [ "http://", { "Fn::GetAtt" : [ "ElasticLoadBalancer", "DNSName" ]}]]}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment