{
    "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"
        }
    }
}