{	"AWSTemplateFormatVersion": "2010-09-09",

	"Description": "CloudFormation template to launch a highly available ArcGIS Server stack in Amazon VPC",

	"Parameters" : {
		"AMI" : {
			"Description" : "Your ArcGIS Server AMI ID.",
			"Type" : "String"
		},
		"VpcId" : {
		  "Type" : "AWS::EC2::VPC::Id",
		  "Description" : "VpcId of your existing Virtual Private Cloud (VPC)",
		  "ConstraintDescription" : "must be the VPC Id of an existing Virtual Private Cloud."
		},
		"Subnets" : {
		  "Type" : "List<AWS::EC2::Subnet::Id>",
		  "Description" : "The list of SubnetIds in your Virtual Private Cloud (VPC)",
		  "ConstraintDescription" : "must be a list of an existing subnets in the selected Virtual Private Cloud."
		},
		"AZs" : {
		  "Type" : "List<String>",
		  "Description" : "The list of AvailabilityZones for your Virtual Private Cloud (VPC)",
		  "ConstraintDescription" : "must be a list if valid EC2 availability zones for the selected Virtual Private Cloud"
		},
		"InstanceType" : {
			"Description" : "EC2 instance type, e.g. m3.medium, m3.large, etc.",
			"Type" : "String",
			"Default" : "m3.medium"
		},
		 "KeyName": {
			  "Description" : "Name of an existing EC2 KeyPair to enable remote access to the instance",
			  "Type": "AWS::EC2::KeyPair::KeyName",
			  "ConstraintDescription" : "must be the name of an existing EC2 KeyPair."
		},
		"MinSize" : {
			"Description" : "Minimum number of EC2 instances.",
			"Type" : "Number",
			"Default" : "2"
		},
		"MaxSize" : {
			"Description" : "Maximum number of EC2 instances.",
			"Type" : "Number",
			"Default" : "4"
		}
	},

	"Resources": {
		
		"LoadBalancerSecurityGroup": {
			"Type": "AWS::EC2::SecurityGroup",
			"Properties": {
				"GroupDescription": "Enable HTTP access on port 80 and 443.",
				"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"
				                         }]
						  }
			},
		"ELB" : {
			"Type" : "AWS::ElasticLoadBalancing::LoadBalancer",
			"Properties" : {
				"CrossZone" : "true",
				"Subnets" : { "Ref" : "Subnets" },
				"SecurityGroups" : [ { "Ref" : "LoadBalancerSecurityGroup" } ],				
				"Listeners" : [ {
					"LoadBalancerPort" : "80",
					"InstancePort" : "6080" ,
					"Protocol" : "HTTP"
				}],
				"HealthCheck" : {
					"Target" : "HTTP:6080/arcgis/rest/info/healthcheck",
					"HealthyThreshold" : "3",
					"UnhealthyThreshold" : "10",
					"Interval" : "30",
					"Timeout" : "5"
				}
			}
		},
		
		"InstanceSecurityGroup": {
			"Type": "AWS::EC2::SecurityGroup",
			"Properties": {
				"GroupDescription": "Enable HTTP access on 6080 and 6443 from ELB.",
				"VpcId" : { "Ref" : "VpcId" },
				"SecurityGroupIngress": [{
				                        	 "IpProtocol": "tcp",
				                        	 "FromPort": "6080" ,
				                        	 "ToPort": "6080" ,
											 "SourceSecurityGroupId": { "Ref" : "LoadBalancerSecurityGroup" }
				                         },{
				                        	 "IpProtocol": "tcp",
				                        	 "FromPort": "6443" ,
				                        	 "ToPort": "6443" ,
				                        	 "SourceSecurityGroupId": { "Ref" : "LoadBalancerSecurityGroup" }
				                         }]
			}
		},
		
		"LaunchConfig": {
			"Type": "AWS::AutoScaling::LaunchConfiguration",
			"Properties": {
				"ImageId": {"Ref" : "AMI"},
				"InstanceType": {"Ref": "InstanceType"},
				"KeyName": {"Ref": "KeyName"},
				"SecurityGroups": [{"Ref": "InstanceSecurityGroup"}],
				"InstanceMonitoring": true
			}
		},
		
		"AutoScalingGroup": {
			"Type": "AWS::AutoScaling::AutoScalingGroup",
			"Properties": {
				"AvailabilityZones" : { "Ref" : "AZs" },
				"VPCZoneIdentifier" : { "Ref" : "Subnets" },				
				"LaunchConfigurationName": {"Ref": "LaunchConfig"},
                "Cooldown": "300",
				"MaxSize": {"Ref" : "MaxSize"},
				"MinSize": {"Ref" : "MinSize"},
				"HealthCheckType" : "EC2",
                "HealthCheckGracePeriod" : "3600",
				"LoadBalancerNames": [{"Ref": "ELB"}],
				"Tags": [{"Key": "Name", "Value": {"Ref": "AWS::StackName"}, "PropagateAtLaunch" : true}]
			},
				"UpdatePolicy" : {
					"AutoScalingRollingUpdate" : {
						"MinInstancesInService" : "1",
						"MaxBatchSize" : "1",
						"PauseTime" : "PT15M"					
				}
			}
		},
		"ScaleUpPolicy" : {
			"Type" : "AWS::AutoScaling::ScalingPolicy",
			"Properties" : {
				"AdjustmentType" : "ChangeInCapacity",
				"AutoScalingGroupName" : { "Ref" : "AutoScalingGroup" },
				"Cooldown" : "60",
				"ScalingAdjustment" : "1"
			}
		},

		"ScaleDownPolicy" : {
			"Type" : "AWS::AutoScaling::ScalingPolicy",
			"Properties" : {
				"AdjustmentType" : "ChangeInCapacity",
				"AutoScalingGroupName" : { "Ref" : "AutoScalingGroup" },
				"Cooldown" : "60",
				"ScalingAdjustment" : "-1"
			}
		},

		"CPUAlarmHigh": {
			"Type": "AWS::CloudWatch::Alarm",
			"Properties": {
				"AlarmDescription": "Scale-up if CPU > 80% for 10 minutes",
				"MetricName": "CPUUtilization",
				"Namespace": "AWS/EC2",
				"Statistic": "Average",
				"Period": "300",
				"EvaluationPeriods": "2",
				"Threshold": "80",
				"AlarmActions": [ { "Ref": "ScaleUpPolicy" } ],
				"Dimensions": [
				               {
				            	   "Name": "AutoScalingGroupName",
				            	   "Value": { "Ref": "AutoScalingGroup" }
				               }
				               ],
				               "ComparisonOperator": "GreaterThanThreshold"
			}
		},

		"CPUAlarmLow": {
			"Type": "AWS::CloudWatch::Alarm",
			"Properties": {
				"AlarmDescription": "Scale-down if CPU < 20% for 10 minutes",
				"MetricName": "CPUUtilization",
				"Namespace": "AWS/EC2",
				"Statistic": "Average",
				"Period": "300",
				"EvaluationPeriods": "2",
				"Threshold": "20",
				"AlarmActions": [ { "Ref": "ScaleDownPolicy" } ],
				"Dimensions": [
				               {
				            	   "Name": "AutoScalingGroupName",
				            	   "Value": { "Ref": "AutoScalingGroup" }
				               }
				               ],
				               "ComparisonOperator": "LessThanThreshold"
			}
		}
	},

	"Outputs": {
		"RestURL": {
			"Value": {
				"Fn::Join": ["", ["http://", {"Fn::GetAtt": ["ELB", "DNSName" ]}, "/arcgis/rest"]]
			},
			"Description" : "ArcGIS Server REST Services Directory URL"
		}
	}   

}