{
	"AWSTemplateFormatVersion": "2010-09-09",
	
	"Description" : "My Stack. Stack description only",
	"Parameters": {
		"DBKeyName": {
			"Description" : "Name of an existing EC2 KeyPair to enable SSH access to the database instance",
			"Type": "String"
		},
		"DBInstanceType": {
			"Default": "t1.micro",
			"Description" : "The type of EC2 instance used for the database server",
			"Type": "String",
			"AllowedPattern" : "[a-zA-Z0-9\\.]+"
		},
		"WebServerKeyName": {
			"Description" : "Name of an existing EC2 KeyPair to enable SSH access to the web server instances",
			"Type": "String"
		},
		"WebServerInstanceType": {
			"Default": "t1.micro",
			"Description" : "The type of EC2 instances used for the web servers",
			"Type": "String",
			"AllowedPattern" : "[a-zA-Z0-9\\.]+"
		},
		"WebServerDefaultGroupSize": {
			"Default": "1",
			"Description" : "The default number of web server EC2 instances",
			"Type": "Number",
			"MinValue": "1"
		},
		"NotificationEmailAddress": {
			"Description": "Email address to notify if there are any operational issues",
			"Type": "String"
		}
	},
	"Mappings" : {
		"AWSInstanceType2Arch" : {
			"t1.micro"    : { "Arch" : "64" },
			"m1.small"    : { "Arch" : "32" },
			"m1.large"    : { "Arch" : "64" },
			"m1.xlarge"   : { "Arch" : "64" },
			"m2.xlarge"   : { "Arch" : "64" },
			"m2.2xlarge"  : { "Arch" : "64" },
			"m2.4xlarge"  : { "Arch" : "64" },
			"c1.medium"   : { "Arch" : "32" },
			"c1.xlarge"   : { "Arch" : "64" },
			"cc1.4xlarge" : { "Arch" : "64" }
		},
		"AWSRegionArch2AMI" : {
			"us-east-1" : { "32" : "ami-ab36fbc2", "64" : "ami-ad36fbc4" },
			"us-west-1" : { "32" : "ami-eb227eae", "64" : "ami-f5227eb0" },
			"us-west-2" : { "32" : "ami-defe73ee", "64" : "ami-c4fe73f4" },
			"eu-west-1" : { "32" : "ami-c00e3cb4", "64" : "ami-cc0e3cb8" },
			"ap-southeast-1" : { "32" : "ami-ea205ab8", "64" : "ami-e8205aba" },
			"ap-northeast-1" : { "32" : "ami-78b40079", "64" : "ami-7ab4007b" }
		}
	},
	"Resources": {
		"DBServer" : {
			"Type" : "AWS::EC2::Instance",
			"Properties" : {
				"KeyName" : { "Ref" : "DBKeyName" },
				"SecurityGroups" : [ { "Ref" : "DBSecurityGroup" } ],
				"InstanceType" : { "Ref": "DBInstanceType" },
				"ImageId" : { "Fn::FindInMap" : [ "AWSRegionArch2AMI", { "Ref" : "AWS::Region" }, { "Fn::FindInMap" : [ "AWSInstanceType2Arch", { "Ref" : "DBInstanceType" }, "Arch" ] } ] },
				"Tags" : [ { "Key" : "Name", "Value" : "Database Server" } ]
			}
		},
		"DBSecurityGroup" : {
			"Type" : "AWS::EC2::SecurityGroup",
			"Properties" : {
				"SecurityGroupIngress" : [
					{
						"FromPort" : "22",
						"CidrIp" : "0.0.0.0/0",
						"ToPort" : "22",
						"IpProtocol" : "tcp"
					},
					{
						"IpProtocol" : "tcp",
						"FromPort" : "3306",
						"ToPort" : "3306",
						"SourceSecurityGroupName" : { "Ref" : "WebServerSecurityGroup" }
					}
				],
				"GroupDescription": "MySQL access from web servers and SSH access to the server"
			}
		},
		"DBServerEIP" : {
			"Type" : "AWS::EC2::EIP",
			"Properties" : {
				"InstanceId" : { "Ref" : "DBServer" }
			}
		},
		"WebServerGroup" : {
			"Type": "AWS::AutoScaling::AutoScalingGroup",
			"DependsOn" : "WebServerLaunchConfig",
			"Properties" : {
				"AvailabilityZones" : { "Fn::GetAZs" : { "Ref" : "AWS::Region" } },
				"DesiredCapacity" : { "Ref": "WebServerDefaultGroupSize" },
				"LaunchConfigurationName": { "Ref" : "WebServerLaunchConfig" },
				"LoadBalancerNames" : [ { "Ref": "WebServerELB" } ],
				"MaxSize" : "4",
				"MinSize" : "1",
				"NotificationConfiguration" : {
					"TopicARN" : { "Ref" : "WebsitesAlarmTopic" },
					"NotificationTypes" : [ "autoscaling:EC2_INSTANCE_LAUNCH",
											"autoscaling:EC2_INSTANCE_LAUNCH_ERROR",
											"autoscaling:EC2_INSTANCE_TERMINATE", 
											"autoscaling:EC2_INSTANCE_TERMINATE_ERROR"]
				}          
			}
		},
		"WebServerLaunchConfig" : {
			"Type": "AWS::AutoScaling::LaunchConfiguration",
			"Properties" : {
				"SecurityGroups" : [ { "Ref": "WebServerSecurityGroup" } ],
				"ImageId" : { "Fn::FindInMap" : [ "AWSRegionArch2AMI", { "Ref" : "AWS::Region" }, { "Fn::FindInMap" : [ "AWSInstanceType2Arch", { "Ref" : "WebServerInstanceType" }, "Arch" ] } ] },
				"KeyName" : { "Ref" : "WebServerKeyName" }, 
				"InstanceType" : { "Ref" : "WebServerInstanceType" }
			}
		},
		"WebServerTrigger" : {
			"Type" : "AWS::AutoScaling::Trigger",
			"Properties" : {
				"MetricName" : "Latency",
				"Namespace" : "AWS/ELB",
				"Statistic" : "Average",
				"Period" : "60",
				"UpperBreachScaleIncrement" : "1",
				"LowerBreachScaleIncrement" : "-1",
				"AutoScalingGroupName" : { "Ref" : "WebServerGroup" },
				"BreachDuration" : "180",
				"UpperThreshold" : "10",
				"LowerThreshold" : "5",
				"Dimensions" : [ { "Name": "LoadBalancerName", "Value": { "Ref": "WebServerELB" } } ]
			}
		},
		"WebServerSecurityGroup" : {
			"Type": "AWS::EC2::SecurityGroup",
			"Properties" : {
				"SecurityGroupIngress" : [
					{
						"FromPort" : "22",
						"CidrIp" : "0.0.0.0/0",
						"ToPort" : "22",
						"IpProtocol" : "tcp"
					},
					{
						"IpProtocol" : "tcp",
						"FromPort" : "80",
						"ToPort" : "80",
						"SourceSecurityGroupOwnerId" : { "Fn::GetAtt" : [ "WebServerELB", "SourceSecurityGroup.OwnerAlias" ] },
						"SourceSecurityGroupName" : { "Fn::GetAtt" : [ "WebServerELB", "SourceSecurityGroup.GroupName" ] }
					}
				],
				"GroupDescription": "HTTP and SSH access to the server"
			}
		},
		"WebServerELB": {
			"Type": "AWS::ElasticLoadBalancing::LoadBalancer",
			"Properties": {
				"Listeners": [
					{
						"InstancePort": "80",
						"Protocol": "HTTP",
						"LoadBalancerPort": "80"
					}
				],
				"HealthCheck" : {
					"HealthyThreshold" : "3",
					"Timeout" : "5",
					"Interval" : "9",
					"UnhealthyThreshold" : "3",
					"Target" : "HTTP:80/index.html"
				},
				"AvailabilityZones": {
					"Fn::GetAZs": {
						"Ref": "AWS::Region"
					}
				}
			}
		},
		"WebsitesAlarmTopic": {
			"Type": "AWS::SNS::Topic",
			"Properties": {
				"Subscription": [
					{
						"Endpoint": { "Ref": "NotificationEmailAddress" },
						"Protocol": "email"
					}
				]
			}
		},
		"DBServerCPUAlarmHigh" : {
			"Type" : "AWS::CloudWatch::Alarm",
			"Properties" : {
				"EvaluationPeriods": "2",
				"Statistic" : "Average",
				"Threshold" : "50",
				"AlarmDescription" : "Alarm if Database Server CPU too high or metric disappears indicating instance is down",
				"Period" : "60",
				"AlarmActions" : [ { "Ref": "WebsitesAlarmTopic" } ],
				"Namespace" : "AWS/EC2",
				"InsufficientDataActions" : [ { "Ref": "WebsitesAlarmTopic" } ],
				"Dimensions" : [ { "Name" : "InstanceId", "Value" : { "Ref" : "DBServer" } } ],
				"ComparisonOperator" : "GreaterThanThreshold",
				"MetricName" : "CPUUtilization"
			}
		},
		"WebServerCPUAlarmHigh" : {
			"Type" : "AWS::CloudWatch::Alarm",
			"Properties" : {
				"EvaluationPeriods": "3",
				"Statistic" : "Average",
				"Threshold" : "50",
				"AlarmDescription" : "Alarm if a Website Server CPU too high or metric disappears indicating instance is down",
				"Period" : "60",
				"AlarmActions" : [ { "Ref": "WebsitesAlarmTopic" } ],
				"Namespace" : "AWS/EC2",
				"InsufficientDataActions" : [ { "Ref": "WebsitesAlarmTopic" } ],        
				"Dimensions" : [ { "Name" : "AutoScalingGroupName", "Value" : { "Ref": "WebServerGroup" } } ],
				"ComparisonOperator": "GreaterThanThreshold",
				"MetricName": "CPUUtilization"
			}
		},
		"TooManyUnhealthyWebServerHostsAlarm": {
			"Type" : "AWS::CloudWatch::Alarm",
			"Properties" : {
				"EvaluationPeriods" : "1",
				"Statistic" : "Average",
				"Threshold" : "0",
				"AlarmDescription" : "Alarm if there are too many unhealthy web server hosts.",
				"Period" : "60",
				"AlarmActions" : [ { "Ref": "WebsitesAlarmTopic" } ],
				"Namespace" : "AWS/ELB",
				"InsufficientDataActions" : [ { "Ref": "WebsitesAlarmTopic" } ],
				"Dimensions" : [ { "Name": "LoadBalancerName", "Value": { "Ref": "WebServerELB" } } ],
				"ComparisonOperator" : "GreaterThanThreshold",
				"MetricName" : "UnHealthyHostCount"
			}
		},
		"WebServerRequestLatencyAlarmHigh": {
			"Type" : "AWS::CloudWatch::Alarm",
			"Properties" : {
				"EvaluationPeriods" : "2",
				"Statistic" : "Average",
				"Threshold" : "10",
				"AlarmDescription" : "Alarm if there aren't any requests coming through",
				"Period" : "60",
				"AlarmActions" : [ { "Ref": "WebsitesAlarmTopic" } ],
				"Namespace" : "AWS/ELB",
				"InsufficientDataActions" : [ { "Ref": "WebsitesAlarmTopic" } ],
				"Dimensions" : [ { "Name": "LoadBalancerName", "Value": { "Ref": "WebServerELB" } } ],
				"ComparisonOperator" : "GreaterThanThreshold",
				"MetricName" : "Latency"
			}
		}
	},
	"Outputs" : {
		"WebServerELBURL" : {
			"Description" : "URL of the web server ELB",
			"Value" :  { "Fn::Join" : [ "", [ "http://", { "Fn::GetAtt" : [ "WebServerELB", "DNSName" ]}]]}
		},
		"DBServerURL" : {
			"Description" : "URL of the DB server URL",
			"Value" :  { "Fn::Join" : [ "", [ "http://", { "Fn::GetAtt" : [ "DBServer", "PublicDnsName" ]}]]}
		},
		"DBServerIP" : {
			"Description" : "URL of the sample website",
			"Value" :  { "Ref" : "DBServerEIP" }
		}
	}
}