ECS is a service provided by AWS that manages the orchestration and provisioning of Docker containers, ECS allows the application to run in the cloud without having to configure the environment for the application to run and also easily scales up/down the containers based on the need.
The traditional way of ECS Service discovery
Service discovery keeps track of all the backend servers so that requests from the client can be distributed across the backend servers. In order to make the services discoverable and also the services to connect to each other, we have to configure our own service discovery by connecting every service to a separate load balancer, but this requires provisioning and maintaining additional infrastructure to achieve service discovery for each service separately. This way of service discovery is always a resource-heavy way.
Drawbacks in Traditional Service Discovery
In order to ensure that services were able to discover and connect with each other, we had to configure and run our own service discovery system. One of the common ways of service discovery is connecting every service to a load balancer, this is resource heavy way, Configuring a load balancer for every seperate services is going to be a time consuming and resource consuming one. And also it is going to cause huge pain in managing all the resources.
Other ways of service discovery are relying on external third parties like consul, etcd, Eureka and Apache zookeeper, using these creates an external dependency.
ECS Integrated Service discovery
ECS service discovery can be configured at the time of ECS service creation itself. In ECS service discovery, the service can automatically register themselves to an AWS Route 53 private hosted domain at the time of service creation, we can use either an existing private hosted domain or create a new one. At the time of service creation, the service registers itself to the private hosted domain by creating a new record set under it. Whenever the service scales up or down, it keeps the private hosted domain’s record set updated by adding new records or by removing.
Types of Routing
Aws Route 53 supports various routing policies,
- Simple Routing
- Failover Routing
- Geolocation Routing
- Geoproximity Routing (Traffic Flow Only)
- Latency-based Routing
- Multivalue Answer Routing
- Weighted Routing
Multivalue Answer Routing
MultiValue Answer routing policy is the best-suited routing policy for our private hosted domain in this service discovery scenario because this routing policy is definitely not a substitute for a load balancer, it has the benefit of returning multiple health-checkable IP’s as a response to the DNS query, thus improving availability.
Multivalue Answer routing routes traffic randomly to multiple instances(container) of the same service, we need to create one route 53 record for every instance(container) of the service with the routing policy as Multivalue Answer and allows to check the health of the container. Hence route 53 responds to DNS queries only with the IP’s of healthy containers.
Now let’s create ECS service with integrated service discovery,
Setting up an ECS service with Route 53 as Service Discovery
Step 1: Create a new service under your cluster in ECS console using the create option,
Here we are configuring the new service with the name test-service
specify the deployment type as rolling update( replaces the currently running version of the container with the latest version) and placement template as AZ Balanced Spread, proceed to the configure network step.
Step 2: In the next step, configure the network by specifying the VPC and the subnet id, skip the health check grace period section and Load balancing section as they are applicable only for service discovery with load balancer, jump directly into the service discovery section,
In the service discovery section, we will create a new namespace as test.net and the service discovery name as test-service. Our ECS service will be discoverable inside our VPC using http://test-service.test.net:port
I have specified the network type as AWSVPC in the task definition of the service, I will be able to create A records against the new namespace(test.net). TTL decides how long does a recordset should be cached in DNS resolver.
Once the above configurations are done, we can go to the next step.
Step 3: Next step is an optional step, here we can set up the autoscaling policy for our service,
Step 4: In the next step, review all your configurations and select create service.
Now we have created our ECS service with route 53 as our service discovery, let’s verify whether we have properly configured,
In the above image, we could confirm that our ECS service has spawned two container instance, both these containers have registered their IP’s in route 53. Now inside our VPC, we can reach the API service using http://test-service.test.net:8080
Achieving Service Discovery through Terraform
Step 1: In order to create service discovery for our ECS service through terraform, we need to create a private DNS namespace for our service,
Step 2: After creating a private DNS namespace, we need to associate this private DNS namespace with an aws_service_discovery_service resource,
Step 3: Finally we need to register our service discovery resource with our ECS service,
Now plan and apply your terraform changes, this will create your new ECS service with integrated service discovery.