Robert Moskal
Robert Moskal

Reputation: 22553

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.

Upvotes: 2

Views: 3427

Answers (3)

Aaron Haspel
Aaron Haspel

Reputation: 340

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();
    }

Upvotes: 3

Robert Moskal
Robert Moskal

Reputation: 22553

The answer above requires reading the container metadata that appears if you set the ECS_ENABLE_CONTAINER_METADATA environment variable in the task. The work flow is then:

  1. Read the container metadata file ecs-container-metadata.json to get the taskArn
  2. Call the aws.ecs.describe-tasks function to get the startedBy property
  3. Call aws.servicediscover.get-service.

Two steps instead of three, if you don't count reading the metadata file. Better, to be sure, but I'm probably not going to change the way we do it for now.

Upvotes: 0

marianogg9
marianogg9

Reputation: 194

You can get the service name from startedBy property of the task definition. Using boto sdk you can call a describe_tasks (or its equivalent in aws-cli: aws ecs describe-tasks) which will provide a

'startedBy': 'string'

The tag specified when a task is started. If the task is started by an Amazon ECS service, then the startedBy parameter contains the deployment ID of the service that starts it.

From:

Hope it helps.

Upvotes: 1

Related Questions