When running containerized services in Elastic Container Service (ECS), it's often important to know which environment you're running in. While environment variables can be useful to store deployment-related information, knowing the current cluster, task definition, and revision, or simply the availability zone, can prove vital when monitoring your running service instances.
Specifically for this case, AWS exposes a local metadata endpoint in every container scheduled on AWS Fargate or EC2 using the Amazon ECS container agent. Depending on the Fargate or ECS container agent version you're using, you will be able to access different versions of the metadata endpoint.
As accessing the endpoint programmatically involves a few steps, I've created wrapper in Go, which will send a request to the task metadata endpoint, and deserialize the response into a struct. Out of the box, it supports both version 3 and 4 of the metadata endpoints, so the majority of users are covered already: If your environment supports version 4, you'll get that, otherwise, you'll receive version 3.
package main
import (
"context"
"github.com/brunoscheufler/aws-ecs-metadata-go"
"log"
"net/http"
)
func main() {
client := &http.Client{}
// Fetch ECS Task metadata from environment
meta, err := metadata.Get(context.Background(), client)
if err != nil {
panic(err)
}
// Based on the Fargate platform version, we'll have access
// to v3 or v4 of the ECS Metadata format
switch m := meta.(type) {
case *metadata.TaskMetadataV3:
log.Printf("%s %s:%s", m.Cluster, m.Family, m.Revision)
case *metadata.TaskMetadataV4:
log.Printf(
"%s(%s) %s:%s",
m.Cluster,
m.AvailabilityZone,
m.Family,
m.Revision,
)
}
}
And that's all you have to do. With this, you'll know exactly which cluster you're running in, and more specifically, which version of your service you're running on. You can even use details such as the Docker Image Tag to enrich logs and metrics.