Created
April 25, 2016 19:52
-
-
Save nicl/34517e25fba0939a0f1419d4d0fbbeb8 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"AWSTemplateFormatVersion": "2010-09-09", | |
"Description": "Top Secret stack", | |
"Parameters": { | |
"Name": { | |
"Description": "Name of the service", | |
"Type": "String" | |
}, | |
"VpcId": { | |
"Description": "ID of the VPC onto which to launch the application eg. vpc-1234abcd", | |
"Type": "String" | |
}, | |
"PrivateVpcSubnets": { | |
"Description": "Subnets to use in VPC for public internet-facing ELB eg. subnet-abcd1234", | |
"Type": "CommaDelimitedList" | |
}, | |
"PublicVpcSubnets": { | |
"Description": "Subnets to use in VPC for public internet-facing ELB eg. subnet-abcd1234", | |
"Type": "CommaDelimitedList" | |
}, | |
"SSLCert": { | |
"Description": "ARN of valid SSL certificate", | |
"Type": "String" | |
}, | |
"AMI": { | |
"Description": "EC2 AMI ID", | |
"Type": "String" | |
}, | |
"InstanceType": { | |
"Description": "EC2 instance type (m3.large, etc.)", | |
"Type": "String" | |
}, | |
"SshKey": { | |
"Description": "Key for ssh access to EC2 instances", | |
"Type": "String" | |
}, | |
"AlarmSNS": { | |
"Description": "ARN for an SNS topic, used to send Cloudwatch alerts for any alarms", | |
"Type": "String" | |
} | |
}, | |
"Resources": { | |
"InstanceProfile": { | |
"Type": "AWS::IAM::InstanceProfile", | |
"Properties": { | |
"Path": "/", | |
"Roles": [ | |
{ | |
"Ref": "Role" | |
} | |
] | |
} | |
}, | |
"Role": { | |
"Type": "AWS::IAM::Role", | |
"Properties": { | |
"AssumeRolePolicyDocument": { | |
"Version": "2012-10-17", | |
"Statement": [ | |
{ | |
"Effect": "Allow", | |
"Principal": { | |
"Service": [ | |
"ec2.amazonaws.com" | |
] | |
}, | |
"Action": [ | |
"sts:AssumeRole" | |
] | |
} | |
] | |
}, | |
"Path": "/", | |
"Policies": [ | |
{ | |
"PolicyName": "TopSecretPolicy", | |
"PolicyDocument": { | |
"Statement": [ | |
{ | |
"Resource": [ | |
{ "Ref": "DynamoTable" }, | |
{ "Fn::Join": [ "", [ { "Ref": "DynamoTable" },"/index/*"] ] } | |
], | |
"Action": [ "dynamodb:*" ], | |
"Effect": "Allow" | |
}, | |
] | |
} | |
} | |
] | |
} | |
}, | |
"DynamoTable": { | |
"Type": "AWS::DynamoDB::Table", | |
"Properties": { | |
"AttributeDefinitions": [ | |
{ | |
"AttributeName": "Id", | |
"AttributeType": "S" | |
} | |
], | |
"GlobalSecondaryIndexes": [ | |
{ | |
"IndexName": "my-secondary-index", | |
"Projection": { | |
"ProjectionType": "ALL" | |
}, | |
"KeySchema": [ | |
{ | |
"KeyType": "HASH", | |
"AttributeName": "Id" | |
}, | |
{ | |
"KeyType": "RANGE", | |
"AttributeName": "LastModified" | |
} | |
], | |
"ProvisionedThroughput" : { | |
"ReadCapacityUnits" : 1, | |
"WriteCapacityUnits" : 1 | |
} | |
} | |
], | |
"KeySchema": [ | |
{ | |
"AttributeName": "Id", | |
"KeyType": "HASH" | |
} | |
], | |
"LocalSecondaryIndexes": [ ], | |
"ProvisionedThroughput": { | |
"WriteCapacityUnits": 1, | |
"ReadCapacityUnits": 1 | |
}, | |
"TableName": { "Ref": "Name" } | |
} | |
"ElasticLoadBalancer": { | |
"Type": "AWS::ElasticLoadBalancing::LoadBalancer", | |
"Properties": { | |
"CrossZone": true, | |
"Listeners": [ | |
{ | |
"Protocol": "HTTPS", | |
"LoadBalancerPort": "443", | |
"InstancePort": "8080", | |
"SSLCertificateId": { "Ref": "SSLCert" } | |
} | |
], | |
"HealthCheck": { | |
"Target": "HTTP:8080/healthcheck", | |
"Timeout": "10", | |
"Interval": "20", | |
"UnhealthyThreshold": "10", | |
"HealthyThreshold": "2" | |
}, | |
"Subnets": { | |
"Ref": "PublicVpcSubnets" | |
}, | |
"SecurityGroups": [ | |
{ | |
"Ref": "ElasticLoadBalancerSecurityGroup" | |
} | |
] | |
} | |
}, | |
"AppServerGroup": { | |
"Type": "AWS::AutoScaling::AutoScalingGroup", | |
"Properties": { | |
"AvailabilityZones": { | |
"Fn::GetAZs": "" | |
}, | |
"VPCZoneIdentifier": { | |
"Ref": "PrivateVpcSubnets" | |
}, | |
"LaunchConfigurationName": { | |
"Ref": "LaunchConfig" | |
}, | |
"MinSize": 1 | |
"MaxSize": 2, | |
"HealthCheckType": "ELB", | |
"HealthCheckGracePeriod": 300, | |
"LoadBalancerNames": [ {"Ref": "ElasticLoadBalancer"}], | |
"Tags": [ | |
{ | |
"Key": "Name", | |
"Value": {"Ref": "Name"}, | |
"PropagateAtLaunch": "true" | |
} | |
] | |
} | |
}, | |
"LaunchConfig": { | |
"Type": "AWS::AutoScaling::LaunchConfiguration", | |
"Properties": { | |
"ImageId": { "Ref": "AMI" }, | |
"SecurityGroups": [ { "Ref": "AppSecurityGroup" } ], | |
"InstanceType": { "Ref": "InstanceType" }, | |
"IamInstanceProfile": { "Ref": "InstanceProfile" }, | |
"KeyName": { "Ref": "SshKey" }, | |
"UserData": { | |
"Fn::Base64": { | |
"Fn::Join": [ "\n", [ | |
"#!/bin/bash -v", | |
"# any (bash) commands to execute on instance startup", | |
"# you could also download or execute any other scripts here", | |
"# you might need to dl the code deploy code here (I'm not sure how it works)" | |
] ] | |
} | |
} | |
} | |
}, | |
"ElasticLoadBalancerSecurityGroup": { | |
"Type": "AWS::EC2::SecurityGroup", | |
"Properties": { | |
"GroupDescription": "Allow public access over HTTP(S)", | |
"VpcId": { | |
"Ref": "VpcId" | |
}, | |
"SecurityGroupIngress": [ | |
{ | |
"IpProtocol": "tcp", | |
"FromPort": "80", | |
"ToPort": "80", | |
"CidrIp": "0.0.0.0/0" | |
}, | |
{ | |
"IpProtocol": "tcp", | |
"FromPort": "443", | |
"ToPort": "443", | |
"CidrIp": "0.0.0.0/0" | |
} | |
], | |
"SecurityGroupEgress": [ | |
{ | |
"IpProtocol": "tcp", | |
"FromPort": "8080", | |
"ToPort": "8080", | |
"CidrIp": "0.0.0.0/0" | |
} | |
] | |
} | |
}, | |
"AppSecurityGroup": { | |
"Type": "AWS::EC2::SecurityGroup", | |
"Properties": { | |
"GroupDescription": "SSH and HTTP", | |
"VpcId": { "Ref": "VpcId" }, | |
"SecurityGroupIngress": [ | |
{ | |
"IpProtocol": "tcp", | |
"FromPort": "8080", | |
"ToPort": "8080", | |
"SourceSecurityGroupId": { | |
"Ref": "ElasticLoadBalancerSecurityGroup" | |
} | |
}, | |
{ | |
"IpProtocol": "tcp", | |
"FromPort": "22", | |
"ToPort": "22", | |
"CidrIp": "0.0.0.0/0" | |
} | |
] | |
} | |
}, | |
"HighLatencyAlarmAlert": { | |
"Type": "AWS::CloudWatch::Alarm", | |
"Properties": { | |
"AlarmName": { "Fn::Join": ["-", [ { "Ref": "Name"}, "alarm", "latency", "alert" ] ]}, | |
"AlarmDescription": "Average latency is >= 3s for a 3 minute period", | |
"Namespace": "AWS/ELB", | |
"Dimensions": [ { "Name": "LoadBalancerName", "Value": { "Ref": "ElasticLoadBalancer" } } ], | |
"MetricName": "Latency", | |
"Statistic": "Average", | |
"ComparisonOperator": "GreaterThanOrEqualToThreshold", | |
"Threshold": "3", | |
"Period": "60", | |
"EvaluationPeriods": "3", | |
"AlarmActions": { "Ref": "AlarmSNS" } | |
} | |
}, | |
"High5xxAlarmAlert": { | |
"Type": "AWS::CloudWatch::Alarm", | |
"Properties": { | |
"AlarmName": { "Fn::Join": ["-", [ { "Ref": "Name"}, { "Ref": "Stage" }, "alarm", "5xx", "alert" ] ]}, | |
"AlarmDescription": "Number of 5XXs is >= 100 for a 1 minute period", | |
"Namespace": "AWS/ELB", | |
"Dimensions": [ { "Name": "LoadBalancerName", "Value": { "Ref": "ElasticLoadBalancer" } } ], | |
"MetricName": "HTTPCode_Backend_5XX", | |
"Statistic": "Sum", | |
"ComparisonOperator": "GreaterThanOrEqualToThreshold", | |
"Threshold": "100", | |
"Period": "60", | |
"EvaluationPeriods": "1", | |
"AlarmActions": { "Ref": "AlarmSNS" } | |
} | |
} | |
}, | |
"Outputs": { | |
"ElasticLoadBalancer": { | |
"Value": { "Fn::GetAtt": [ "ElasticLoadBalancer", "DNSName" ] } | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This link will help telling you what properties you can use:
http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-template-resource-type-ref.html
Also worth checking out the available functions in cloudformation:
http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference.html
More generally check out the left-hand-side menu bar for useful info.