aws/meme_captain.json
{
"AWSTemplateFormatVersion": "2010-09-09",
"Outputs": {
"dbHost": {
"Value": {
"Fn::GetAtt": [
"database",
"Endpoint.Address"
]
}
}
},
"Parameters": {
"canaryAmi": {
"Type": "String"
},
"dbPassword": {
"NoEcho": "TRUE",
"Type": "String"
},
"dbUser": {
"Type": "String"
},
"onDemandAmi": {
"Type": "String"
},
"spotAmi": {
"Type": "String"
}
},
"Resources": {
"autoScalingTopic": {
"Properties": {
"DisplayName": "autoscaling",
"Subscription": [
{
"Endpoint": "matthewm@boedicker.org",
"Protocol": "email"
}
],
"TopicName": "autoscaling"
},
"Type": "AWS::SNS::Topic"
},
"canaryAutoScalingGroup": {
"Properties": {
"DesiredCapacity": 1,
"HealthCheckGracePeriod": 300,
"HealthCheckType": "ELB",
"LaunchConfigurationName": {
"Ref": "canaryLaunchConfig"
},
"MaxSize": 1,
"MinSize": 1,
"NotificationConfigurations": [
{
"NotificationTypes": [
"autoscaling:EC2_INSTANCE_LAUNCH",
"autoscaling:EC2_INSTANCE_LAUNCH_ERROR",
"autoscaling:EC2_INSTANCE_TERMINATE",
"autoscaling:EC2_INSTANCE_TERMINATE_ERROR"
],
"TopicARN": {
"Ref": "autoScalingTopic"
}
}
],
"Tags": [
{
"Key": "pool",
"PropagateAtLaunch": true,
"Value": "canary"
}
],
"TargetGroupARNs": [
{
"Ref": "elbTargetGroup"
}
],
"VPCZoneIdentifier": [
{
"Ref": "publicSubnet1"
}
]
},
"Type": "AWS::AutoScaling::AutoScalingGroup",
"UpdatePolicy": {
"AutoScalingRollingUpdate": {}
}
},
"canaryLaunchConfig": {
"Properties": {
"AssociatePublicIpAddress": true,
"BlockDeviceMappings": [
{
"DeviceName": "/dev/xvda",
"Ebs": {
"VolumeSize": "16"
}
}
],
"IamInstanceProfile": {
"Ref": "instanceProfile"
},
"ImageId": {
"Ref": "canaryAmi"
},
"InstanceType": "t2.small",
"KeyName": "memecaptain",
"SecurityGroups": [
{
"Ref": "webSecurityGroup"
}
],
"UserData": {
"Fn::Base64": {
"Fn::Join": [
"\n",
[
"#!/bin/bash",
"set -e",
"aws s3 cp s3://memecaptain-secrets/database.yml /database.yml",
"aws s3 cp s3://memecaptain-secrets/env/small.env /env",
"echo canary > /pool",
". /startup"
]
]
}
}
},
"Type": "AWS::AutoScaling::LaunchConfiguration"
},
"cloudFrontLogsBucket": {
"Properties": {
"AccessControl": "Private",
"BucketName": "memecaptain-cloudfront-logs"
},
"Type": "AWS::S3::Bucket"
},
"database": {
"Properties": {
"AllocatedStorage": "10",
"AvailabilityZone": "us-east-1d",
"BackupRetentionPeriod": "1",
"DBInstanceClass": "db.t2.small",
"DBName": "memecaptain",
"DBSubnetGroupName": {
"Ref": "dbSubnetGroup"
},
"Engine": "postgres",
"MasterUserPassword": {
"Ref": "dbPassword"
},
"MasterUsername": {
"Ref": "dbUser"
},
"Tags": [
{
"Key": "Name",
"Value": "memecaptain"
}
],
"VPCSecurityGroups": [
{
"Ref": "dbSecurityGroup"
}
]
},
"Type": "AWS::RDS::DBInstance"
},
"dbFreeStorageLowAlarm": {
"Properties": {
"AlarmActions": [
{
"Ref": "dbTopic"
}
],
"AlarmDescription": "notify if database free storage is < 5G",
"AlarmName": "dbFreeStorageLow",
"ComparisonOperator": "LessThanThreshold",
"Dimensions": [
{
"Name": "DBInstanceIdentifier",
"Value": {
"Ref": "database"
}
}
],
"EvaluationPeriods": "1",
"MetricName": "FreeStorageSpace",
"Namespace": "AWS/RDS",
"Period": "60",
"Statistic": "Minimum",
"Threshold": "5000000000"
},
"Type": "AWS::CloudWatch::Alarm"
},
"dbSecurityGroup": {
"Properties": {
"GroupDescription": "db security group",
"SecurityGroupEgress": [
{
"CidrIp": "0.0.0.0/0",
"FromPort": "1",
"IpProtocol": "tcp",
"ToPort": "65535"
}
],
"SecurityGroupIngress": [
{
"FromPort": "5432",
"IpProtocol": "tcp",
"SourceSecurityGroupId": {
"Ref": "webSecurityGroup"
},
"ToPort": "5432"
}
],
"Tags": [
{
"Key": "Name",
"Value": "db"
}
],
"VpcId": {
"Ref": "vpc"
}
},
"Type": "AWS::EC2::SecurityGroup"
},
"dbSubnetGroup": {
"Properties": {
"DBSubnetGroupDescription": "db subnet group",
"SubnetIds": [
{
"Ref": "privateSubnet1"
},
{
"Ref": "privateSubnet2"
}
]
},
"Type": "AWS::RDS::DBSubnetGroup"
},
"dbTopic": {
"Properties": {
"DisplayName": "db",
"Subscription": [
{
"Endpoint": "matthewm@boedicker.org",
"Protocol": "email"
}
],
"TopicName": "db"
},
"Type": "AWS::SNS::Topic"
},
"elb2": {
"DependsOn": "internetGatewayAttachment",
"Properties": {
"LoadBalancerAttributes": [
{
"Key": "access_logs.s3.enabled",
"Value": true
},
{
"Key": "access_logs.s3.bucket",
"Value": {
"Ref": "elbLogsBucket"
}
}
],
"Name": "memecaptain2",
"SecurityGroups": [
{
"Ref": "elbSecurityGroup"
}
],
"Subnets": [
{
"Ref": "publicSubnet1"
},
{
"Ref": "publicSubnet2"
}
]
},
"Type": "AWS::ElasticLoadBalancingV2::LoadBalancer"
},
"elbCert": {
"Properties": {
"DomainName": "*.memecaptain.com",
"SubjectAlternativeNames": [
"memecaptain.com"
]
},
"Type": "AWS::CertificateManager::Certificate"
},
"elbHttpListener": {
"Properties": {
"DefaultActions": [
{
"TargetGroupArn": {
"Ref": "elbTargetGroup"
},
"Type": "forward"
}
],
"LoadBalancerArn": {
"Ref": "elb2"
},
"Port": 80,
"Protocol": "HTTP"
},
"Type": "AWS::ElasticLoadBalancingV2::Listener"
},
"elbHttpsListener": {
"Properties": {
"Certificates": [
{
"CertificateArn": {
"Ref": "elbCert"
}
}
],
"DefaultActions": [
{
"TargetGroupArn": {
"Ref": "elbTargetGroup"
},
"Type": "forward"
}
],
"LoadBalancerArn": {
"Ref": "elb2"
},
"Port": 443,
"Protocol": "HTTPS"
},
"Type": "AWS::ElasticLoadBalancingV2::Listener"
},
"elbLogsBucket": {
"Properties": {
"AccessControl": "Private",
"BucketName": "memecaptain-elb-logs"
},
"Type": "AWS::S3::Bucket"
},
"elbLogsBucketPolicy": {
"Properties": {
"Bucket": {
"Ref": "elbLogsBucket"
},
"PolicyDocument": {
"Statement": [
{
"Action": [
"s3:PutObject"
],
"Effect": "Allow",
"Principal": {
"AWS": [
"127311923021"
]
},
"Resource": {
"Fn::Join": [
"",
[
"arn:aws:s3:::",
{
"Ref": "elbLogsBucket"
},
"/AWSLogs/165945320610/*"
]
]
}
}
]
}
},
"Type": "AWS::S3::BucketPolicy"
},
"elbSecurityGroup": {
"Properties": {
"GroupDescription": "elb security group",
"SecurityGroupEgress": [
{
"CidrIp": "0.0.0.0/0",
"FromPort": "1",
"IpProtocol": "tcp",
"ToPort": "65535"
}
],
"SecurityGroupIngress": [
{
"CidrIp": "0.0.0.0/0",
"FromPort": "80",
"IpProtocol": "tcp",
"ToPort": "80"
},
{
"CidrIp": "0.0.0.0/0",
"FromPort": "443",
"IpProtocol": "tcp",
"ToPort": "443"
}
],
"Tags": [
{
"Key": "Name",
"Value": "elb"
}
],
"VpcId": {
"Ref": "vpc"
}
},
"Type": "AWS::EC2::SecurityGroup"
},
"elbTargetGroup": {
"Properties": {
"HealthCheckIntervalSeconds": 30,
"HealthCheckPath": "/instance_health",
"HealthCheckPort": "80",
"HealthCheckProtocol": "HTTP",
"HealthCheckTimeoutSeconds": 5,
"HealthyThresholdCount": 4,
"Name": "memecaptain",
"Port": 80,
"Protocol": "HTTP",
"UnhealthyThresholdCount": 2,
"VpcId": {
"Ref": "vpc"
}
},
"Type": "AWS::ElasticLoadBalancingV2::TargetGroup"
},
"imageStoreBucket": {
"Properties": {
"AccessControl": "Private",
"BucketName": "memecaptain-images",
"VersioningConfiguration": {
"Status": "Enabled"
}
},
"Type": "AWS::S3::Bucket"
},
"instanceProfile": {
"Properties": {
"Roles": [
{
"Ref": "instanceRole"
}
]
},
"Type": "AWS::IAM::InstanceProfile"
},
"instanceRole": {
"Properties": {
"AssumeRolePolicyDocument": {
"Statement": [
{
"Action": [
"sts:AssumeRole"
],
"Effect": "Allow",
"Principal": {
"Service": [
"ec2.amazonaws.com"
]
}
}
],
"Version": "2012-10-17"
},
"Path": "/",
"Policies": [
{
"PolicyDocument": {
"Statement": [
{
"Action": [
"s3:ListBucket"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::memecaptain-secrets"
},
{
"Action": [
"s3:GetObject"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::memecaptain-secrets/*"
}
],
"Version": "2012-10-17"
},
"PolicyName": "secretsPolicy"
},
{
"PolicyDocument": {
"Statement": [
{
"Action": [
"s3:CreateMultipartUpload",
"s3:PutObject",
"s3:GetObject"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::memecaptain-images/*"
}
],
"Version": "2012-10-17"
},
"PolicyName": "imageStorePolicy"
}
]
},
"Type": "AWS::IAM::Role"
},
"internetGateway": {
"Type": "AWS::EC2::InternetGateway"
},
"internetGatewayAttachment": {
"Properties": {
"InternetGatewayId": {
"Ref": "internetGateway"
},
"VpcId": {
"Ref": "vpc"
}
},
"Type": "AWS::EC2::VPCGatewayAttachment"
},
"internetGatewayRoute": {
"DependsOn": "internetGatewayAttachment",
"Properties": {
"DestinationCidrBlock": "0.0.0.0/0",
"GatewayId": {
"Ref": "internetGateway"
},
"RouteTableId": {
"Ref": "internetGatewayRouteTable"
}
},
"Type": "AWS::EC2::Route"
},
"internetGatewayRouteTable": {
"Properties": {
"Tags": [
{
"Key": "Name",
"Value": "igw"
}
],
"VpcId": {
"Ref": "vpc"
}
},
"Type": "AWS::EC2::RouteTable"
},
"natRouteTable": {
"Properties": {
"Tags": [
{
"Key": "Name",
"Value": "nat"
}
],
"VpcId": {
"Ref": "vpc"
}
},
"Type": "AWS::EC2::RouteTable"
},
"onDemandAutoScalingGroup": {
"Properties": {
"DesiredCapacity": 0,
"HealthCheckGracePeriod": 300,
"HealthCheckType": "ELB",
"LaunchConfigurationName": {
"Ref": "onDemandLaunchConfig"
},
"MaxSize": 0,
"MinSize": 0,
"NotificationConfigurations": [
{
"NotificationTypes": [
"autoscaling:EC2_INSTANCE_LAUNCH",
"autoscaling:EC2_INSTANCE_LAUNCH_ERROR",
"autoscaling:EC2_INSTANCE_TERMINATE",
"autoscaling:EC2_INSTANCE_TERMINATE_ERROR"
],
"TopicARN": {
"Ref": "autoScalingTopic"
}
}
],
"Tags": [
{
"Key": "pool",
"PropagateAtLaunch": true,
"Value": "ondemand"
}
],
"TargetGroupARNs": [
{
"Ref": "elbTargetGroup"
}
],
"VPCZoneIdentifier": [
{
"Ref": "publicSubnet1"
}
]
},
"Type": "AWS::AutoScaling::AutoScalingGroup",
"UpdatePolicy": {
"AutoScalingRollingUpdate": {}
}
},
"onDemandLaunchConfig": {
"Properties": {
"AssociatePublicIpAddress": true,
"BlockDeviceMappings": [
{
"DeviceName": "/dev/xvda",
"Ebs": {
"VolumeSize": "16"
}
}
],
"IamInstanceProfile": {
"Ref": "instanceProfile"
},
"ImageId": {
"Ref": "onDemandAmi"
},
"InstanceType": "t2.small",
"KeyName": "memecaptain",
"SecurityGroups": [
{
"Ref": "webSecurityGroup"
}
],
"UserData": {
"Fn::Base64": {
"Fn::Join": [
"\n",
[
"#!/bin/bash",
"set -e",
"aws s3 cp s3://memecaptain-secrets/database.yml /database.yml",
"aws s3 cp s3://memecaptain-secrets/env/small.env /env",
"echo ondemand > /pool",
". /startup"
]
]
}
}
},
"Type": "AWS::AutoScaling::LaunchConfiguration"
},
"privateSubnet1": {
"Properties": {
"AvailabilityZone": "us-east-1d",
"CidrBlock": "10.0.2.0/24",
"Tags": [
{
"Key": "Name",
"Value": "private1"
}
],
"VpcId": {
"Ref": "vpc"
}
},
"Type": "AWS::EC2::Subnet"
},
"privateSubnet1RouteTableAssociation": {
"Properties": {
"RouteTableId": {
"Ref": "natRouteTable"
},
"SubnetId": {
"Ref": "privateSubnet1"
}
},
"Type": "AWS::EC2::SubnetRouteTableAssociation"
},
"privateSubnet2": {
"Properties": {
"AvailabilityZone": "us-east-1e",
"CidrBlock": "10.0.3.0/24",
"Tags": [
{
"Key": "Name",
"Value": "private2"
}
],
"VpcId": {
"Ref": "vpc"
}
},
"Type": "AWS::EC2::Subnet"
},
"privateSubnet2RouteTableAssociation": {
"Properties": {
"RouteTableId": {
"Ref": "natRouteTable"
},
"SubnetId": {
"Ref": "privateSubnet2"
}
},
"Type": "AWS::EC2::SubnetRouteTableAssociation"
},
"publicSubnet1": {
"Properties": {
"AvailabilityZone": "us-east-1d",
"CidrBlock": "10.0.0.0/24",
"Tags": [
{
"Key": "Name",
"Value": "public1"
}
],
"VpcId": {
"Ref": "vpc"
}
},
"Type": "AWS::EC2::Subnet"
},
"publicSubnet1RouteTableAssociation": {
"Properties": {
"RouteTableId": {
"Ref": "internetGatewayRouteTable"
},
"SubnetId": {
"Ref": "publicSubnet1"
}
},
"Type": "AWS::EC2::SubnetRouteTableAssociation"
},
"publicSubnet2": {
"Properties": {
"AvailabilityZone": "us-east-1e",
"CidrBlock": "10.0.1.0/24",
"Tags": [
{
"Key": "Name",
"Value": "public2"
}
],
"VpcId": {
"Ref": "vpc"
}
},
"Type": "AWS::EC2::Subnet"
},
"publicSubnet2RouteTableAssociation": {
"Properties": {
"RouteTableId": {
"Ref": "internetGatewayRouteTable"
},
"SubnetId": {
"Ref": "publicSubnet2"
}
},
"Type": "AWS::EC2::SubnetRouteTableAssociation"
},
"s3VPCEndpoint": {
"Properties": {
"RouteTableIds": [
{
"Ref": "internetGatewayRouteTable"
}
],
"ServiceName": "com.amazonaws.us-east-1.s3",
"VpcId": {
"Ref": "vpc"
}
},
"Type": "AWS::EC2::VPCEndpoint"
},
"secretsBucket": {
"Properties": {
"AccessControl": "Private",
"BucketName": "memecaptain-secrets"
},
"Type": "AWS::S3::Bucket"
},
"v1RedirectBucket": {
"Properties": {
"AccessControl": "PublicRead",
"BucketName": "v1.memecaptain.com",
"WebsiteConfiguration": {
"RedirectAllRequestsTo": {
"HostName": "memecaptain.com"
}
}
},
"Type": "AWS::S3::Bucket"
},
"vpc": {
"Properties": {
"CidrBlock": "10.0.0.0/16",
"Tags": [
{
"Key": "Name",
"Value": "memecaptain"
}
]
},
"Type": "AWS::EC2::VPC"
},
"webSecurityGroup": {
"Properties": {
"GroupDescription": "web security group",
"SecurityGroupEgress": [
{
"CidrIp": "0.0.0.0/0",
"FromPort": "1",
"IpProtocol": "tcp",
"ToPort": "65535"
},
{
"CidrIp": "10.0.0.0/24",
"FromPort": "8125",
"IpProtocol": "udp",
"ToPort": "8125"
}
],
"SecurityGroupIngress": [
{
"FromPort": "80",
"IpProtocol": "tcp",
"SourceSecurityGroupId": {
"Ref": "elbSecurityGroup"
},
"ToPort": "80"
}
],
"Tags": [
{
"Key": "Name",
"Value": "web"
}
],
"VpcId": {
"Ref": "vpc"
}
},
"Type": "AWS::EC2::SecurityGroup"
}
}
}