{ "AWSTemplateFormatVersion": "2010-09-09", "Outputs": { "ALBURL": { "Description": "URL of the ALB", "Value": { "Fn::Join": [ "", [ "http://", { "Fn::GetAtt": [ "ALB", "DNSName" ] } ] ] } } }, "Parameters": { "NginxImage": { "Default": "nginx:alpine", "Description": "The nginx container image to run (e.g. nginx:alpine)", "Type": "String" } }, "Resources": { "ALB": { "Properties": { "Scheme": "internet-facing", "SecurityGroups": [ { "Ref": "ALBSecurityGroup" } ], "Subnets": [ { "Ref": "PubSubnetAz1" }, { "Ref": "PubSubnetAz2" } ] }, "Type": "AWS::ElasticLoadBalancingV2::LoadBalancer" }, "ALBListener": { "Properties": { "DefaultActions": [ { "TargetGroupArn": { "Ref": "ALBTargetGroup" }, "Type": "forward" } ], "LoadBalancerArn": { "Ref": "ALB" }, "Port": "80", "Protocol": "HTTP" }, "Type": "AWS::ElasticLoadBalancingV2::Listener" }, "ALBSecurityGroup": { "Properties": { "GroupDescription": "ALB Security Group", "SecurityGroupIngress": [ { "CidrIp": "0.0.0.0/0", "FromPort": "80", "IpProtocol": "tcp", "ToPort": "80" } ], "VpcId": { "Ref": "VPC" } }, "Type": "AWS::EC2::SecurityGroup" }, "ALBTargetGroup": { "Properties": { "HealthCheckIntervalSeconds": "30", "HealthCheckProtocol": "HTTP", "HealthCheckTimeoutSeconds": "10", "HealthyThresholdCount": "4", "Matcher": { "HttpCode": "200" }, "Port": 80, "Protocol": "HTTP", "TargetType": "ip", "UnhealthyThresholdCount": "3", "VpcId": { "Ref": "VPC" } }, "Type": "AWS::ElasticLoadBalancingV2::TargetGroup" }, "AttachGateway": { "Properties": { "InternetGatewayId": { "Ref": "InternetGateway" }, "VpcId": { "Ref": "VPC" } }, "Type": "AWS::EC2::VPCGatewayAttachment" }, "CWLogGroup": { "Type": "AWS::Logs::LogGroup" }, "ECSCluster": { "Properties": { "ClusterName": "Fargate" }, "Type": "AWS::ECS::Cluster" }, "InternetGateway": { "Type": "AWS::EC2::InternetGateway" }, "PubSubnet1RouteTableAssociation": { "Properties": { "RouteTableId": { "Ref": "RouteViaIgw" }, "SubnetId": { "Ref": "PubSubnetAz1" } }, "Type": "AWS::EC2::SubnetRouteTableAssociation" }, "PubSubnet2RouteTableAssociation": { "Properties": { "RouteTableId": { "Ref": "RouteViaIgw" }, "SubnetId": { "Ref": "PubSubnetAz2" } }, "Type": "AWS::EC2::SubnetRouteTableAssociation" }, "PubSubnetAz1": { "Properties": { "AvailabilityZone": { "Fn::Join": [ "", [ { "Ref": "AWS::Region" }, "a" ] ] }, "CidrBlock": "10.0.0.0/24", "VpcId": { "Ref": "VPC" } }, "Type": "AWS::EC2::Subnet" }, "PubSubnetAz2": { "Properties": { "AvailabilityZone": { "Fn::Join": [ "", [ { "Ref": "AWS::Region" }, "b" ] ] }, "CidrBlock": "10.0.1.0/24", "VpcId": { "Ref": "VPC" } }, "Type": "AWS::EC2::Subnet" }, "PublicRouteViaIgw": { "Properties": { "DestinationCidrBlock": "0.0.0.0/0", "GatewayId": { "Ref": "InternetGateway" }, "RouteTableId": { "Ref": "RouteViaIgw" } }, "Type": "AWS::EC2::Route" }, "RouteViaIgw": { "Properties": { "VpcId": { "Ref": "VPC" } }, "Type": "AWS::EC2::RouteTable" }, "Service": { "DependsOn": "ALBListener", "Properties": { "Cluster": { "Ref": "ECSCluster" }, "DesiredCount": 1, "LaunchType": "FARGATE", "LoadBalancers": [ { "ContainerName": "nginx", "ContainerPort": 80, "TargetGroupArn": { "Ref": "ALBTargetGroup" } } ], "NetworkConfiguration": { "AwsvpcConfiguration": { "AssignPublicIp": "ENABLED", "SecurityGroups": [ { "Ref": "TaskSecurityGroup" } ], "Subnets": [ { "Ref": "PubSubnetAz1" }, { "Ref": "PubSubnetAz2" } ] } }, "TaskDefinition": { "Ref": "TaskDefinition" } }, "Type": "AWS::ECS::Service" }, "TaskDefinition": { "DependsOn": "TaskExecutionPolicy", "Properties": { "ContainerDefinitions": [ { "Essential": "true", "Image": { "Ref": "NginxImage" }, "LogConfiguration": { "LogDriver": "awslogs", "Options": { "awslogs-group": { "Ref": "CWLogGroup" }, "awslogs-region": { "Ref": "AWS::Region" }, "awslogs-stream-prefix": "nginx" } }, "Name": "nginx", "PortMappings": [ { "ContainerPort": 80 } ] } ], "Cpu": "512", "ExecutionRoleArn": { "Fn::GetAtt": [ "TaskExecutionRole", "Arn" ] }, "Memory": "1GB", "NetworkMode": "awsvpc", "RequiresCompatibilities": [ "FARGATE" ] }, "Type": "AWS::ECS::TaskDefinition" }, "TaskExecutionPolicy": { "Properties": { "PolicyDocument": { "Statement": [ { "Action": [ "ecr:GetAuthorizationToken", "ecr:BatchCheckLayerAvailability", "ecr:GetDownloadUrlForLayer", "ecr:BatchGetImage", "logs:CreateLogStream", "logs:PutLogEvents" ], "Effect": "Allow", "Resource": [ "*" ] } ], "Version": "2012-10-17" }, "PolicyName": "fargate-execution", "Roles": [ { "Ref": "TaskExecutionRole" } ] }, "Type": "AWS::IAM::Policy" }, "TaskExecutionRole": { "Properties": { "AssumeRolePolicyDocument": { "Statement": [ { "Action": [ "sts:AssumeRole" ], "Effect": "Allow", "Principal": { "Service": [ "ecs-tasks.amazonaws.com" ] } } ] } }, "Type": "AWS::IAM::Role" }, "TaskSecurityGroup": { "Properties": { "GroupDescription": "Task Security Group", "SecurityGroupIngress": [ { "FromPort": "80", "IpProtocol": "tcp", "SourceSecurityGroupId": { "Fn::GetAtt": [ "ALBSecurityGroup", "GroupId" ] }, "ToPort": "80" } ], "VpcId": { "Ref": "VPC" } }, "Type": "AWS::EC2::SecurityGroup" }, "VPC": { "Properties": { "CidrBlock": "10.0.0.0/16", "EnableDnsHostnames": "true", "EnableDnsSupport": "true" }, "Type": "AWS::EC2::VPC" } } }