production.jsonΒΆ

{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Description": "My static webapp production stack",
  "Resources": {
    "LoadBalancer": {
      "Type": "AWS::ElasticLoadBalancing::LoadBalancer",
      "Properties": {
        "HealthCheck": {
          "HealthyThreshold": "2",
          "Interval": "30",
          "Target": "HTTP:80/",
          "Timeout": "5",
          "UnhealthyThreshold": "2"
        },
        "Listeners": [
          {
            "InstancePort": "80",
            "PolicyNames": [],
            "LoadBalancerPort": "80",
            "Protocol": "HTTP",
            "InstanceProtocol": "HTTP"
          }
        ],
        "AvailabilityZones": [
          "us-east-1a",
          "us-east-1d",
          "us-east-1e"
        ]
      }
    },
    "ELBSecurityGroup": {
      "Type": "AWS::EC2::SecurityGroup",
      "Properties": {
        "GroupDescription": "allow traffic from our app servers to the load balancer"
      }
    },
    "ELBSecurityGroupIngressHTTP": {
      "Type": "AWS::EC2::SecurityGroupIngress",
      "Properties": {
        "FromPort": "80",
        "GroupName": {
          "Ref": "ELBSecurityGroup"
        },
        "SourceSecurityGroupOwnerId": {
          "Fn::GetAtt": [
            "LoadBalancer",
            "SourceSecurityGroup.OwnerAlias"
          ]
        },
        "SourceSecurityGroupName": {
          "Fn::GetAtt": [
            "LoadBalancer",
            "SourceSecurityGroup.GroupName"
          ]
        },
        "ToPort": "80",
        "IpProtocol": "tcp"
      }
    },
    "SSHSecurityGroup": {
      "Type": "AWS::EC2::SecurityGroup",
      "Properties": {
        "SecurityGroupIngress": {
          "ToPort": "22",
          "IpProtocol": "tcp",
          "FromPort": "22",
          "CidrIp": "0.0.0.0/0"
        },
        "GroupDescription": "allows inbound SSH from all"
      }
    },
    "AppServerAutoScalingGroup": {
      "Type": "AWS::AutoScaling::AutoScalingGroup",
      "Properties": {
        "MinSize": 4,
        "Tags": [
          {
            "PropagateAtLaunch": true,
            "Value": "production-static-app-server",
            "Key": "Name"
          }
        ],
        "MaxSize": 100,
        "HealthCheckGracePeriod": 300,
        "LaunchConfigurationName": {
          "Ref": "AppServerAutoScalingLaunchConfig"
        },
        "AvailabilityZones": [
          "us-east-1a",
          "us-east-1d",
          "us-east-1e"
        ],
        "LoadBalancerNames": [
          {
            "Ref": "LoadBalancer"
          }
        ],
        "HealthCheckType": "ELB"
      }
    },
    "AppServerAutoScalingLaunchConfig": {
      "Type": "AWS::AutoScaling::LaunchConfiguration",
      "Properties": {
        "UserData": {
          "Fn::Base64": {
            "Fn::Join": [
              "\n",
              [
                "#!/bin/bash -v",
                "# do stuff...",
                "# ",
                "# Like maybe kick off cfnbootstrap, using all of the",
                "# AWS:CloudFormation::Init Metadata That we could have",
                "# put on our AutoScalingGroup",
                "exit 0"
              ]
            ]
          }
        },
        "KeyName": "production",
        "SecurityGroups": [
          {
            "Ref": "ELBSecurityGroup"
          },
          {
            "Ref": "SSHSecurityGroup"
          }
        ],
        "InstanceType": "m1.large",
        "ImageId": "ami-c30360aa"
      }
    },
    "AppServerScaleUpPolicy": {
      "Type": "AWS::AutoScaling::ScalingPolicy",
      "Properties": {
        "ScalingAdjustment": "1",
        "Cooldown": "600",
        "AutoScalingGroupName": {
          "Ref": "AppServerAutoScalingGroup"
        },
        "AdjustmentType": "ChangeInCapacity"
      }
    },
    "AppServerScaleDownPolicy": {
      "Type": "AWS::AutoScaling::ScalingPolicy",
      "Properties": {
        "ScalingAdjustment": "-1",
        "Cooldown": "600",
        "AutoScalingGroupName": {
          "Ref": "AppServerAutoScalingGroup"
        },
        "AdjustmentType": "ChangeInCapacity"
      }
    },
    "AppServerCPUAlarmHigh": {
      "Type": "AWS::CloudWatch::Alarm",
      "Properties": {
        "Dimensions": [
          {
            "Name": "AutoScalingGroupName",
            "Value": {
              "Ref": "AppServerAutoScalingGroup"
            }
          }
        ],
        "Namespace": "AWS/EC2",
        "ActionsEnabled": true,
        "MetricName": "CPUUtilization",
        "EvaluationPeriods": "5",
        "AlarmActions": [
          {
            "Ref": "AppServerScaleUpPolicy"
          }
        ],
        "AlarmDescription": "Scale up if average CPU usage of the AppServers stays above 75% for at least 5 minutes",
        "Period": "60",
        "ComparisonOperator": "GreaterThanThreshold",
        "Statistic": "Average",
        "Threshold": "75",
        "Unit": "Percent"
      }
    },
    "AppServerCPUAlarmLow": {
      "Type": "AWS::CloudWatch::Alarm",
      "Properties": {
        "Dimensions": [
          {
            "Name": "AutoScalingGroupName",
            "Value": {
              "Ref": "AppServerAutoScalingGroup"
            }
          }
        ],
        "Namespace": "AWS/EC2",
        "ActionsEnabled": true,
        "MetricName": "CPUUtilization",
        "EvaluationPeriods": "5",
        "AlarmActions": [
          {
            "Ref": "AppServerScaleUpPolicy"
          }
        ],
        "AlarmDescription": "Scale down if average CPU usage of the AppServers stays below 25% for at least 5 minutes",
        "Period": "60",
        "ComparisonOperator": "LessThanThreshold",
        "Statistic": "Average",
        "Threshold": "25",
        "Unit": "Percent"
      }
    }
  },
  "Outputs": {
    "LoadBalancerEndpoint": {
      "Value": {
        "Fn::GetAtt": [
          "LoadBalancer",
          "DNSName"
        ]
      }
    }
  }
}