Description: > This template illustrates reference architecture for ECS Parameters: InstanceType: Type: String Default: c4.xlarge ClusterSize: Type: Number Default: 1 TemplateBucket: Type: String Description: > S3 Bucket used for nested templates Mappings: AWSRegionToAMI: us-east-1: AMI: ami-6df8fe7a us-east-2: AMI: ami-c6b5efa3 us-west-1: AMI: ami-1eda8d7e us-west-2: AMI: ami-a2ca61c2 eu-west-1: AMI: ami-c91624b0 eu-west-2: AMI: ami-42c5cf26 eu-central-1: AMI: ami-e012d48f ap-northeast-1: AMI: ami-08f7956f ap-southeast-1: AMI: ami-f4832f97 ap-southeast-2: AMI: ami-774b7314 ca-central-1: AMI: ami-be45f7da Resources: BetaPort: Type: "AWS::SSM::Parameter" Properties: Name: "BetaPort" Type: "String" Value: "8080" LivePort: Type: "AWS::SSM::Parameter" Properties: Name: "LivePort" Type: "String" Value: "80" ECSRole: Type: AWS::IAM::Role Properties: Path: / #RoleName: !Sub ecs-${AWS::StackName} AssumeRolePolicyDocument: | { "Statement": [{ "Effect": "Allow", "Principal": { "Service": [ "ec2.amazonaws.com" ]}, "Action": [ "sts:AssumeRole" ] }] } ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role InstanceProfile: Type: AWS::IAM::InstanceProfile Properties: Path: / Roles: - !Ref ECSRole SecurityGroup: Type: "AWS::EC2::SecurityGroup" Properties: GroupDescription: !Sub ${AWS::StackName}-hosts SecurityGroupIngress: - SourceSecurityGroupId: !GetAtt LoadBalancer.Outputs.SecurityGroup IpProtocol: -1 VpcId: !GetAtt VPC.Outputs.VpcId Cluster: Type: AWS::ECS::Cluster Properties: ClusterName: !Ref AWS::StackName AutoScalingGroup: Type: AWS::AutoScaling::AutoScalingGroup Properties: VPCZoneIdentifier: - !GetAtt VPC.Outputs.Subnet1 - !GetAtt VPC.Outputs.Subnet2 LaunchConfigurationName: !Ref LaunchConfiguration MinSize: !Ref ClusterSize MaxSize: !Ref ClusterSize DesiredCapacity: !Ref ClusterSize Tags: - Key: Name Value: !Sub ${AWS::StackName} - ECS Host PropagateAtLaunch: true CreationPolicy: ResourceSignal: Timeout: PT15M UpdatePolicy: AutoScalingRollingUpdate: MinInstancesInService: 1 MaxBatchSize: 1 PauseTime: PT15M WaitOnResourceSignals: true LaunchConfiguration: Type: AWS::AutoScaling::LaunchConfiguration Metadata: AWS::CloudFormation::Init: config: commands: 01_add_instance_to_cluster: command: !Sub echo ECS_CLUSTER=${Cluster} > /etc/ecs/ecs.config files: "/etc/cfn/cfn-hup.conf": mode: 000400 owner: root group: root content: !Sub | [main] stack=${AWS::StackId} region=${AWS::Region} "/etc/cfn/hooks.d/cfn-auto-reloader.conf": content: !Sub | [cfn-auto-reloader-hook] triggers=post.update path=Resources.ContainerInstances.Metadata.AWS::CloudFormation::Init action=/opt/aws/bin/cfn-init -v --region ${AWS::Region} --stack ${AWS::StackName} --resource LaunchConfiguration services: sysvinit: cfn-hup: enabled: true ensureRunning: true files: - /etc/cfn/cfn-hup.conf - /etc/cfn/hooks.d/cfn-auto-reloader.conf Properties: ImageId: !FindInMap [ AWSRegionToAMI, !Ref "AWS::Region", AMI ] InstanceType: !Ref InstanceType IamInstanceProfile: !Ref InstanceProfile SecurityGroups: - !Ref SecurityGroup UserData: "Fn::Base64": !Sub | #!/bin/bash yum install -y aws-cfn-bootstrap /opt/aws/bin/cfn-init -v --region ${AWS::Region} --stack ${AWS::StackName} --resource LaunchConfiguration /opt/aws/bin/cfn-signal -e $? --region ${AWS::Region} --stack ${AWS::StackName} --resource AutoScalingGroup LoadBalancer: Type: AWS::CloudFormation::Stack Properties: TemplateURL: !Sub https://s3.amazonaws.com/${TemplateBucket}/templates/load-balancer.yaml Parameters: Subnet1 : !GetAtt VPC.Outputs.Subnet1 Subnet2 : !GetAtt VPC.Outputs.Subnet2 VpcId: !GetAtt VPC.Outputs.VpcId VpcCIDR: 10.215.0.0/16 Name: !Sub "${AWS::StackName}" LoadBalancerListener: Type: AWS::ElasticLoadBalancingV2::Listener Properties: LoadBalancerArn: !GetAtt LoadBalancer.Outputs.LoadBalancerArn Port: 80 Protocol: HTTP DefaultActions: - Type: forward TargetGroupArn: !Ref DefaultTargetGroup LoadBalancerListener2: Type: AWS::ElasticLoadBalancingV2::Listener Properties: LoadBalancerArn: !GetAtt LoadBalancer.Outputs.LoadBalancerArn Port: 8080 Protocol: HTTP DefaultActions: - Type: forward TargetGroupArn: !Ref DefaultTargetGroup # We define a default target group here, as this is a mandatory Parameters # when creating an Application Load Balancer Listener. This is not used, instead # a target group is created per-service in each service template (../services/*) DefaultTargetGroup: Type: AWS::ElasticLoadBalancingV2::TargetGroup Properties: Name: !Sub ${AWS::StackName}-default VpcId: !GetAtt VPC.Outputs.VpcId Port: 80 Protocol: HTTP VPC: Type: AWS::CloudFormation::Stack Properties: TemplateURL: !Sub https://s3.amazonaws.com/${TemplateBucket}/templates/vpc.yaml Parameters: Name: !Ref AWS::StackName VpcCIDR: 10.215.0.0/16 Subnet1CIDR: 10.215.10.0/24 Subnet2CIDR: 10.215.20.0/24 Outputs: LoadBalancerARN: Value: !GetAtt LoadBalancer.Outputs.LoadBalancerArn BetaListenerARN: Value: !Ref LoadBalancerListener2 LiveListenerARN: Value: !Ref LoadBalancerListener