Easier automation

Subscribe to our newsletter and never miss any upcoming articles

Listen to this article

A few weeks ago Justin Garrison tweeted:

When I try to do something new I’ve been following the same pattern for a decade

  1. Do it in the GUI at least once
  2. Do it manually in the CLI
  3. Automate it with a script or declarative tool like Terraform
  4. (If needed) build a declarative API for others to use

This roughly echoes my own approach to automation, but I've been noticing recently that sometimes I'm going straight to step 3 without even trying 1 & 2.

An example would be multi architecture builds for Docker images. We've been doing x86_64 builds for a while, but we also wanted to do 32bit and 64bit Arm for Raspberry Pis, Apple M1, AWS Graviton etc.

We were already using a GitHub Action to create the x86_64 image, and to get that working from the boilerplate below needed just a couple of things:

  1. Create the secrets for DOCKERHUB_USERNAME and DOCKERHUB_TOKEN
  2. Fill in the appropriate accountname, imagename and tagname for the tags: line
name: Docker

on:
  workflow_dispatch:

jobs:
  docker:
    runs-on: ubuntu-latest
    steps:
      -
        name: Set up QEMU
        uses: docker/setup-qemu-action@v1
      -
        name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v1
      -
        name: Login to DockerHub
        uses: docker/login-action@v1 
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}
      -
        name: Build and push
        id: docker_build
        uses: docker/build-push-action@v2
        with:
          push: true
          tags: accountname/imagename:tagname
      -
        name: Image digest
        run: echo ${{ steps.docker_build.outputs.digest }}

To get the Action to make Arm images too all I needed to add was a platforms section after tags:

          tags: |
            accountname/imagename:tagname
            accountname/imagename:latest
            accountname/imagename:GHA${{ github.run_number }}
          platforms: |
            linux/amd64
            linux/arm/v7
            linux/arm64/v8

You'll see that I also added some extra stuff to the tags there to get :latest and a tag associated with the Action run number.

And that's all that was needed. Without ever trying to create a multi-arch image manually, I pressed the run button and it made me images for all 3 architectures. I can't actually imagine how doing it manually would be any easier - even for one iteration never mind for a repeatable system.

NB: I'm using on: workflow_dispatch: here whilst I test the Action, but soon enough it will be plumbed into the pipeline and running without human touch.

We are changing the Internet for good. Join us on

and code with us.

No Comments Yet