Assigning a domain name to an AWS Fargate task
I have an AWS Fargate task running a web app in a public subnet so it has a public address. My question is how to I connect a domain (through Route 53) to that task, so that nothing breaks when I deploy a new version of it.
- I know I can use ALB/NLB but I want to save on costs.
- I don't want to use the public IP directly as it may change.
- I assume the solution has to do something with the ENI but I'm not sure how to point to it through Route 53.
Any help would be much appreciated.
Thanks
For most cases, you most likely want to use an ALB/NLB for service discovery. While there are some costs, you also get a lot of benefits: Some DoS protection, scaling metrics, logging, SSL/TLS
However, you can use ECS service discovery.
Service discovery uses Amazon Route 53 auto naming API actions to manage DNS entries for your service's tasks, making them discoverable within your VPC
and
Public namespaces are supported but you must have an existing public hosted zone registered with Route 53 before creating your service discovery service.
Service discovery requires that tasks use either the awsvpc, bridge, or host network mode.
Here is a Blog entry detailing how to use Service discovery with fargate: https://aws.amazon.com/blogs/aws/amazon-ecs-service-discovery/
I tried to. The problem is the public ip that fargate uses is attached to the TASK so if the task is restarted then a new ip address is given and the dns record needs to be updated. Thats why the alb/nlb is used.
In theory you could use something else to manage the dns host records, perhaps a lambda function or something
https://forums.aws.amazon.com/thread.jspa?threadID=270599
As stated in the ECS developer guide:
Amazon ECS does not support registering services into public DNS namespaces
So no chance for out-of-the-box public domain registration via ECS Service Discovery. But what you can do, is to use AWS SKD to fetch the public IP address of your container after deployment and register it in your public Route 53 hosted zone.
This article shows an approach using a lambda function to do exactly that whenever your container is redeployed.
I don't believe @m-glatki's answer is correct - you cannot use Service Discovery for public IP addresses, as mentioned by @andreas-pasch.
The only way I've found to implement this was to create a Lambda function triggered by a Cloudwatch Event for when the container reaches the 'RUNNING' state. My first attempt was to fetch the container metadata and update Route 53 on launch via a startup script but this was a dead-end.
There's a good guide here for JavaScript (I re-wrote in Python & Terraform). Something I thought missing was adding the ECS cluster ARN to the Cloudwatch Event pattern under 'detail'; the function may trigger on every container launch otherwise. The ECS event docs might be useful for specifics.
AWS have a guide for EC2 but I didn't bother wading through their code; might be handy to refer to if you also prefer Python.
NB: Service Discovery works well for private IP addresses.