How to:
- create a Docker-based AWS Fargate/ECS deployment
- without the Docker containers having a public IP
- with an Application Load Balancer as reverse proxy / SSL termination proxy sitting in front of the containers
For Fargate/ECS to be able to access your Docker images hosted on ECR (or somewhere else) you'll have to allow outbound internet access to the Fargate subnets. Here's how you do it.
-
Create a Fargate Cluster with a new VPC with 2 (or more) subnets.
- Go to ECS -> Clusters -> Create Cluster
- Select Networking Only (Fargate) -> Create new VPC with 2 subnets at 10.0.0.0/24 & 10.0.1.0/24
-
Make the 2 subnets created in step 1 private, add 2 new public-facing subnets and bridge them with NAT:
- Go to VPC -> Subnets -> Create Subnet
- Create 2 new public-facing subnets in your VPC in the AZ of the subnets auto-created in step 1. For example, if in step 1 2 subnets 10.0.0.0/24 (us-east-1a) and 10.0.1.0/24 (us-east-1b) were created, create 2 new subnets 10.0.2.0/24 (us-east-1a) and 10.0.3.0/24 (us-east-1b).
- (optional) Name the subnets something like: private-sub-01 (10.0.0.0/24), private-sub-02 (10.0.1.0/24), public-sub-01 (10.0.2.0/24), & public-sub-02 (10.0.3.0/24)
- Create a NAT gateway for each of the new public-facing subnets (Allocate new Elastic IP for each gateway).
- Create a new route table for each of the public subnets and add two entries to each table:
10.0.0.0/16 -> local
and0.0.0.0/0 -> igw-xxx
(the internet gateway auto-created in step 1). - Modify the route tables of each of the subnets auto-created in step 1 as follows: change the target of the 0.0.0.0/0 route to the nat-xxx NAT gateway of the subnet's AZ. In the example above, point.
- You should now have
- the private 10.0.0.0/24 subnet's 0.0.0.0/0 route to the NAT gateway in subnet 10.0.2.0/24
- the private 10.0.1.0/24 subnet's 0.0.0.0/0 route to the NAT gateway in subnet 10.0.3.0/24
- the public 10.0.2.0/24 subnet's 0.0.0.0/0 route to the Internet gateway from before
- the public 10.0.2.0/24 subnet's 0.0.0.0/0 route to the Internet gateway from before
-
Create an Application Load Balancer with the 2 public-facing subnets selected in the "Availability Zones" section.
-
Create ECR repository and upload your image:
- Go to ECS, Repositories, Create Repository.
- Upload your image and remember its tag.
-
Create Fargate Task Definition(s) for your task(s):
- Select Fargate type.
- Select "ecsTaskExecutionRole" as Task Role.
- Use "awsvpc" networking mode.
- Press "Add container".
- Put the URL of your new ECR repository plus the image tag.
- Leave the "Healthcheck" fields empty unless you know what you're doing. Health checks will be done by the load balancer and will be configured in the next step.
-
Create a Fargate Service:
- Select Fargate type.
- Choose your VPC created in step 1.
- Select the 2 private subnets created in step 1.
- Disable "Auto-assign public IP".
- Choose "Application Load Balancer"
- Select your load balancer created in step 3.
- Add your container(s).
- Choose health check options. Note that these are HTTP-based and different from the container health check options (not) used in step 5.
- Service discovery is not required for this setup.
-
When the container is deployed, depending your networking, you can access your deployed service via EC2 -> Networking Interfaces. 2 of the interfaces will be associated with the ALB, where the other 2 are associated to the NAT gateway. The ALB interfaces should have a public IP open. Visit http://<YOUR_IP>:<YOUR_APP_PORT>/ to see the service. If it's timing out, be sure to check the security group inbound rules associated with that Network Interface as you may be blocked.
- https://user-images.githubusercontent.com/175722/80485502-d2cd8380-8959-11ea-97c8-0dfc971d78e0.png
- https://de.slideshare.net/AmazonWebServices/introducing-aws-fargate slides 27ff
- aws/amazon-ecs-agent#1128 (comment)
- aws/amazon-ecs-agent#1266
- https://aws.amazon.com/de/blogs/compute/task-networking-in-aws-fargate/