Skip to content

Instantly share code, notes, and snippets.

@mojodna
Created April 30, 2015 03:51
Show Gist options
  • Save mojodna/327ed929a31a4eb978a4 to your computer and use it in GitHub Desktop.
Save mojodna/327ed929a31a4eb978a4 to your computer and use it in GitHub Desktop.
CloudFormation template for Toner. Includes hard-coded VPC (and security group?) ids, so not drop-in for others.
{
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "Toner",
"Parameters": {
"TonerVersion": {
"Description": "Toner image version",
"Type": "String",
"AllowedPattern": "v?\\d+\\.\\d+\\.\\d+"
},
"NaturalEarthVersion": {
"Description": "Data image version",
"Type": "String",
"AllowedPattern": "v?\\d+\\.\\d+\\.\\d+"
},
"DatabaseURL": {
"Description": "Database URL",
"Type": "String",
"AllowedPattern": "postgres://.+",
"NoEcho": true
},
"QuayAuth": {
"Description": "Quay.io token",
"Type": "String",
"NoEcho": true
},
"SentryDSN": {
"Description": "Sentry DSN",
"Type": "String",
"NoEcho": true
}
},
"Resources": {
"ELB": {
"Type": "AWS::ElasticLoadBalancing::LoadBalancer",
"Properties": {
"Subnets": [
"subnet-419c4018",
"subnet-c49426b3"
],
"HealthCheck": {
"HealthyThreshold": "2",
"Interval": "30",
"Target": "HTTP:80/toner/index.json",
"Timeout": "5",
"UnhealthyThreshold": "3"
},
"SecurityGroups": [
{
"Ref": "ELBSecurityGroup"
}
],
"Listeners": [
{
"InstancePort": "80",
"LoadBalancerPort": "80",
"Protocol": "HTTP",
"InstanceProtocol": "HTTP"
}
]
}
},
"AutoScalingGroup": {
"Type": "AWS::AutoScaling::AutoScalingGroup",
"CreationPolicy": {
"ResourceSignal": {
"Timeout": "PT15M",
"Count": "3"
}
},
"UpdatePolicy": {
"AutoScalingScheduledAction": {
"IgnoreUnmodifiedGroupSizeProperties": "true"
},
"AutoScalingRollingUpdate": {
"MaxBatchSize": "1",
"MinInstancesInService": "1",
"PauseTime": "PT15M",
"WaitOnResourceSignals": "true"
}
},
"Properties": {
"AvailabilityZones": [
"us-east-1c",
"us-east-1d"
],
"Cooldown": "300",
"DesiredCapacity": "3",
"MaxSize": "5",
"MinSize": "2",
"HealthCheckGracePeriod": "300",
"HealthCheckType": "EC2",
"VPCZoneIdentifier": [
"subnet-419c4018",
"subnet-c49426b3"
],
"NotificationConfiguration": {
"TopicARN": "arn:aws:sns:us-east-1:207818873931:toner",
"NotificationTypes": [
"autoscaling:EC2_INSTANCE_LAUNCH",
"autoscaling:EC2_INSTANCE_LAUNCH_ERROR",
"autoscaling:EC2_INSTANCE_TERMINATE",
"autoscaling:EC2_INSTANCE_TERMINATE_ERROR"
]
},
"LaunchConfigurationName": {
"Ref": "LaunchConfiguration"
},
"LoadBalancerNames": [
{
"Ref": "ELB"
}
],
"Tags": [
{
"Key": "client",
"Value": "cloudatlas",
"PropagateAtLaunch": true
},
{
"Key": "Name",
"Value": {
"Fn::Join": [
"",
[
"toner ",
{
"Ref": "TonerVersion"
},
" / ",
{
"Ref": "NaturalEarthVersion"
}
]
]
},
"PropagateAtLaunch": true
}
]
}
},
"LaunchConfiguration": {
"Type": "AWS::AutoScaling::LaunchConfiguration",
"Properties": {
"ImageId": "ami-705d3d18",
"InstanceType": "c3.xlarge",
"KeyName": "stamen-keypair",
"InstanceMonitoring": "true",
"SecurityGroups": [
"sg-a3e604c7",
{
"Ref": "SecurityGroup"
}
],
"UserData": {
"Fn::Base64": {
"Fn::Join": [
"",
[
"#cloud-config\n",
"\n",
"coreos:\n",
" update:\n",
" reboot-strategy: off\n",
" units:\n",
" - name: toner.service\n",
" command: start\n",
" content: |\n",
" [Unit]\n",
" Description=Toner\n",
" After=docker.service\n",
" Requires=docker.service\n",
"\n",
" [Service]\n",
" User=core\n",
" TimeoutStartSec=0\n",
" Restart=always\n",
" ExecStartPre=-/usr/bin/docker kill toner\n",
" ExecStartPre=-/usr/bin/docker kill data\n",
" ExecStartPre=-/usr/bin/docker rm toner\n",
" ExecStartPre=-/usr/bin/docker rm -v data\n",
" ExecStartPre=-/usr/bin/docker pull quay.io/stamen/toner-data:",
{
"Ref": "NaturalEarthVersion"
},
"\n",
" ExecStartPre=-/usr/bin/docker pull quay.io/stamen/toner:",
{
"Ref": "TonerVersion"
},
"\n",
" ExecStartPre=-/usr/bin/docker pull quay.io/mojodna/awscli\n",
" ExecStartPre=/usr/bin/docker run --name data quay.io/stamen/toner-data:",
{
"Ref": "NaturalEarthVersion"
},
"\n",
" ExecStart=/usr/bin/docker run -p 80:8080 --volumes-from data -e UV_THREADPOOL_SIZE=10 -e DATABASE_URL=",
{
"Ref": "DatabaseURL"
},
" -e SENTRY_DSN=",
{
"Ref": "SentryDSN"
},
" --rm --name toner quay.io/stamen/toner:",
{
"Ref": "TonerVersion"
},
"\n",
" ExecStartPost=-/usr/bin/docker run --rm quay.io/mojodna/awscli cfn-signal --stack ",
{
"Ref": "AWS::StackName"
},
" --resource AutoScalingGroup --region ",
{
"Ref": "AWS::Region"
},
"\n",
" ExecStop=/usr/bin/docker kill toner\n",
" ExecStop=/usr/bin/docker kill data\n",
"\n",
"write_files:\n",
" - path: /home/core/.dockercfg\n",
" owner: core:core\n",
" permissions: 0644\n",
" content: |\n",
" {\n",
" \"quay.io\": {\n",
" \"auth\": \"",
{
"Ref": "QuayAuth"
},
"\",\n",
" \"email\": \"\"\n",
" }\n",
" }\n"
]
]
}
}
}
},
"SecurityGroup": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"GroupDescription": "Toner render nodes",
"VpcId": "vpc-6f9a0a0a",
"SecurityGroupIngress": [
{
"IpProtocol": "tcp",
"FromPort": "80",
"ToPort": "80",
"SourceSecurityGroupId": {
"Ref": "ELBSecurityGroup"
}
}
],
"SecurityGroupEgress": [
{
"IpProtocol": "-1",
"CidrIp": "0.0.0.0/0"
}
]
}
},
"ELBSecurityGroup": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"GroupDescription": "Toner ELB",
"VpcId": "vpc-6f9a0a0a",
"SecurityGroupIngress": [
{
"IpProtocol": "tcp",
"FromPort": "80",
"ToPort": "80",
"CidrIp": "0.0.0.0/0"
}
],
"SecurityGroupEgress": [
{
"IpProtocol": "-1",
"CidrIp": "0.0.0.0/0"
}
]
}
},
"alarmTonerCPU20": {
"Type": "AWS::CloudWatch::Alarm",
"Properties": {
"AlarmDescription": "Toner: CPU > 20%",
"ActionsEnabled": "true",
"ComparisonOperator": "GreaterThanThreshold",
"EvaluationPeriods": "1",
"MetricName": "CPUUtilization",
"Namespace": "AWS/EC2",
"Period": "300",
"Statistic": "Average",
"Threshold": "20.0",
"OKActions": [
"arn:aws:sns:us-east-1:207818873931:toner"
],
"Dimensions": [
{
"Name": "AutoScalingGroupName",
"Value": {
"Ref": "AutoScalingGroup"
}
}
]
}
},
"alarmTonerCPUCreditBalance20": {
"Type": "AWS::CloudWatch::Alarm",
"Properties": {
"AlarmDescription": "Toner: credits < 20",
"ActionsEnabled": "true",
"ComparisonOperator": "LessThanThreshold",
"EvaluationPeriods": "1",
"MetricName": "CPUCreditBalance",
"Namespace": "AWS/EC2",
"Period": "300",
"Statistic": "Minimum",
"Threshold": "20.0",
"OKActions": [
"arn:aws:sns:us-east-1:207818873931:toner"
],
"Dimensions": [
{
"Name": "AutoScalingGroupName",
"Value": {
"Ref": "AutoScalingGroup"
}
}
]
}
},
"alarmTonerCPUCreditBalance10": {
"Type": "AWS::CloudWatch::Alarm",
"Properties": {
"AlarmDescription": "Toner: credits < 10",
"ActionsEnabled": "true",
"ComparisonOperator": "LessThanOrEqualToThreshold",
"EvaluationPeriods": "1",
"MetricName": "CPUCreditBalance",
"Namespace": "AWS/EC2",
"Period": "300",
"Statistic": "Minimum",
"Threshold": "10.0",
"AlarmActions": [
"arn:aws:sns:us-east-1:207818873931:toner"
],
"Dimensions": [
{
"Name": "AutoScalingGroupName",
"Value": {
"Ref": "AutoScalingGroup"
}
}
]
}
},
"alarmTonerCPUUsage50": {
"Type": "AWS::CloudWatch::Alarm",
"Properties": {
"AlarmDescription": "Toner: CPU > 50%",
"ActionsEnabled": "true",
"ComparisonOperator": "GreaterThanThreshold",
"EvaluationPeriods": "1",
"MetricName": "CPUUtilization",
"Namespace": "AWS/EC2",
"Period": "300",
"Statistic": "Average",
"Threshold": "50.0",
"AlarmActions": [
"arn:aws:sns:us-east-1:207818873931:toner"
],
"Dimensions": [
{
"Name": "AutoScalingGroupName",
"Value": {
"Ref": "AutoScalingGroup"
}
}
]
}
}
},
"Outputs": {
"LoadBalancer": {
"Value": {
"Fn::GetAtt": [
"ELB",
"DNSName"
]
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment