Search code examples
amazon-web-servicesnetwork-programmingamazon-ecsamazon-vpc

AWS ECS Fargate multi container interaction


I have a problem regarding the interaction between containers in a AWS ECS cluster.

I'll start by introducing my project and AWS configuration. My app is split in 2 components: frontend and backend. The frontend runs on port 3000 and the backend runs on port 8000. From the frontend I make some API calls with the usual localhost:8000 which works just in fine on my local machine.

Then I made them into docker images and deployed them to AWS ECR. From there I can't figure it out how to make them communicate. I can first deploy the backend, see the public or private ip and modify the frontend project and change localhost:8000 to 192.... and that works too but it's not the solution that I want.

I couldn't find any tutorial on this and I'm in dire need of help/

Thank you for your time!

What I had in mind it's the following: I have a VPC(192.168.0.0/24) with 4 subnets, 2 public, 2 private. I want to deploy the backend service(or services in the future) on the 2 private without a public IP(which I succeded creating some endpoints in the VPC). Then I want to have the frontend service(or services) still on the 2 private networks but with a public IP to access it.

I discovered 2 possibilities: with an option when creating an AWS ECS service "Service Connect" and using an Load Balancer. But I didn't succeded on using them. I tried in special the "Service Connect" option. I created a namespace named "ECS" and in that I created a service named "my-backend". From there I see that I can register a service instance but I need to provide an ID which I saw that need to match with the backend task ID and fill out the IP address on the private subnet with the port. I'm blocked at this step.. this means that I have to register a instance every time a new task of a backend runs? and in the frontend i need to replace the url to the backend with http://my-backend.ECS:8000?

Update 1

The frontend is using React and the requests are running on the users browser.

The frontend and backend are running of separate services and separate tasks.


Solution

  • Building on the replies, my suggestion is keep the front end service in the private subnets as well and don't assign it a public ip. Use an ALB to receive all public traffic, and associate the front end ecs service with this load balancer (along with a target group and listener, and security group rule to allow the ALB/target group to reach the front end service). Place the front end service and all of the backend services in the same service connect namespace. In the task definitions, set the portMappings. For simplicity I would give the port name the same name as the service itself, and containerPort and hostPort to the same port as what the service in the container listens on.

          portMappings = [
            {
              name          = service-name
              containerPort = service-port
              hostPort      = service-port
              protocol      = "tcp"
              appProtocol   = "http"
            }
          ]
    

    Then in your front end service, call your backend services via http://service-name:service-port. Backend services can talk to each other the same way as well

    browser -> ALB -> target group -> front end service, calls to backend services via http://some-backend-service:some-backend-port, http://some-other-backend-service:some-other-backend-port, etc), which will get routed to -> the backend service(s).

    for things to communicate with each other, on top of Service Connect, you may need to attach a security group that allows traffic to/from itself and attach it to all of the services.