Search code examples
amazon-web-servicesamazon-ecsservice-discoveryaws-fargate

Get service Name of Task under aws fargate


We need to get the service name under which a fargate task runs so we can perform some per service configuration (we have one service per customer, and use the service name to identify them).

By knowing the service discovery namespace for our cluster and the Task IP address, we are able to do find out the service by doing the following.

  1. Get the task ip address, eaither by calling http://169.254.170.2/v2/metadata endpoint or by using the ECS_ENABLE_CONTAINER_METADATA method in my follow-up answer.
  2. With the cluster namespace we call AWS.ServiceDiscovery.listNamespaces From there we extract the nameSpace id.
  3. We pass that to AWS.ServiceDiscovery.listServices
  4. We pass the id of each service to AWS.ServiceDiscovery.listInstances
  5. We flat map the results of that and look for an instance that matches our IP address above.

Voilà! that record gives us the service name.

Works fine, it just seems like a super circuitous path! I'm just wondering whether there is some shorter way to get this information.


Solution

  • Here's a working C# example in two steps. It gets the taskARN from the metadata to retrieve the task description, and then reads its Group property, which contains the name of the service. It uses AWSSDK.ECS to get the task description and Newtonsoft.Json to parse the JSON.

        private static string getServiceName()
        {
            // secret keys, should be encoded in license configuration object
            var ecsClient = new AmazonECSClient( ACCESS_KEY, SECRET_KEY );
            var request = new DescribeTasksRequest();
            // need cluster here if not default
            request.Cluster = NAME_OF_CLUSTER;
            request.Tasks.Add( getTaskArn() );
            var asyncResponse = ecsClient.DescribeTasksAsync( request );
            // probably need this synchronously for application to proceed
            asyncResponse.Wait();
            var response = asyncResponse.Result;
            string group = response.Tasks.Single().Group;
            // group returned in the form "service:[NAME_OF_SERVICE]"
            return group.Remove( 0, 8 );
        }
    
        private static string getTaskArn()
        {
            // special URL for fetching internal Amazon information for ECS instances
            string url = @"http://169.254.170.2/v2/metadata";
            string metadata = getWebRequest( url );
            // use JObject to read the JSON return
            return JObject.Parse( metadata )[ "TaskARN" ].ToString();
        }
    
        private static string getWebRequest( string url )
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create( url );
            request.AutomaticDecompression = DecompressionMethods.GZip;
            using HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            using Stream stream = response.GetResponseStream();
            using StreamReader reader = new StreamReader( stream );
            return reader.ReadToEnd();
        }