Skip to content

Build and Use a Custom Runner Image

To build a custom runner image, you need a Dockerfile that extends the base image and that adds OpenTofu (plus any additional required tooling).

The repository that contains the base images is here.

All base image tags follow the following format: ${TF_CONTROLLER_VERSION}-base.

Prerequisites

You need Docker and Git to build the image.

Build the Image

  1. Create a Dockerfile that extends the base image and that adds the OpenTofu binary, plus any additional required tooling. For example:

    ARG BASE_IMAGE
    ARG TOFU_VERSION=1.11.3
    
    FROM ghcr.io/opentofu/opentofu:${TOFU_VERSION}-minimal AS tofu
    
    FROM $BASE_IMAGE
    
    COPY --from=tofu /usr/local/bin/tofu /usr/local/bin/tofu
    
    # Switch back to the non-root user after operations
    USER 65532:65532
    

    Find the original Dockerfile for the runner here.

  2. Build the image from the directory containing the Dockerfile you created above:

    export TF_CONTROLLER_VERSION=v0.16.0-rc.8
    export TOFU_VERSION=1.11.3
    export BASE_IMAGE=ghcr.io/flux-iac/tf-runner:${TF_CONTROLLER_VERSION}-base
    export REMOTE_REPO=ghcr.io/my-org/custom-runnner
    docker build \
        --build-arg BASE_IMAGE=${BASE_IMAGE} \
        --build-arg TOFU_VERSION=${TOFU_VERSION} \
        --tag my-custom-runner:${TF_CONTROLLER_VERSION} .
    docker tag my-custom-runner:${TF_CONTROLLER_VERSION} $REMOTE_REPO:${TF_CONTROLLER_VERSION}
    docker push $REMOTE_REPO:${TF_CONTROLLER_VERSION}
    

    Replace the relevant values above with the corresponding values in your organisation/implementation.

  3. Update the values.runner.image values in the Tofu Controller Helm chart values to point to the new image:

    values:
      runner:
        image:
          repository: ghcr.io/my-org/custom-runnner
          tag: v0.16.0-rc.3
    
  4. Commit and push the changes to Git. Confirm that the HelmRelease has been updated:

    kubectl get deployments.apps -n flux-system tofu-controller -o jsonpath='{.spec.template.spec.containers[*]}' | jq '.env[] | select(.name == "RUNNER_POD_IMAGE")'
    {
      "name": "RUNNER_POD_IMAGE",
      "value": "ghcr.io/my-org/custom-runner:v0.16.0-rc3"
    }
    

References

A set of GitHub actions in the Tofu Controller community repo facilitates a process similar to the above, but uses GitHub Actions to build and push the image.