--- AWSTemplateFormatVersion: 2010-09-09 Description: ECS Spot Workshop CFN Template Metadata: Author: Description: Jayaprakash Alawala License: Description: 'Copyright 2020 Amazon.com, Inc. and its affiliates. All Rights Reserved. Licensed under the Amazon Software License (the "License"). You may not use this file except in compliance with the License. A copy of the License is located at http://aws.amazon.com/asl/ or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.' Parameters: sourceCidr: Default: 0.0.0.0/0 Description: Optional - CIDR/IP range for instance ssh/http access and load balancer http access Type: String ECSAMI: Description: AMI ID Type: AWS::SSM::Parameter::Value Default: /aws/service/ecs/optimized-ami/amazon-linux-2/recommended/image_id EETeamRoleArn: Type: String Default: '' Conditions: EventEngine: !Not [!Equals [!Ref EETeamRoleArn, '']] Resources: vpc: Type: AWS::EC2::VPC Properties: CidrBlock: 10.0.0.0/16 EnableDnsHostnames: true EnableDnsSupport: true Tags: - Key: Name Value: "EcsSpotWorkshop" internetGateway: Type: AWS::EC2::InternetGateway DependsOn: - vpc attachGateway: Type: AWS::EC2::VPCGatewayAttachment DependsOn: - vpc - internetGateway Properties: InternetGatewayId: !Ref internetGateway VpcId: !Ref vpc publicSubnet1: Type: AWS::EC2::Subnet DependsOn: attachGateway Properties: AvailabilityZone: Fn::Select: - 0 - Fn::GetAZs: Ref: AWS::Region CidrBlock: 10.0.0.0/24 MapPublicIpOnLaunch: true Tags: - Key: Name Value: "EcsSpotWorkshop publicSubnet1" VpcId: !Ref vpc publicSubnet2: Type: AWS::EC2::Subnet DependsOn: attachGateway Properties: AvailabilityZone: Fn::Select: - 1 - Fn::GetAZs: Ref: AWS::Region CidrBlock: 10.0.1.0/24 MapPublicIpOnLaunch: true Tags: - Key: Name Value: "EcsSpotWorkshop publicSubnet2" VpcId: !Ref vpc publicSubnet3: Type: AWS::EC2::Subnet DependsOn: attachGateway Properties: AvailabilityZone: Fn::Select: - 2 - Fn::GetAZs: Ref: AWS::Region CidrBlock: 10.0.2.0/24 MapPublicIpOnLaunch: true Tags: - Key: Name Value: "EcsSpotWorkshop publicSubnet3" VpcId: !Ref vpc privateSubnet1: Type: AWS::EC2::Subnet Properties: AvailabilityZone: Fn::Select: - 0 - Fn::GetAZs: Ref: AWS::Region CidrBlock: 10.0.3.0/24 Tags: - Key: Name Value: "EcsSpotWorkshop privateSubnet1" VpcId: !Ref vpc privateSubnet2: Type: AWS::EC2::Subnet Properties: AvailabilityZone: Fn::Select: - 1 - Fn::GetAZs: Ref: AWS::Region CidrBlock: 10.0.4.0/24 Tags: - Key: Name Value: "EcsSpotWorkshop privateSubnet2" VpcId: !Ref vpc privateSubnet3: Type: AWS::EC2::Subnet Properties: AvailabilityZone: Fn::Select: - 2 - Fn::GetAZs: Ref: AWS::Region CidrBlock: 10.0.5.0/24 Tags: - Key: Name Value: "EcsSpotWorkshop privateSubnet3" VpcId: !Ref vpc publicRouteTable: Type: AWS::EC2::RouteTable DependsOn: - vpc - attachGateway Properties: Tags: - Key: Name Value: "EcsSpotWorkshop Public Route Table" VpcId: !Ref vpc RouteTablePrivate: Type: AWS::EC2::RouteTable DependsOn: vpc Properties: VpcId: !Ref vpc Tags: - Key: Name Value: "EcsSpotWorkshop Private Route Table" publicSubnet1RouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation DependsOn: - publicRouteTable - publicSubnet1 - attachGateway Properties: RouteTableId: !Ref publicRouteTable SubnetId: !Ref publicSubnet1 publicSubnet2RouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation DependsOn: - publicRouteTable - publicSubnet2 - attachGateway Properties: RouteTableId: !Ref publicRouteTable SubnetId: !Ref publicSubnet2 publicSubnet3RouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation DependsOn: - publicRouteTable - publicSubnet3 - attachGateway Properties: RouteTableId: !Ref publicRouteTable SubnetId: !Ref publicSubnet3 privateSubnet1RouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation DependsOn: - RouteTablePrivate - privateSubnet1 Properties: RouteTableId: !Ref RouteTablePrivate SubnetId: !Ref privateSubnet1 privateSubnet2RouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation DependsOn: - RouteTablePrivate - privateSubnet2 Properties: RouteTableId: !Ref RouteTablePrivate SubnetId: !Ref privateSubnet2 privateSubnet3RouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation DependsOn: - RouteTablePrivate - privateSubnet3 Properties: RouteTableId: !Ref RouteTablePrivate SubnetId: !Ref privateSubnet3 EIPNATGateway: Type: AWS::EC2::EIP DependsOn: - attachGateway - vpc Properties: Domain: vpc NATGateway: Type: AWS::EC2::NatGateway DependsOn: - publicSubnet1 Properties: AllocationId: !GetAtt EIPNATGateway.AllocationId SubnetId: !Ref publicSubnet1 publicRoute: Type: AWS::EC2::Route DependsOn: - publicRouteTable - internetGateway - attachGateway Properties: DestinationCidrBlock: 0.0.0.0/0 GatewayId: !Ref internetGateway RouteTableId: !Ref publicRouteTable privateRoute: Type: AWS::EC2::Route DependsOn: - RouteTablePrivate - NATGateway Properties: DestinationCidrBlock: 0.0.0.0/0 NatGatewayId: !Ref NATGateway RouteTableId: !Ref RouteTablePrivate autoScalingServiceLinkedRole: Type: AWS::IAM::ServiceLinkedRole Properties: AWSServiceName: autoscaling.amazonaws.com Description: Default Service-Linked Role enables access to AWS Services and Resources used or managed by Auto Scaling loadBalancerSecurityGroup: Type: AWS::EC2::SecurityGroup DependsOn: - vpc Properties: GroupDescription: Allow all traffic from internet SecurityGroupIngress: - CidrIp: !Ref sourceCidr IpProtocol: -1 VpcId: !Ref vpc instanceSecurityGroup: Type: AWS::EC2::SecurityGroup DependsOn: - vpc Properties: GroupDescription: Allow traffic from ALB VpcId: !Ref vpc instanceSecurityGroupIngress: Type: AWS::EC2::SecurityGroupIngress DependsOn: - instanceSecurityGroup - loadBalancerSecurityGroup Properties: GroupId: !Ref instanceSecurityGroup IpProtocol: -1 SourceSecurityGroupId: !Ref loadBalancerSecurityGroup ECSServiceALB: Type: AWS::ElasticLoadBalancingV2::LoadBalancer DependsOn: - loadBalancerSecurityGroup - publicSubnet1 - publicSubnet2 - publicSubnet3 Properties: Name: "EcsSpotWorkshop" Scheme: internet-facing SecurityGroups: - !Ref loadBalancerSecurityGroup Subnets: - !Ref publicSubnet1 - !Ref publicSubnet2 - !Ref publicSubnet3 ECSServiceTG: Type: AWS::ElasticLoadBalancingV2::TargetGroup DependsOn: - vpc Properties: HealthCheckIntervalSeconds: 50 HealthCheckPath: / HealthCheckPort: traffic-port HealthCheckProtocol: HTTP HealthCheckTimeoutSeconds: 45 HealthyThresholdCount: 2 Matcher: HttpCode: 200 Name: "EcsSpotWorkshop" Port: 80 Protocol: HTTP UnhealthyThresholdCount: 4 VpcId: !Ref vpc ECSServiceALBListener: Type: AWS::ElasticLoadBalancingV2::Listener DependsOn: - ECSServiceALB - ECSServiceTG Properties: DefaultActions: - Type: forward TargetGroupArn: !Ref ECSServiceTG LoadBalancerArn: !Ref ECSServiceALB Port: 80 Protocol: HTTP instanceRole: Type: AWS::IAM::Role Properties: RoleName: "EcsSpotWorkshop-EcsInstanceRole" AssumeRolePolicyDocument: Statement: - Action: - sts:AssumeRole Effect: Allow Principal: Service: - ec2.amazonaws.com Version: 2012-10-17 ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role - arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceAutoscaleRole - arn:aws:iam::aws:policy/AmazonEC2ReadOnlyAccess Cloud9instanceRole: Type: AWS::IAM::Role Properties: RoleName: "EcsSpotWorkshop-Cloud9InstanceRole" AssumeRolePolicyDocument: Statement: - Action: - sts:AssumeRole Effect: Allow Principal: Service: - ec2.amazonaws.com Version: 2012-10-17 ManagedPolicyArns: - arn:aws:iam::aws:policy/AdministratorAccess cloud9Environment: DependsOn: - publicSubnet1 Properties: Name : EcsSpotWorkshop Description: ECS Spot Workshop - Cloud9 environment OwnerArn: !If [EventEngine, !Sub "arn:aws:sts::${AWS::AccountId}:assumed-role/TeamRole/MasterKey", !Ref "AWS::NoValue"] InstanceType: t3.large SubnetId: Ref: publicSubnet1 Type: AWS::Cloud9::EnvironmentEC2 Cloud9instanceProfile: Type: AWS::IAM::InstanceProfile DependsOn: - Cloud9instanceRole Properties: InstanceProfileName: "EcsSpotWorkshop-Cloud9InstanceProfile" Path: / Roles: - Ref: Cloud9instanceRole instanceProfile: Type: AWS::IAM::InstanceProfile DependsOn: - instanceRole Properties: InstanceProfileName: "EcsSpotWorkshop-InstanceProfile" Path: / Roles: - Ref: instanceRole ECSInstanceLaunchTemplate: DependsOn: - instanceProfile Type: AWS::EC2::LaunchTemplate Properties: LaunchTemplateData: InstanceType: t3.large ImageId: !Ref ECSAMI IamInstanceProfile: Arn: Fn::GetAtt: - instanceProfile - Arn SecurityGroupIds: - !Ref instanceSecurityGroup TagSpecifications: - ResourceType: instance Tags: - Key: Name Value: "EcsSpotWorkshop" UserData: Fn::Base64: !Sub | #!/bin/bash echo "ECS_CLUSTER=EcsSpotWorkshop" >> /etc/ecs/ecs.config echo "ECS_ENABLE_SPOT_INSTANCE_DRAINING=true" >> /etc/ecs/ecs.config echo "ECS_CONTAINER_STOP_TIMEOUT=90s" >> /etc/ecs/ecs.config echo "ECS_ENABLE_CONTAINER_METADATA=true" >> /etc/ecs/ecs.config LaunchTemplateName: "EcsSpotWorkshop" ecrRepository: Type: AWS::ECR::Repository Properties: RepositoryName: ecs-spot-workshop/webapp Outputs: awsRegionId: Description: The AWS Region ID your template was launched in Value: !Ref AWS::Region instanceRole: Description: Instance Role Value: Fn::GetAtt: - instanceRole - Arn instanceProfile: Description: Instance profile ARN Value: Fn::GetAtt: - instanceProfile - Arn Cloud9instanceProfile: Description: Cloud9 Instance profile ARN Value: Fn::GetAtt: - Cloud9instanceProfile - Arn instanceSecurityGroup: Description: Instance security group Value: !Ref instanceSecurityGroup loadBalancerSecurityGroup: Description: Load Balancer security group Value: !Ref loadBalancerSecurityGroup publicSubnet1: Description: Public subnet 1 Value: !Ref publicSubnet1 publicSubnet2: Description: Public subnet 2 Value: !Ref publicSubnet2 publicSubnet3: Description: Public subnet 3 Value: !Ref publicSubnet3 privateSubnet1: Description: Private subnet 1 Value: !Ref privateSubnet1 privateSubnet2: Description: Private subnet 2 Value: !Ref privateSubnet2 privateSubnet3: Description: Private subnet 3 Value: !Ref privateSubnet3 vpc: Description: The VPC Value: !Ref vpc LaunchTemplateId: Description: The Launch Template Value: !Ref ECSInstanceLaunchTemplate ALBDNSName: Description: The Application Load Balancer Value: !GetAtt ECSServiceALB.DNSName TargetGroup: Description: The Target Group Value: !Ref ECSServiceTG VPCPublicSubnets: Description: The list of public subnets in the VPC Value: !Join [",", [!Ref publicSubnet1, !Ref publicSubnet2]] VPCPrivateSubnets: Description: The list of private subnets in the VPC Value: !Join [",", [!Ref privateSubnet1, !Ref privateSubnet2]] ecrRepository: Description: The ecrRepository Value: !Ref ecrRepository Cloud9instanceRole: Description: The Cloud9instanceRole Value: Fn::GetAtt: - Cloud9instanceRole - Arn autoScalingServiceLinkedRole: Description: The AWS Region ID your template was launched in Value: !Ref autoScalingServiceLinkedRole EETeamRoleArn: Description: EETeamRoleArn Value: !Ref EETeamRoleArn cloud9Environment: Description: Cloud9 environment Value: Fn::GetAtt: - cloud9Environment - Name ...