Skip to content

Instantly share code, notes, and snippets.

@dblooman
Created August 11, 2016 22:22
Show Gist options
  • Save dblooman/caa8b04c3df4e19d9edbb37e545e56ff to your computer and use it in GitHub Desktop.
Save dblooman/caa8b04c3df4e19d9edbb37e545e56ff to your computer and use it in GitHub Desktop.
{
"AWSTemplateFormatVersion": "2010-09-09",
"Parameters": {
"CPUAlarmHighEvalPeriods": {
"Type": "String",
"Default": "1"
},
"CPUAlarmHighThreshold": {
"Type": "String",
"Default": "80"
},
"CPUAlarmLowThreshold": {
"Type": "String",
"Default": "60"
},
"CPUAlarmLowEvalPeriods": {
"Type": "String",
"Default": "5"
},
"AlarmPeriod": {
"Type": "String",
"Default": "60"
},
"ELBConnectionDraining": {
"Type": "String",
"Description": "Connection draining ensures that the load balancer completes serving all in-flight requests made to a registered instance when the instance is deregistered or becomes unhealthy",
"Default": 30
},
"HealthCheckGracePeriod": {
"Type": "String",
"Description": "The length of time in seconds after a new EC2 instance comes into service that Auto Scaling starts checking its health.",
"Default": 600
},
"ImageId": {
"Type": "String",
"Default": "ami-bff32ccc"
},
"InstanceType": {
"Type": "String",
"Description": "The size of the instances",
"Default": "t2.micro"
},
"KeyName": {
"Type": "String",
"Default": "mykeypair"
},
"MaxSize": {
"Type": "String",
"Description": "The maximum number of instances",
"Default": 2
},
"MinSize": {
"Type": "String",
"Description": "The minimum number of instances",
"Default": 1
},
"PublicSubnet1Id": {
"Type": "String",
"Default": "subnet-"
},
"PublicSubnet2Id": {
"Type": "String",
"Default": "subnet-"
},
"PublicSubnet3Id": {
"Type": "String",
"Default": "subnet-"
},
"UpdateMaxBatchSize": {
"Type": "String",
"Description": "The maximum number of instances to be killed at one time during an ASG update.",
"Default": 1
},
"UpdateMinInService": {
"Type": "String",
"Description": "The minimum number of instances in service during an ASG update.",
"Default": 1
},
"UpdatePauseTime": {
"Type": "String",
"Description": "The time to wait between new instances coming online and the next batch being killed during an ASG update.",
"Default": "PT0S"
},
"VpcId": {
"Type": "String",
"Default": "vpc-"
}
},
"Resources": {
"ComponentAutoScalingGroup": {
"Type": "AWS::AutoScaling::AutoScalingGroup",
"UpdatePolicy": {
"AutoScalingRollingUpdate": {
"MinInstancesInService": {
"Ref": "UpdateMinInService"
},
"MaxBatchSize": {
"Ref": "UpdateMaxBatchSize"
},
"PauseTime": {
"Ref": "UpdatePauseTime"
}
}
},
"Properties": {
"LoadBalancerNames": [
{
"Ref": "ComponentElasticLoadBalancer"
}
],
"MinSize": {
"Ref": "MinSize"
},
"MaxSize": {
"Ref": "MaxSize"
},
"LaunchConfigurationName": {
"Ref": "ComponentLaunchConfiguration"
},
"AvailabilityZones": [
"eu-west-1a",
"eu-west-1b",
"eu-west-1c"
],
"HealthCheckType": "ELB",
"HealthCheckGracePeriod": {
"Ref": "HealthCheckGracePeriod"
}
}
},
"ComponentLaunchConfiguration": {
"Type": "AWS::AutoScaling::LaunchConfiguration",
"Properties": {
"KeyName": {
"Ref": "KeyName"
},
"SecurityGroups": [
{
"Ref": "ComponentSecurityGroup"
}
],
"InstanceType": {
"Ref": "InstanceType"
},
"IamInstanceProfile": {
"Ref": "ComponentInstanceProfile"
},
"ImageId": {
"Ref": "ImageId"
},
"UserData": {
"Fn::Base64": {
"Fn::Join": [
"",
[
"#cloud-config",
"\n",
"runcmd:\n",
"- yum update -y\n",
"- yum install epel-release -y\n",
"- yum install docker -y \n",
"- service docker start\n",
"- docker pull davey/hello\n",
"- docker run -d -p 8080:9292 davey/hello\n"
]
]
}
}
}
},
"ComponentScaleUpPolicy": {
"Type": "AWS::AutoScaling::ScalingPolicy",
"Properties": {
"AutoScalingGroupName": {
"Ref": "ComponentAutoScalingGroup"
},
"AdjustmentType": "ChangeInCapacity",
"Cooldown": 240,
"ScalingAdjustment": 1
}
},
"ComponentScaleDownPolicy": {
"Type": "AWS::AutoScaling::ScalingPolicy",
"Properties": {
"AutoScalingGroupName": {
"Ref": "ComponentAutoScalingGroup"
},
"AdjustmentType": "ChangeInCapacity",
"Cooldown": 60,
"ScalingAdjustment": -1
}
},
"CPUAlarmHigh": {
"Type": "AWS::CloudWatch::Alarm",
"Properties": {
"AlarmDescription": "Scale-up if CPU > 80% for 1 minutes",
"Threshold": {
"Ref": "CPUAlarmHighThreshold"
},
"AlarmActions": [
{
"Ref": "ComponentScaleUpPolicy"
}
],
"ComparisonOperator": "GreaterThanThreshold",
"EvaluationPeriods": {
"Ref": "CPUAlarmHighEvalPeriods"
},
"MetricName": "CPUUtilization",
"Namespace": "AWS/EC2",
"Statistic": "Average",
"Period": {
"Ref": "AlarmPeriod"
},
"Dimensions": [
{
"Name": "AutoScalingGroupName",
"Value": {
"Ref": "ComponentAutoScalingGroup"
}
}
]
}
},
"CPUAlarmLow": {
"Type": "AWS::CloudWatch::Alarm",
"Properties": {
"AlarmDescription": "Scale-down if CPU < 60% for 5 minutes",
"Threshold": {
"Ref": "CPUAlarmLowThreshold"
},
"AlarmActions": [
{
"Ref": "ComponentScaleDownPolicy"
}
],
"ComparisonOperator": "LessThanThreshold",
"EvaluationPeriods": {
"Ref": "CPUAlarmLowEvalPeriods"
},
"MetricName": "CPUUtilization",
"Namespace": "AWS/EC2",
"Statistic": "Average",
"Period": {
"Ref": "AlarmPeriod"
},
"Dimensions": [
{
"Name": "AutoScalingGroupName",
"Value": {
"Ref": "ComponentAutoScalingGroup"
}
}
]
}
},
"LoadBalancerSecurityGroup": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"SecurityGroupIngress": [
{
"ToPort": 8080,
"IpProtocol": "tcp",
"FromPort": 8080,
"CidrIp": "0.0.0.0/0"
}
],
"VpcId": {
"Ref": "VpcId"
},
"GroupDescription": "An ELB group allowing access only to from the corresponding component"
}
},
"ComponentSecurityGroup": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"SecurityGroupIngress": [
{
"FromPort": 8080,
"ToPort": 8080,
"IpProtocol": "tcp",
"SourceSecurityGroupId": {
"Ref": "LoadBalancerSecurityGroup"
}
}
],
"VpcId": {
"Ref": "VpcId"
},
"GroupDescription": "A component security group allowing access only from the corresponding ELB"
}
},
"ELBRule": {
"Type": "AWS::ElasticLoadBalancingV2::ListenerRule",
"Properties": {
"Actions": [
{
"TargetGroupArn": {
"Ref": "ELBTargetGroup"
},
"Type": "forward"
}
],
"Conditions": [
{
"Field": "path-pattern"
}
],
"ListenerArn": {
"Ref": "ELBListen"
},
"Priority": 1
}
},
"ELBListen": {
"Type": "AWS::ElasticLoadBalancingV2::Listener",
"Properties": {
"DefaultActions": [
{
"TargetGroupArn": {
"Ref": "ELBTargetGroup"
},
"Type": "forward"
}
],
"LoadBalancerArn": {
"Ref": "ComponentElasticLoadBalancer"
},
"Port": 8080,
"Protocol": "HTTP"
}
},
"ELBTargetGroup": {
"Type": "AWS::ElasticLoadBalancingV2::TargetGroup",
"Properties": {
"HealthCheckIntervalSeconds": "15",
"HealthCheckPath": "/status",
"HealthCheckPort": "8080",
"HealthCheckProtocol": "HTTP",
"HealthCheckTimeoutSeconds": 300,
"HealthyThresholdCount": 3,
"Port": 8080,
"Protocol": "HTTP",
"Targets": [
{
"Ref": "ComponentAutoScalingGroup"
}
],
"UnhealthyThresholdCount": 5,
"VpcId": {
"Ref": "VpcId"
}
}
},
"ComponentElasticLoadBalancer": {
"Type": "AWS::ElasticLoadBalancingV2::LoadBalancer",
"Properties": {
"Name": "ALB",
"Subnets": [
{
"Ref": "PublicSubnet1Id"
},
{
"Ref": "PublicSubnet2Id"
},
{
"Ref": "PublicSubnet3Id"
}
],
"SecurityGroups": [
{
"Ref": "LoadBalancerSecurityGroup"
}
]
}
},
"ComponentInstanceProfile": {
"Type": "AWS::IAM::InstanceProfile",
"Properties": {
"Path": "/",
"Roles": [
{
"Ref": "DefaultRole"
}
]
}
},
"EC2ComponentPolicy": {
"Type": "AWS::IAM::Policy",
"Properties": {
"PolicyDocument": {
"Statement": [
{
"Action": [
"cloudwatch:*"
],
"Resource": [
"*"
],
"Effect": "Allow"
},
{
"Action": [
"cloudformation:Describe*"
],
"Resource": [
"*"
],
"Effect": "Allow"
},
{
"Action": [
"ec2:Describe*"
],
"Resource": [
"*"
],
"Effect": "Allow"
}
]
},
"PolicyName": "EC2ComponentPolicy",
"Roles": [
{
"Ref": "DefaultRole"
}
]
}
},
"DefaultRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"Path": "/",
"AssumeRolePolicyDocument": {
"Statement": [
{
"Action": [
"sts:AssumeRole"
],
"Effect": "Allow",
"Principal": {
"Service": [
"ec2.amazonaws.com"
]
}
}
]
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment