Renovate vs. Terraform required_version

If you use renovate to receive MR for updates on Terraform/Tofu-providers, you would usually also ensure the lock-files are updated.

Inside the renovate configuration could be items like this to ensure the lock-files are updated:

  "postUpdateOptions": [
    "terraformLockFiles"
  ],

Most likely you would like to have also this configuration, to prevent constant updates of required_version. I’ll explain now why.

  "packageRules": [
    {
      "description": "Disable Terraform required_version updates - keep minimum version as is",
      "matchDatasources": [
        "github-releases",
        "github-tags",
        "terraform-provider"
      ],
      "matchManagers": [
        "terraform"
      ],
      "matchDepTypes": [
        "required_version"
      ],
      "enabled": false
    },

Why?

  • Because maybe you do not always know the exact version of the executing Terraform/Tofu-version.
  • The update only creates unneccessary changes or updates and is in 99% percent of all cases completely useless.
  • The update could create malfunctions.

Malfunctions?

Terraform and OpenTofu are both highly backwards compatible. The latest bigger changes in behaviour and syntax happened years ago, with version 0.12 of Terraform.

Both tools are constantly improved and extended while keeping compatibility.

Let us now take a look at what I found:

I had a repository with required_version = "~> 1.11" configured. In this repository the TF-lockfiles were not updated together with the Terraform-provider and renovate logged something like “dependency update failed, external host error”.

At the same time all other repositories with Terraform worked perfectly fine with renovate.

Some analysis showed, that renovate uses internally a Terraform version OLDER than the required_version = "~> 1.11".

This could explain why this dependency management / lock-file generation fails.

Tuning our repository to use required_version = "~> 1.5" and rebasing the renovate-MR on the update main-branch showed: lock-files are updated!

Baseline

Set your required_version in Terraform / Tofu to a conservative value.

Thank you, renovate!


There seems to be some alternative configuration for renovate.json:

  "binarySource": "install",
  "constraints": {
    "terraform": "1.11.0",
    "opentofu": "1.6.2"
  },

This apparently should make renovate install distinct TF-versions at runtime, and I suppose it currently does this as well (without the explicit config)!

Of course this raises some general thoughts about security and control.


Until now I couldn’t trace down how renovate actually installs Terraform in the renovate repository.

The Terraform binaries are not in the container base-images of renovate, neither in the source-code nor in the container image (tag: renovate/renovate:43-full).

But inside the container image is a file /usr/local/containerbase/tools/v2/terraform.sh, that has this content:

#!/bin/bash

function install_tool () {
  local versioned_tool_path
  local file
  local arch=linux_amd64

  if [[ "$(uname -p)" = "aarch64" ]]; then
    arch=linux_arm64
  fi

  file=$(get_from_url "https://releases.hashicorp.com/terraform/${TOOL_VERSION}/terraform_${TOOL_VERSION}_${arch}.zip")

  versioned_tool_path=$(create_versioned_tool_path)
  create_folder "${versioned_tool_path}/bin"

  bsdtar -C "${versioned_tool_path}/bin" -xf "${file}"
}

function link_tool () {
  local versioned_tool_path
  versioned_tool_path=$(find_versioned_tool_path)

  shell_wrapper "${TOOL_NAME}" "${versioned_tool_path}/bin"
  terraform version
}

But there’s no real trace (for me) about the source of the actual Terraform version.