AWSTemplateFormatVersion: '2010-09-09' Description: This stack deploys a Fargate cluster in an existing VPC with both public and private subnets. Containers are deployed into the private subnet and a Public loadbalancer is created to route traffic to the containers. Parameters: ResourceName: Type: String Resources: # ECS Resources ECSCluster: Type: AWS::ECS::Cluster # A security group for the containers we will run in Fargate. # Three rules, allowing network traffic from a public facing load # balancer, a private internal load balancer, and from other members # of the security group. # # Remove any of the following ingress rules that are not needed. FargateContainerSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: Access to the Fargate containers VpcId: !ImportValue 'TrivyVpcStack:VpcID' EcsSecurityGroupIngressFromPublicALB: Type: AWS::EC2::SecurityGroupIngress Properties: Description: Ingress from the public ALB GroupId: !Ref 'FargateContainerSecurityGroup' IpProtocol: -1 SourceSecurityGroupId: !Ref 'PublicLoadBalancerSG' EcsSecurityGroupIngressFromSelf: Type: AWS::EC2::SecurityGroupIngress Properties: Description: Ingress from other containers in the same security group GroupId: !Ref 'FargateContainerSecurityGroup' IpProtocol: -1 SourceSecurityGroupId: !Ref 'FargateContainerSecurityGroup' # Load balancers for getting traffic to containers. # This sample template creates a public load balancer: # # - One public load balancer, hosted in public subnets that is accessible # to the public, and is intended to route traffic to one or more public # facing services. # A public facing load balancer, this is used for accepting traffic from the public # internet and directing it to public facing microservices PublicLoadBalancerSG: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: Access to the public facing load balancer VpcId: !ImportValue 'TrivyVpcStack:VpcID' SecurityGroupIngress: # Allow access to ALB from anywhere on the internet - CidrIp: 0.0.0.0/0 IpProtocol: TCP FromPort: '80' ToPort: '80' PublicLoadBalancer: Type: AWS::ElasticLoadBalancingV2::LoadBalancer Properties: Scheme: internet-facing LoadBalancerAttributes: - Key: idle_timeout.timeout_seconds Value: '30' Subnets: # The load balancer is placed into the public subnets, so that traffic # from the internet can reach the load balancer directly via the internet gateway - !ImportValue 'TrivyVpcStack:PublicSubnet1' - !ImportValue 'TrivyVpcStack:PublicSubnet2' SecurityGroups: [!Ref 'PublicLoadBalancerSG'] # A dummy target group is used to setup the ALB to just drop traffic # initially, before any real service target groups have been added. DummyTargetGroupPublic: Type: AWS::ElasticLoadBalancingV2::TargetGroup Properties: HealthCheckIntervalSeconds: 6 HealthCheckPath: / HealthCheckProtocol: HTTP HealthCheckTimeoutSeconds: 5 HealthyThresholdCount: 2 Name: !Join ['-', [!Ref 'ResourceName', 'drop-1']] Port: 80 Protocol: HTTP UnhealthyThresholdCount: 2 VpcId: !ImportValue 'TrivyVpcStack:VpcID' PublicLoaDBalancerListener: Type: AWS::ElasticLoadBalancingV2::Listener DependsOn: - PublicLoadBalancer Properties: DefaultActions: - TargetGroupArn: !Ref 'DummyTargetGroupPublic' Type: 'forward' LoadBalancerArn: !Ref 'PublicLoadBalancer' Port: 80 Protocol: HTTP # This is an IAM role which authorizes ECS to manage resources on your # account on your behalf, such as updating your load balancer with the # details of where your containers are, so that traffic can reach your # containers. ECSRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Statement: - Effect: Allow Principal: Service: [ecs.amazonaws.com] Action: ['sts:AssumeRole'] Path: / Policies: - PolicyName: ecs-service PolicyDocument: Statement: - Effect: Allow Action: # Rules which allow ECS to update load balancers on your behalf # with the information sabout how to send traffic to your containers - 'elasticloadbalancing:DeregisterInstancesFromLoadBalancer' - 'elasticloadbalancing:DeregisterTargets' - 'elasticloadbalancing:Describe*' - 'elasticloadbalancing:RegisterInstancesWithLoadBalancer' - 'elasticloadbalancing:RegisterTargets' Resource: '*' # This is a role which is used by the ECS tasks themselves. ECSTaskExecutionRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Statement: - Effect: Allow Principal: Service: [ecs-tasks.amazonaws.com] Action: ['sts:AssumeRole'] Path: / Policies: - PolicyName: AmazonECSTaskExecutionRolePolicy PolicyDocument: Statement: - Effect: Allow Action: # Allow the ECS Tasks to download images from ECR - 'ecr:GetAuthorizationToken' - 'ecr:BatchCheckLayerAvailability' - 'ecr:GetDownloadUrlForLayer' - 'ecr:BatchGetImage' # Allow the ECS tasks to upload logs to CloudWatch - 'logs:CreateLogStream' - 'logs:PutLogEvents' Resource: '*' Outputs: FargateContainerSG: Description: A reference to the created SecurityGroup Value: !Ref FargateContainerSecurityGroup Export: Name: FargateClusterStack:FargateContainerSG ECSCluster: Description: A reference to the created Cluster Value: !Ref ECSCluster Export: Name: FargateClusterStack:ECSCluster ECSTaskExecutionRole: Description: A reference to the created ECSTaskRole Value: !Ref ECSTaskExecutionRole Export: Name: FargateClusterStack:ECSTaskExecutionRole PublicListener: Description: A reference to the created ALB Listener Value: !Ref PublicLoaDBalancerListener Export: Name: FargateClusterStack:PublicListener