Skip to content

Instantly share code, notes, and snippets.

@tkawachi
Created October 28, 2018 03:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tkawachi/a4803e3782c660c343317b3509faa173 to your computer and use it in GitHub Desktop.
Save tkawachi/a4803e3782c660c343317b3509faa173 to your computer and use it in GitHub Desktop.
AWSTemplateFormatVersion: '2010-09-09'
Description: >
AWS CloudFormation template to create a new VPC
or use an existing VPC for ECS deployment
in Create Cluster Wizard. Requires exactly 3
Instance Types for a Spot Request.
Parameters:
EcsClusterName:
Type: String
Description: >
Specifies the ECS Cluster Name with which the resources would be
associated
Default: default
EcsAmiId:
Type: String
Description: Specifies the AMI ID for your container instances.
EcsInstanceType:
Type: CommaDelimitedList
Description: >
Specifies the EC2 instance type for your container instances.
Defaults to m4.large
Default: m4.large
ConstraintDescription: must be a valid EC2 instance type.
KeyName:
Type: String
Description: >
Optional - Specifies the name of an existing Amazon EC2 key pair
to enable SSH access to the EC2 instances in your cluster.
Default: ''
VpcId:
Type: String
Description: >
Optional - Specifies the ID of an existing VPC in which to launch
your container instances. If you specify a VPC ID, you must specify a list of
existing subnets in that VPC. If you do not specify a VPC ID, a new VPC is created
with atleast 1 subnet.
Default: ''
ConstraintDescription: >
VPC Id must begin with 'vpc-' or leave blank to have a
new VPC created
SubnetIds:
Type: CommaDelimitedList
Description: >
Optional - Specifies the Comma separated list of existing VPC Subnet
Ids where ECS instances will run
Default: ''
SecurityGroupId:
Type: String
Description: >
Optional - Specifies the Security Group Id of an existing Security
Group. Leave blank to have a new Security Group created
Default: ''
VpcCidr:
Type: String
Description: Optional - Specifies the CIDR Block of VPC
Default: ''
SubnetCidr1:
Type: String
Description: Specifies the CIDR Block of Subnet 1
Default: ''
SubnetCidr2:
Type: String
Description: Specifies the CIDR Block of Subnet 2
Default: ''
SubnetCidr3:
Type: String
Description: Specifies the CIDR Block of Subnet 3
Default: ''
AsgMaxSize:
Type: Number
Description: >
Specifies the number of instances to launch and register to the cluster.
Defaults to 1.
Default: '1'
IamRoleInstanceProfile:
Type: String
Description: >
Specifies the Name or the Amazon Resource Name (ARN) of the instance
profile associated with the IAM role for the instance
SecurityIngressFromPort:
Type: Number
Description: >
Optional - Specifies the Start of Security Group port to open on
ECS instances - defaults to port 0
Default: '0'
SecurityIngressToPort:
Type: Number
Description: >
Optional - Specifies the End of Security Group port to open on ECS
instances - defaults to port 65535
Default: '65535'
SecurityIngressCidrIp:
Type: String
Description: >
Optional - Specifies the CIDR/IP range for Security Ports - defaults
to 0.0.0.0/0
Default: 0.0.0.0/0
EcsEndpoint:
Type: String
Description: >
Optional - Specifies the ECS Endpoint for the ECS Agent to connect to
Default: ''
VpcAvailabilityZones:
Type: CommaDelimitedList
Description: >
Specifies a comma-separated list of 3 VPC Availability Zones for
the creation of new subnets. These zones must have the available status.
Default: ''
EbsVolumeSize:
Type: Number
Description: >
Optional - Specifies the Size in GBs, of the newly created Amazon
Elastic Block Store (Amazon EBS) volume
Default: '0'
EbsVolumeType:
Type: String
Description: Optional - Specifies the Type of (Amazon EBS) volume
Default: ''
AllowedValues:
- ''
- standard
- io1
- gp2
- sc1
- st1
ConstraintDescription: Must be a valid EC2 volume type.
DeviceName:
Type: String
Description: Optional - Specifies the device mapping for the Volume
UseSpot:
Type: String
Default: 'false'
IamSpotFleetRoleArn:
Type: String
Default: ''
SpotPrice:
Type: String
Default: ''
SpotAllocationStrategy:
Type: String
Default: 'diversified'
AllowedValues:
- 'lowestPrice'
- 'diversified'
UserData:
Type: String
IsWindows:
Type: String
Default: 'false'
Conditions:
CreateEC2LCWithKeyPair:
!Not [!Equals [!Ref KeyName, '']]
SetEndpointToECSAgent:
!Not [!Equals [!Ref EcsEndpoint, '']]
CreateNewSecurityGroup:
!Equals [!Ref SecurityGroupId, '']
CreateNewVpc:
!Equals [!Ref VpcId, '']
CreateSubnet1: !And
- !Not [!Equals [!Ref SubnetCidr1, '']]
- !Condition CreateNewVpc
CreateSubnet2: !And
- !Not [!Equals [!Ref SubnetCidr2, '']]
- !Condition CreateSubnet1
CreateSubnet3: !And
- !Not [!Equals [!Ref SubnetCidr3, '']]
- !Condition CreateSubnet2
CreateWithSpot: !Equals [!Ref UseSpot, 'true']
CreateWithASG: !Not [!Condition CreateWithSpot]
CreateWithSpotPrice: !Not [!Equals [!Ref SpotPrice, '']]
Resources:
Vpc:
Condition: CreateSubnet1
Type: AWS::EC2::VPC
Properties:
CidrBlock: !Ref VpcCidr
EnableDnsSupport: 'true'
EnableDnsHostnames: 'true'
PubSubnetAz1:
Condition: CreateSubnet1
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref Vpc
CidrBlock: !Ref SubnetCidr1
AvailabilityZone: !Select [ 0, !Ref VpcAvailabilityZones ]
MapPublicIpOnLaunch: true
PubSubnetAz2:
Condition: CreateSubnet2
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref Vpc
CidrBlock: !Ref SubnetCidr2
AvailabilityZone: !Select [ 1, !Ref VpcAvailabilityZones ]
MapPublicIpOnLaunch: true
PubSubnetAz3:
Condition: CreateSubnet3
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref Vpc
CidrBlock: !Ref SubnetCidr3
AvailabilityZone: !Select [ 2, !Ref VpcAvailabilityZones ]
MapPublicIpOnLaunch: true
InternetGateway:
Condition: CreateSubnet1
Type: AWS::EC2::InternetGateway
AttachGateway:
Condition: CreateSubnet1
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId: !Ref Vpc
InternetGatewayId: !Ref InternetGateway
RouteViaIgw:
Condition: CreateSubnet1
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref Vpc
PublicRouteViaIgw:
Condition: CreateSubnet1
Type: AWS::EC2::Route
DependsOn: AttachGateway
Properties:
RouteTableId: !Ref RouteViaIgw
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref InternetGateway
PubSubnet1RouteTableAssociation:
Condition: CreateSubnet1
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PubSubnetAz1
RouteTableId: !Ref RouteViaIgw
PubSubnet2RouteTableAssociation:
Condition: CreateSubnet2
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PubSubnetAz2
RouteTableId: !Ref RouteViaIgw
PubSubnet3RouteTableAssociation:
Condition: CreateSubnet3
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PubSubnetAz3
RouteTableId: !Ref RouteViaIgw
EcsSecurityGroup:
Condition: CreateNewSecurityGroup
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: ECS Allowed Ports
VpcId: !If [ CreateSubnet1, !Ref Vpc, !Ref VpcId ]
SecurityGroupIngress:
IpProtocol: tcp
FromPort: !Ref SecurityIngressFromPort
ToPort: !Ref SecurityIngressToPort
CidrIp: !Ref SecurityIngressCidrIp
EcsInstanceLc:
Type: AWS::AutoScaling::LaunchConfiguration
Condition: CreateWithASG
Properties:
ImageId: !Ref EcsAmiId
InstanceType: !Select [ 0, !Ref EcsInstanceType ]
AssociatePublicIpAddress: true
IamInstanceProfile: !Ref IamRoleInstanceProfile
KeyName: !If [ CreateEC2LCWithKeyPair, !Ref KeyName, !Ref "AWS::NoValue" ]
SecurityGroups: [ !If [ CreateNewSecurityGroup, !Ref EcsSecurityGroup, !Ref SecurityGroupId ] ]
BlockDeviceMappings:
- DeviceName: !Ref DeviceName
Ebs:
VolumeSize: !Ref EbsVolumeSize
VolumeType: !Ref EbsVolumeType
UserData:
Fn::Base64: !Ref UserData
EcsInstanceAsg:
Type: AWS::AutoScaling::AutoScalingGroup
Condition: CreateWithASG
Properties:
VPCZoneIdentifier: !If
- CreateSubnet1
- !If
- CreateSubnet2
- !If
- CreateSubnet3
- [ !Sub "${PubSubnetAz1}, ${PubSubnetAz2}, ${PubSubnetAz3}" ]
- [ !Sub "${PubSubnetAz1}, ${PubSubnetAz2}" ]
- [ !Sub "${PubSubnetAz1}" ]
- !Ref SubnetIds
LaunchConfigurationName: !Ref EcsInstanceLc
MinSize: '0'
MaxSize: !Ref AsgMaxSize
DesiredCapacity: !Ref AsgMaxSize
Tags:
-
Key: Name
Value: !Sub "ECS Instance - ${AWS::StackName}"
PropagateAtLaunch: 'true'
-
Key: Description
Value: "This instance is the part of the Auto Scaling group which was created through ECS Console"
PropagateAtLaunch: 'true'
EcsSpotFleet:
Condition: CreateWithSpot
Type: AWS::EC2::SpotFleet
Properties:
SpotFleetRequestConfigData:
AllocationStrategy: !Ref SpotAllocationStrategy
IamFleetRole: !Ref IamSpotFleetRoleArn
TargetCapacity: !Ref AsgMaxSize
SpotPrice: !If [ CreateWithSpotPrice, !Ref SpotPrice, !Ref 'AWS::NoValue' ]
TerminateInstancesWithExpiration: true
LaunchSpecifications:
-
IamInstanceProfile:
Arn: !Ref IamRoleInstanceProfile
ImageId: !Ref EcsAmiId
InstanceType: !Select [ 0, !Ref EcsInstanceType ]
KeyName: !If [ CreateEC2LCWithKeyPair, !Ref KeyName, !Ref "AWS::NoValue" ]
Monitoring:
Enabled: true
SecurityGroups:
- GroupId: !If [ CreateNewSecurityGroup, !Ref EcsSecurityGroup, !Ref SecurityGroupId ]
SubnetId: !If
- CreateSubnet1
- !If
- CreateSubnet2
- !If
- CreateSubnet3
- !Join [ "," , [ !Ref PubSubnetAz1, !Ref PubSubnetAz2, !Ref PubSubnetAz3 ] ]
- !Join [ "," , [ !Ref PubSubnetAz1, !Ref PubSubnetAz2 ] ]
- !Ref PubSubnetAz1
- !Join [ "," , !Ref SubnetIds ]
BlockDeviceMappings:
- DeviceName: !Ref DeviceName
Ebs:
VolumeSize: !Ref EbsVolumeSize
VolumeType: !Ref EbsVolumeType
UserData:
Fn::Base64: !Ref UserData
-
IamInstanceProfile:
Arn: !Ref IamRoleInstanceProfile
ImageId: !Ref EcsAmiId
InstanceType: !Select [ 1, !Ref EcsInstanceType ]
KeyName: !If [ CreateEC2LCWithKeyPair, !Ref KeyName, !Ref "AWS::NoValue" ]
Monitoring:
Enabled: true
SecurityGroups:
- GroupId: !If [ CreateNewSecurityGroup, !Ref EcsSecurityGroup, !Ref SecurityGroupId ]
SubnetId: !If
- CreateSubnet1
- !If
- CreateSubnet2
- !If
- CreateSubnet3
- !Join [ "," , [ !Ref PubSubnetAz1, !Ref PubSubnetAz2, !Ref PubSubnetAz3 ] ]
- !Join [ "," , [ !Ref PubSubnetAz1, !Ref PubSubnetAz2 ] ]
- !Ref PubSubnetAz1
- !Join [ "," , !Ref SubnetIds ]
BlockDeviceMappings:
- DeviceName: !Ref DeviceName
Ebs:
VolumeSize: !Ref EbsVolumeSize
VolumeType: !Ref EbsVolumeType
UserData:
Fn::Base64: !Ref UserData
-
IamInstanceProfile:
Arn: !Ref IamRoleInstanceProfile
ImageId: !Ref EcsAmiId
InstanceType: !Select [ 2, !Ref EcsInstanceType ]
KeyName: !If [ CreateEC2LCWithKeyPair, !Ref KeyName, !Ref "AWS::NoValue" ]
Monitoring:
Enabled: true
SecurityGroups:
- GroupId: !If [ CreateNewSecurityGroup, !Ref EcsSecurityGroup, !Ref SecurityGroupId ]
SubnetId: !If
- CreateSubnet1
- !If
- CreateSubnet2
- !If
- CreateSubnet3
- !Join [ "," , [ !Ref PubSubnetAz1, !Ref PubSubnetAz2, !Ref PubSubnetAz3 ] ]
- !Join [ "," , [ !Ref PubSubnetAz1, !Ref PubSubnetAz2 ] ]
- !Ref PubSubnetAz1
- !Join [ "," , !Ref SubnetIds ]
BlockDeviceMappings:
- DeviceName: !Ref DeviceName
Ebs:
VolumeSize: !Ref EbsVolumeSize
VolumeType: !Ref EbsVolumeType
UserData:
Fn::Base64: !Ref UserData
Outputs:
EcsInstanceAsgName:
Condition: CreateWithASG
Description: Auto Scaling Group Name for ECS Instances
Value: !Ref EcsInstanceAsg
EcsSpotFleetRequestId:
Condition: CreateWithSpot
Description: Spot Fleet Request for ECS Instances
Value: !Ref EcsSpotFleet
UsedByECSCreateCluster:
Description: Flag used by ECS Create Cluster Wizard
Value: 'true'
TemplateVersion:
Description: The version of the template used by Create Cluster Wizard
Value: '2.0.0'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment