{
"AWSTemplateFormatVersion": "2010-09-09", "Description": "AWS CloudFormation template to create resources required to run tasks on an ECS cluster.", "Mappings": { "VpcCidrs": { "vpc": {"cidr" : "10.0.0.0/16"}, "pubsubnet1": {"cidr" : "10.0.0.0/24"}, "pubsubnet2": {"cidr" :"10.0.1.0/24"} } }, "Parameters": { "EcsAmiId": { "Type": "String", "Description": "ECS EC2 AMI id", "Default": "" }, "EcsInstanceType": { "Type": "String", "Description": "ECS EC2 instance type", "Default": "t2.micro", "AllowedValues": [ "t2.nano", "t2.micro", "t2.small", "t2.medium", "t2.large", "m3.medium", "m3.large", "m3.xlarge", "m3.2xlarge", "m4.large", "m4.xlarge", "m4.2xlarge", "m4.4xlarge", "m4.10xlarge", "c4.large", "c4.xlarge", "c4.2xlarge", "c4.4xlarge", "c4.8xlarge", "c3.large", "c3.xlarge", "c3.2xlarge", "c3.4xlarge", "c3.8xlarge", "r3.large", "r3.xlarge", "r3.2xlarge", "r3.4xlarge", "r3.8xlarge", "i2.xlarge", "i2.2xlarge", "i2.4xlarge", "i2.8xlarge", "g2.2xlarge", "g2.8xlarge", "d2.xlarge", "d2.2xlarge", "d2.4xlarge", "d2.8xlarge" ], "ConstraintDescription": "must be a valid EC2 instance type." }, "KeyName": { "Type": "AWS::EC2::KeyPair::KeyName", "Description": "Optional - Name of an existing EC2 KeyPair to enable SSH access to the ECS instances", "Default": "" }, "VpcId": { "Type": "String", "Description": "Optional - VPC Id of existing VPC. Leave blank to have a new VPC created", "Default": "", "AllowedPattern": "^(?:vpc-[0-9a-f]{8}|vpc-[0-9a-f]{17}|)$", "ConstraintDescription": "VPC Id must begin with 'vpc-' followed by either an 8 or 17 character identifier, or leave blank to have a new VPC created" }, "SubnetIds": { "Type": "CommaDelimitedList", "Description": "Optional - Comma separated list of two (2) existing VPC Subnet Ids where ECS instances will run. Required if setting VpcId.", "Default": "" }, "AsgMaxSize": { "Type": "Number", "Description": "Maximum size and initial Desired Capacity of ECS Auto Scaling Group", "Default": "1" }, "SecurityGroup": { "Type": "String", "Description": "Optional - Existing security group to associate the container instances. Creates one by default.", "Default": "" }, "SourceCidr": { "Type": "String", "Description": "Optional - CIDR/IP range for EcsPort - defaults to 0.0.0.0/0", "Default": "0.0.0.0/0" }, "EcsPort" : { "Type" : "String", "Description" : "Optional - Security Group port to open on ECS instances - defaults to port 80", "Default" : "80" }, "VpcAvailabilityZones": { "Type": "CommaDelimitedList", "Description": "Optional - Comma-delimited list of VPC availability zones in which to create subnets. Required if setting VpcId.", "Default": "" }, "EcsCluster" : { "Type" : "String", "Description" : "ECS Cluster Name", "Default" : "default" } }, "Conditions": { "CreateVpcResources": { "Fn::Equals": [ { "Ref": "VpcId" }, "" ] }, "CreateSecurityGroup": { "Fn::Equals": [ { "Ref": "SecurityGroup" }, "" ] }, "CreateEC2LCWithKeyPair": { "Fn::Not": [ { "Fn::Equals": [ { "Ref": "KeyName" }, "" ] } ] }, "CreateEC2LCWithoutKeyPair": { "Fn::Equals": [ { "Ref": "KeyName" }, "" ] }, "UseSpecifiedVpcAvailabilityZones": { "Fn::Not": [ { "Fn::Equals": [ { "Fn::Join": [ "", { "Ref": "VpcAvailabilityZones" } ] }, "" ] } ] } }, "Resources": { "Vpc": { "Condition": "CreateVpcResources", "Type": "AWS::EC2::VPC", "Properties": { "CidrBlock": { "Fn::FindInMap": ["VpcCidrs", "vpc", "cidr"] } } }, "PubSubnetAz1": { "Condition": "CreateVpcResources", "Type": "AWS::EC2::Subnet", "Properties": { "VpcId": { "Ref": "Vpc" }, "CidrBlock": { "Fn::FindInMap": ["VpcCidrs", "pubsubnet1", "cidr"] }, "AvailabilityZone": { "Fn::If": [ "UseSpecifiedVpcAvailabilityZones", { "Fn::Select": [ "0", { "Ref": "VpcAvailabilityZones" } ] }, { "Fn::Select": [ "0", { "Fn::GetAZs": { "Ref": "AWS::Region" } } ] } ] } } }, "PubSubnetAz2": { "Condition": "CreateVpcResources", "Type": "AWS::EC2::Subnet", "Properties": { "VpcId": { "Ref": "Vpc" }, "CidrBlock": { "Fn::FindInMap": ["VpcCidrs", "pubsubnet2", "cidr"] }, "AvailabilityZone": { "Fn::If": [ "UseSpecifiedVpcAvailabilityZones", { "Fn::Select": [ "1", { "Ref": "VpcAvailabilityZones" } ] }, { "Fn::Select": [ "1", { "Fn::GetAZs": { "Ref": "AWS::Region" } } ] } ] } } }, "InternetGateway": { "Condition": "CreateVpcResources", "Type": "AWS::EC2::InternetGateway" }, "AttachGateway": { "Condition": "CreateVpcResources", "Type": "AWS::EC2::VPCGatewayAttachment", "Properties": { "VpcId": { "Ref": "Vpc" }, "InternetGatewayId": { "Ref": "InternetGateway" } } }, "RouteViaIgw": { "Condition": "CreateVpcResources", "Type": "AWS::EC2::RouteTable", "Properties": { "VpcId": { "Ref": "Vpc" } } }, "PublicRouteViaIgw": { "Condition": "CreateVpcResources", "DependsOn": "AttachGateway", "Type": "AWS::EC2::Route", "Properties": { "RouteTableId": { "Ref": "RouteViaIgw" }, "DestinationCidrBlock": "0.0.0.0/0", "GatewayId": { "Ref": "InternetGateway" } } }, "PubSubnet1RouteTableAssociation": { "Condition": "CreateVpcResources", "Type": "AWS::EC2::SubnetRouteTableAssociation", "Properties": { "SubnetId": { "Ref": "PubSubnetAz1" }, "RouteTableId": { "Ref": "RouteViaIgw" } } }, "PubSubnet2RouteTableAssociation": { "Condition": "CreateVpcResources", "Type": "AWS::EC2::SubnetRouteTableAssociation", "Properties": { "SubnetId": { "Ref": "PubSubnetAz2" }, "RouteTableId": { "Ref": "RouteViaIgw" } } }, "EcsSecurityGroup": { "Condition": "CreateSecurityGroup", "Type": "AWS::EC2::SecurityGroup", "Properties": { "GroupDescription": "ECS Allowed Ports", "VpcId": { "Fn::If": [ "CreateVpcResources", { "Ref": "Vpc" }, { "Ref": "VpcId" } ] }, "SecurityGroupIngress" : [ { "IpProtocol" : "tcp", "FromPort" : { "Ref" : "EcsPort" }, "ToPort" : { "Ref" : "EcsPort" }, "CidrIp" : { "Ref" : "SourceCidr" } } ] } }, "EcsInstancePolicy": { "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": [ "ec2.amazonaws.com" ] }, "Action": [ "sts:AssumeRole" ] } ] }, "Path": "/", "ManagedPolicyArns": [ "arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role" ] } }, "EcsInstanceProfile": { "Type": "AWS::IAM::InstanceProfile", "Properties": { "Path": "/", "Roles": [ { "Ref": "EcsInstancePolicy" } ] } }, "EcsInstanceLc": { "Condition": "CreateEC2LCWithKeyPair", "Type": "AWS::AutoScaling::LaunchConfiguration", "Properties": { "ImageId": { "Ref" : "EcsAmiId" }, "InstanceType": { "Ref": "EcsInstanceType" }, "AssociatePublicIpAddress": true, "IamInstanceProfile": { "Ref": "EcsInstanceProfile" }, "KeyName": { "Ref": "KeyName" }, "SecurityGroups": { "Fn::If": [ "CreateSecurityGroup", [ { "Ref": "EcsSecurityGroup" } ], [ { "Ref": "SecurityGroup" } ] ] }, "UserData": { "Fn::Base64": { "Fn::Join": [ "", [ "#!/bin/bash\n", "echo ECS_CLUSTER=", { "Ref": "EcsCluster" }, " >> /etc/ecs/ecs.config\n" ] ] } } } }, "EcsInstanceLcWithoutKeyPair": { "Condition": "CreateEC2LCWithoutKeyPair", "Type": "AWS::AutoScaling::LaunchConfiguration", "Properties": { "ImageId": { "Ref" : "EcsAmiId" }, "InstanceType": { "Ref": "EcsInstanceType" }, "AssociatePublicIpAddress": true, "IamInstanceProfile": { "Ref": "EcsInstanceProfile" }, "SecurityGroups": { "Fn::If": [ "CreateSecurityGroup", [ { "Ref": "EcsSecurityGroup" } ], [ { "Ref": "SecurityGroup" } ] ] }, "UserData": { "Fn::Base64": { "Fn::Join": [ "", [ "#!/bin/bash\n", "echo ECS_CLUSTER=", { "Ref": "EcsCluster" }, " >> /etc/ecs/ecs.config\n" ] ] } } } }, "EcsInstanceAsg": { "Type": "AWS::AutoScaling::AutoScalingGroup", "Properties": { "VPCZoneIdentifier": { "Fn::If": [ "CreateVpcResources", [ { "Fn::Join": [ ",", [ { "Ref": "PubSubnetAz1" }, { "Ref": "PubSubnetAz2" } ] ] } ], { "Ref": "SubnetIds" } ] }, "LaunchConfigurationName": { "Fn::If": [ "CreateEC2LCWithKeyPair", { "Ref": "EcsInstanceLc" }, { "Ref": "EcsInstanceLcWithoutKeyPair" } ] }, "MinSize": "1", "MaxSize": { "Ref": "AsgMaxSize" }, "DesiredCapacity": { "Ref": "AsgMaxSize" }, "Tags": [ { "Key": "Name", "Value": { "Fn::Join": [ "", [ "ECS Instance - ", { "Ref": "AWS::StackName" } ] ] }, "PropagateAtLaunch": "true" } ] } } }
}