bash - clusters - How to find out which ECS cluster is associated to an ALB

aws ecs service (1)

We run an ECS cluster behind an ELB (ALB, to be specific).

I have a process that allows me to find out which ECS cluster is associated with the ALB by querying the ALB and tracing the results back through the target group and then instances:

Here is the bash script:

ELB_NAME=$(aws route53 list-resource-record-sets --hosted-zone-id <Zone-ID> | jq -r --arg URL "$URL"'.ResourceRecordSets[]|select(.Name==$URL)|.AliasTarget.DNSName')

ELB_NAME=$(echo $ELB_NAME | cut -f 2- -d "." | rev | cut -f 2- -d "." | rev)

ELB_ARN=$(aws elbv2 describe-load-balancers | jq -r --arg ELB_NAME "$ELB_NAME" '.LoadBalancers[]|select((.DNSName|ascii_downcase)==$ELB_NAME)|.LoadBalancerArn')

TG_ARNS=$(aws elbv2 describe-target-groups | jq -r --arg ELB_ARN "$ELB_ARN" '.TargetGroups[]|select(.LoadBalancerArns[]==$ELB_ARN)|.TG_ARN=$(echo $TG_ARNS | cut -f 1 -d " ")

INSTANCE_ID=$(aws elbv2 describe-target-health --target-group-arn $TG_ARN | jq -r '.TargetHealthDescriptions[].Target.Id' | head -n 1)

CLUSTER=$(aws ec2 describe-instances --instance-ids $INSTANCE_ID | jq -r '.Reservations[].Instances[].Tags[]|select(.Key=="aws:cloudformation:stack-name")|.Value' | cut -f 2 -d "-")

The problem I have is that when there are no running instances associated with the ECS cluster, I can no longer query them for the the tag that returns the Cloudformation stack name, the request for the targets from the target group is empty.

How can I use the AWS API so that I can determine which ECS cluster the ALB would target if it had running instances?

It's not really clear what you're asking for, or indeed the purpose you are trying to achieve, but the following should set you on the right track.

An ECS "cluster" is really just an Amazon service, when you create a cluster nothing is really provisioned. You can think of an empty cluster as a record or a placeholder in the ECS service.

In order to do anything with a cluster, it needs instances. When you boot an EC2 machine from a supported AMI, appropriate IAM role and the cluster name written to a config file, the instance will join the cluster. (If you create a cluster via the AWS console, a CloudFormation template is created that handles the provisioning and orchestration of these steps.) The ECS cluster management can then schedule tasks and services onto that instance as you have defined in the ECS service.

Without any instances, there can be no listening containers, therefore there can be no target groups in your ALB that route to anything. So it is not possible to get from the ELB to the cluster... as you have asked when there are no running instances.

You might find the following commands are a better way of determining whether or not you have a running cluster.

First, use the list-clusters command to show which clusters are available:

aws ecs list-clusters 
    "clusterArns": [

Then use the output from that to show if there are any EC2 instances registered to the cluster:

aws ecs describe-clusters --clusters your_cluster
    "clusters": [
            "status": "ACTIVE", 
            "statistics": [], 
            "clusterName": "your_cluster", 
            "registeredContainerInstancesCount": 1, 
            "pendingTasksCount": 0, 
            "runningTasksCount": 0, 
            "activeServicesCount": 0, 
            "clusterArn": "arn:aws:ecs:eu-west-1:XXXXXXXXX:cluster/your_cluster"
    "failures": []

Note the registeredContainerInstancesCount property shows the number of running instances. I assume you have your ECS services set to register tasks (containers) with the ALB, so when the count is greater than 0, this will be possible.

So, querying that property should tell you if your cluster is "on" or not:

if [[ $(aws ecs describe-clusters --clusters your_cluster | jq -r '.clusters[].registeredContainerInstancesCount') -gt 0 ]] ; then 
  echo "cluster is on"
  echo "cluster is off"