DEV Community

schollii
schollii

Posted on

Using jq to find the latest master tag of an AWS ECR repository

Lately I've had to use jq a few times and got to understand the power of its pipe system. Here is an example of how to get the latest docker image tag in a specific docker repo of AWS ECR.

Firstly you have to know that aws ecr describe-images --repository-name $repo_name returns a json object which consists of a list of objects, each object looks like this:

  {
    "registryId": ...,
    "repositoryName": ...,
    "imageDigest": "sha256:...",
    "imageTags": [
      "..."
    ],
    "imageSizeInBytes": ...,
    "imagePushedAt": ...,
    "imageManifestMediaType": "application/...",
    "artifactMediaType": "application/..."
  }
Enter fullscreen mode Exit fullscreen mode

Not all objects have an imageTags.

Further requirements:

  • I don't want objects that have a non-master-branch tag (they have "dev" in their tag)
  • I am only interested in the first tag of each object
  • I want to output the tag in a form that I can consume in a script later, in my case REPO_NAME=tag where REPO_NAME is an environment variable.

Here is the code:

aws ecr describe-images --repository-name $repo_name  | jq '.[] | map(select(has("imageTags"))) | sort_by(.imagePushedAt) | map(select(.imageTags[0] | contains("dev") | not)) | .[-1] | [(.repositoryName | gsub("-";"_") | ascii_upcase), .imageTags[0]] | join("=")'
Enter fullscreen mode Exit fullscreen mode

I explain each line (the following block of code will not run as-is due to the comments; use the above snippet instead):

  repo_name=...
  aws ecr describe-images --repository-name $repo_name | 
    # don't want quotes around the final output so -r:
    jq -r '
    # loop over all objects of the list:
    .[] 
    # select those that have imageTags:
    | map(select(has("imageTags")))
    # filter out those that have "dev" in their tag:
    | map(select(.imageTags[0] | contains("dev") | not))
    # sort remaining ones by push date:
    | sort_by(.imagePushedAt)
    # keep only the most recent one
    | .[-1] 
    # create pair based on fields of the selected object
    | [
         # 1st is env var name for the repo: all upper, and underscores:
         (.repositoryName | gsub("-"; "_") | ascii_upcase), 
         # 2nd is the tag itself:
         .imageTags[0]
      ]
    # format items of the pair into ENV_VAR_NAME=tag:
    | join("=")'
Enter fullscreen mode Exit fullscreen mode

Example output:

MY_REPO_NAME=2021.03.22-9941301
Enter fullscreen mode Exit fullscreen mode

Top comments (0)