OpenTofu 1.6: Revisiting Open-Source Terraform

Published: Feb 6, 2024 by Isaac Johnson

The last time we visited OpenTofu it had only recently been created. In that September post we compiled it ourselves to make a ‘v1.6.0-dev’ instance.

Since then, the team behind it has completed and released version 1.6.0. More importantly, it’s installable with all the normal tools like snap and brew.

Let’s install the latest stable version and try it locally then update a Github workflow to use it. We’ll wrap by updating our Github actions runner to leverage it as well.

Installing

The easiest way to install now is with homebrew or snap.

Presently, I have the self-compiled version in my path

$ which opentofu
/usr/local/bin/opentofu
$ opentofu --version
OpenTofu v1.6.0-dev
on linux_amd64

I’ll move that out

$ sudo mv /usr/local/bin/opentofu /usr/local/bin/opentofu.dev160
[sudo] password for builder:

Now I can install with Homebrew

$ brew update && brew install opentofu
Updated 6 taps (codefresh-io/cli, derailed/k9s, kdash-rs/kdash, f1bonacc1/tap, homebrew/core and homebrew/cask).
==> New Formulae
c3c                   halp                  k8sgpt                ncmdump               rattler-build         texi2mdoc             wasmedge
cargo-llvm-cov        helm-ls               kiota                 netsurf-buildsystem   ruby@3.2              urlscan               zigmod
csvlens               hopscotch-map         libnsbmp              pivit                 steamguard-cli        veilid                zipkin
doltgres              jot                   libwapcaplet          rathole               sugarjar              vulkan-volk
==> New Casks
aqua                      ia-presenter              markedit                  openthesaurus-deutsch     shadow-bot                wakatime
emby                      jyutping                  ollama                    pile                      streammusic               znote
geekbench-ml              lightburn                 opencat                   prettyclean               taccy
==> Outdated Formulae
alsa-lib                       gh                             kn                             little-cms2                    python-yq
argocd                         glib                           kubectx                        nettle                         python@3.10
azure-functions-core-tools@4   gnutls                         kubernetes-cli                 oniguruma                      python@3.11
ca-certificates                go                             kustomize                      opa                            pyyaml
cairo                          harfbuzz                       libevent                       openjdk@11                     sonar-scanner
cf2                            hugo                           libnghttp2                     openssl@1.1                    tfenv
cups                           icu4c                          libpthread-stubs               openssl@3                      unbound
devspace                       jpeg-turbo                     libtiff                        p11-kit                        util-linux
fontconfig                     jq                             libxml2                        popeye                         vault
gawk                           k9s                            libxrandr                      process-compose                yq
gettext                        kdash                          linux-headers@5.15             punq

You have 54 outdated formulae installed.
You can upgrade them with brew upgrade
or list them with brew outdated.
==> Downloading https://ghcr.io/v2/homebrew/core/opentofu/manifests/1.6.0
###################################################################################################################################################### 100.0%
==> Fetching dependencies for opentofu: linux-headers@5.15
==> Downloading https://ghcr.io/v2/homebrew/core/linux-headers/5.15/manifests/5.15.146
###################################################################################################################################################### 100.0%
==> Fetching linux-headers@5.15
==> Downloading https://ghcr.io/v2/homebrew/core/linux-headers/5.15/blobs/sha256:d4967ca0fb3dd5306243fa1847bc45f4edc23fa7c82d33ea86003c110ad5f975
###################################################################################################################################################### 100.0%
==> Fetching opentofu
==> Downloading https://ghcr.io/v2/homebrew/core/opentofu/blobs/sha256:b8c32b966c78cb27a15e3e68479db99a9437db13f55873613857730bef3bc143
###################################################################################################################################################### 100.0%
==> Installing dependencies for opentofu: linux-headers@5.15
==> Installing opentofu dependency: linux-headers@5.15
==> Downloading https://ghcr.io/v2/homebrew/core/linux-headers/5.15/manifests/5.15.146
Already downloaded: /home/builder/.cache/Homebrew/downloads/75fb62b0b21e3867f7a78d57ada24766cf4c50c7b6600ceb264bef26322c36a1--linux-headers@5.15-5.15.146.bottle_manifest.json
==> Pouring linux-headers@5.15--5.15.146.x86_64_linux.bottle.tar.gz
🍺  /home/linuxbrew/.linuxbrew/Cellar/linux-headers@5.15/5.15.146: 961 files, 5.7MB
==> Installing opentofu
==> Pouring opentofu--1.6.0.x86_64_linux.bottle.tar.gz
🍺  /home/linuxbrew/.linuxbrew/Cellar/opentofu/1.6.0: 6 files, 75.8MB
==> Running `brew cleanup opentofu`...
Disable this behaviour by setting HOMEBREW_NO_INSTALL_CLEANUP.
Hide these hints with HOMEBREW_NO_ENV_HINTS (see `man brew`).
==> `brew cleanup` has not been run in the last 30 days, running now...
Disable this behaviour by setting HOMEBREW_NO_INSTALL_CLEANUP.
Hide these hints with HOMEBREW_NO_ENV_HINTS (see `man brew`).
Removing: /home/builder/.cache/Homebrew/alsa-lib--1.2.10... (681.4KB)
Removing: /home/linuxbrew/.linuxbrew/Cellar/binutils/2.41... (4,729 files, 469MB)
Removing: /home/builder/.cache/Homebrew/binutils--2.41... (86.3MB)
Removing: /home/builder/.cache/Homebrew/ca-certificates--2023-08-22... (125.2KB)
Removing: /home/builder/.cache/Homebrew/dbus--1.14.10... (889.3KB)
Removing: /home/builder/.cache/Homebrew/devspace--6.3.5... (23MB)
Removing: /home/builder/.cache/Homebrew/devspace--6.3.7... (23MB)
Removing: /home/builder/.cache/Homebrew/freetype--2.13.2... (1MB)
Removing: /home/builder/.cache/Homebrew/gcc--13.2.0... (111.6MB)
Removing: /home/builder/.cache/Homebrew/gettext--0.22.3... (9.5MB)
Removing: /home/builder/.cache/Homebrew/gh--2.39.2... (10.2MB)
Removing: /home/builder/.cache/Homebrew/gh--2.40.1... (10.2MB)
Removing: /home/builder/.cache/Homebrew/glib--2.78.1... (7.2MB)
Removing: /home/builder/.cache/Homebrew/hugo--0.120.4... (20.0MB)
Removing: /home/builder/.cache/Homebrew/hugo--0.121.1... (19.9MB)
Removing: /home/builder/.cache/Homebrew/icu4c--73.2... (30.7MB)
Removing: /home/builder/.cache/Homebrew/jpeg-turbo--3.0.0... (1.4MB)
Removing: /home/builder/.cache/Homebrew/jq--1.7... (630.2KB)
Removing: /home/builder/.cache/Homebrew/k1s--0.1.2.tar.gz... (4.2KB)
Removing: /home/builder/.cache/Homebrew/krb5--1.21.2... (1.6MB)
Removing: /home/builder/.cache/Homebrew/kubernetes-cli--1.28.4... (14.9MB)
Removing: /home/builder/.cache/Homebrew/libedit--20230828-3.1... (244.8KB)
Removing: /home/builder/.cache/Homebrew/libpng--1.6.40... (499.0KB)
Removing: /home/builder/.cache/Homebrew/libxcrypt--4.4.36... (126.4KB)
Removing: /home/builder/.cache/Homebrew/libxml2--2.12.1... (2.4MB)
Removing: /home/linuxbrew/.linuxbrew/Cellar/linux-headers@5.15/5.15.140... (961 files, 5.7MB)
Removing: /home/linuxbrew/.linuxbrew/Cellar/linux-headers@5.15/5.15.145... (961 files, 5.7MB)
Removing: /home/builder/.cache/Homebrew/linux-headers@5.15--5.15.140... (1.5MB)
Removing: /home/builder/.cache/Homebrew/linux-headers@5.15--5.15.145... (1.5MB)
Removing: /home/builder/.cache/Homebrew/nettle--3.9.1... (1005KB)
Removing: /home/builder/.cache/Homebrew/opa--0.58.0... (9.4MB)
Removing: /home/builder/.cache/Homebrew/popeye--0.11.1.tar.gz... (13MB)
Removing: /home/builder/.cache/Homebrew/process-compose--0.75.1.tar.gz... (8.6MB)
Removing: /home/builder/.cache/Homebrew/python@3.10--3.10.13... (15.6MB)
Removing: /home/builder/.cache/Homebrew/python@3.11--3.11.6_1... (16.7MB)
Removing: /home/builder/.cache/Homebrew/pyyaml--6.0.1... (1.1MB)
Removing: /home/builder/.cache/Homebrew/sonar-scanner--5.0.1.3006... (575.2KB)
Removing: /home/builder/.cache/Homebrew/util-linux--2.39.2... (7.8MB)
Removing: /home/builder/.cache/Homebrew/xorgproto--2023.2... (696KB)
Removing: /home/builder/.cache/Homebrew/yq--4.40.3... (3.8MB)
Removing: /home/builder/.cache/Homebrew/zlib--1.3... (170.8KB)
Removing: /home/builder/.cache/Homebrew/devspace_bottle_manifest--6.3.3... (7.9KB)
Removing: /home/builder/.cache/Homebrew/openssl@3_bottle_manifest--3.1.2-1... (11KB)
Removing: /home/builder/.cache/Homebrew/glib_bottle_manifest--2.78.0... (13.3KB)
Removing: /home/builder/.cache/Homebrew/icu4c_bottle_manifest--73.2... (10.5KB)
Removing: /home/builder/.cache/Homebrew/libxcb_bottle_manifest--1.16... (15.0KB)
Removing: /home/builder/.cache/Homebrew/libnghttp2_bottle_manifest--1.56.0... (9.3KB)
Removing: /home/builder/.cache/Homebrew/util-linux_bottle_manifest--2.39.2... (9.0KB)
Removing: /home/builder/.cache/Homebrew/unbound_bottle_manifest--1.18.0_1... (12.2KB)
Removing: /home/builder/.cache/Homebrew/python-yq_bottle_manifest--3.2.3... (16.4KB)
Removing: /home/builder/.cache/Homebrew/kubernetes-cli_bottle_manifest--1.28.1... (7.3KB)
Removing: /home/builder/.cache/Homebrew/libpng_bottle_manifest--1.6.40... (9.9KB)
Removing: /home/builder/.cache/Homebrew/yq_bottle_manifest--4.35.1... (7.3KB)
Removing: /home/builder/.cache/Homebrew/libtiff_bottle_manifest--4.5.1... (9.8KB)
Removing: /home/builder/.cache/Homebrew/krb5_bottle_manifest--1.21.2... (11.4KB)
Removing: /home/builder/.cache/Homebrew/jq_bottle_manifest--1.7... (7.9KB)
Removing: /home/builder/.cache/Homebrew/sonar-scanner_bottle_manifest--5.0.1.3006... (3.9KB)
Removing: /home/builder/.cache/Homebrew/gnutls_bottle_manifest--3.8.1... (14.4KB)
Removing: /home/builder/.cache/Homebrew/vault_bottle_manifest--1.14.2... (7.7KB)
Removing: /home/builder/.cache/Homebrew/libx11_bottle_manifest--1.8.6... (13.9KB)
Removing: /home/builder/.cache/Homebrew/libxml2_bottle_manifest--2.11.5... (8.8KB)
Removing: /home/builder/.cache/Homebrew/nettle_bottle_manifest--3.9.1... (8.2KB)
Removing: /home/builder/.cache/Homebrew/openjdk_bottle_manifest--20.0.2... (23.4KB)
Removing: /home/builder/.cache/Homebrew/libxcrypt_bottle_manifest--4.4.36... (7.5KB)
Removing: /home/builder/.cache/Homebrew/python@3.12--3.12.0... (18MB)
Removing: /home/builder/.cache/Homebrew/ca-certificates_bottle_manifest--2023-08-22... (9.1KB)
Removing: /home/builder/.cache/Homebrew/hugo_bottle_manifest--0.118.2... (7.3KB)
Removing: /home/builder/.cache/Homebrew/gcc_bottle_manifest--13.2.0... (12.7KB)
Removing: /home/builder/.cache/Homebrew/alsa-lib_bottle_manifest--1.2.10... (1.9KB)
Removing: /home/builder/.cache/Homebrew/jpeg-turbo_bottle_manifest--3.0.0... (12.8KB)
Removing: /home/builder/.cache/Homebrew/opa_bottle_manifest--0.56.0... (7.3KB)
Removing: /home/builder/.cache/Homebrew/linux-headers@5.15_bottle_manifest--5.15.131... (1.9KB)
Removing: /home/builder/.cache/Homebrew/freetype_bottle_manifest--2.13.2-1... (10.4KB)
Removing: /home/builder/.cache/Homebrew/gh_bottle_manifest--2.34.0... (7.3KB)
Removing: /home/builder/.cache/Homebrew/zlib_bottle_manifest--1.3... (9.2KB)
Removing: /home/builder/.cache/Homebrew/python@3.10_bottle_manifest--3.10.13... (21.7KB)
Removing: /home/builder/.cache/Homebrew/cups_bottle_manifest--2.4.6-1... (8KB)
Removing: /home/builder/.cache/Homebrew/pyyaml_bottle_manifest--6.0.1... (7.8KB)
Removing: /home/builder/.cache/Homebrew/binutils_bottle_manifest--2.41... (11.7KB)
Removing: /home/builder/.cache/Homebrew/python@3.11_bottle_manifest--3.11.5... (21.8KB)
Removing: /home/builder/.cache/Homebrew/harfbuzz_bottle_manifest--8.2.0... (19.9KB)
Removing: /home/builder/.cache/Homebrew/xorgproto_bottle_manifest--2023.2... (14.2KB)
Removing: /home/builder/.cache/Homebrew/p11-kit_bottle_manifest--0.25.0... (9KB)
Removing: /home/builder/.cache/Homebrew/xz_bottle_manifest--5.4.4... (9.4KB)
Removing: /home/builder/.cache/Homebrew/dbus_bottle_manifest--1.14.10... (10.0KB)
Removing: /home/builder/.cache/Homebrew/python-argcomplete--3.1.6... (110.3KB)
Removing: /home/builder/.cache/Homebrew/sqlite_bottle_manifest--3.43.1... (8.1KB)
Removing: /home/builder/.cache/Homebrew/openjdk@11_bottle_manifest--11.0.20.1... (23.8KB)
Removing: /home/builder/.cache/Homebrew/libedit_bottle_manifest--20230828-3.1... (7.6KB)
Removing: /home/builder/.cache/Homebrew/mpfr_bottle_manifest--4.2.0-p12... (10KB)
Removing: /home/builder/.cache/Homebrew/Logs/dbus... (4.1KB)
Removing: /home/builder/.cache/Homebrew/Logs/process-compose... (4KB)
Removing: /home/builder/.cache/Homebrew/Logs/python@3.11... (2 files, 5.8KB)

(I thought) It wasn’t initially on my path, so i fixed the shell

$ brew shellenv
export HOMEBREW_PREFIX="/home/linuxbrew/.linuxbrew";
export HOMEBREW_CELLAR="/home/linuxbrew/.linuxbrew/Cellar";
export HOMEBREW_REPOSITORY="/home/linuxbrew/.linuxbrew/Homebrew";
export PATH="/home/linuxbrew/.linuxbrew/bin:/home/linuxbrew/.linuxbrew/sbin${PATH+:$PATH}";
export MANPATH="/home/linuxbrew/.linuxbrew/share/man${MANPATH+:$MANPATH}:";
export INFOPATH="/home/linuxbrew/.linuxbrew/share/info:${INFOPATH:-}";

$ echo 'eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"' >> $HOME/.bashrc
$ eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"

I then realized the name settled upon is “tofu” not “opentofu”.

$ which tofu
/home/linuxbrew/.linuxbrew/bin/tofu

Which shows the 1.6.0 (released) version

$ tofu version
OpenTofu v1.6.0
on linux_amd64

Github Runner

My Github Runner used the dev version initially as I purged out the BSL licensed binaries.

These steps are still useful for using the very latest OpenTofu.

# OpenTF

# Install Golang 1.19
RUN eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)" \
  && brew install go@1.19
#echo 'export PATH="/home/linuxbrew/.linuxbrew/opt/go@1.19/bin:$PATH"'

RUN git clone https://github.com/opentofu/opentofu.git /tmp/opentofu \
  && cd /tmp/opentofu && export PATH="/home/linuxbrew/.linuxbrew/opt/go@1.19/bin:$PATH" \
  && /home/linuxbrew/.linuxbrew/opt/go@1.19/bin/go install ./cmd/tofu

RUN sudo chown runner /usr/local/bin

RUN cd $(/home/linuxbrew/.linuxbrew/opt/go@1.19/bin/go env GOPATH) \
  && cd ./bin && pwd && export && cp ./tofu /usr/local/bin/

I’ll now change that block to still install Go Lang (still useful) but install Tofu via Homebrew

# Install Golang 1.19
RUN eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)" \
  && brew install go@1.19
#echo 'export PATH="/home/linuxbrew/.linuxbrew/opt/go@1.19/bin:$PATH"'

RUN eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)" \
  && brew install opentofu

RUN cp /home/linuxbrew/.linuxbrew/bin/tofu /usr/local/bin/

RUN sudo chown runner /usr/local/bin

In the end, I also needed to update my Bundler to fix the version to match my Ruby version

# save time per build
RUN umask 0002 \
  && gem install bundler -v 2.4.22

Rendering the final Dockerfile as

FROM summerwind/actions-runner:latest

RUN sudo apt update -y \
  && umask 0002 \
  && sudo apt install -y ca-certificates curl apt-transport-https lsb-release gnupg

# Install MS Key
RUN curl -sL https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/microsoft.gpg > /dev/null

# Add MS Apt repo
RUN umask 0002 && echo "deb [arch=amd64] https://packages.microsoft.com/repos/azure-cli/ focal main" | sudo tee /etc/apt/sources.list.d/azure-cli.list

# Install Azure CLI
RUN sudo apt update -y \
  && umask 0002 \
  && sudo apt install -y azure-cli awscli ruby-full

# Install Pulumi
RUN curl -fsSL https://get.pulumi.com | sh

# Install Homebrew
RUN /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

# OpenTF

# Install Golang 1.19
RUN eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)" \
  && brew install go@1.19
#echo 'export PATH="/home/linuxbrew/.linuxbrew/opt/go@1.19/bin:$PATH"'

RUN eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)" \
  && brew install opentofu

RUN sudo cp /home/linuxbrew/.linuxbrew/bin/tofu /usr/local/bin/

RUN sudo chown runner /usr/local/bin

RUN sudo chmod 777 /var/lib/gems/2.7.0

RUN sudo chown runner /var/lib/gems/2.7.0

# Install Expect and SSHPass

RUN sudo apt update -y \
  && umask 0002 \
  && sudo apt install -y sshpass expect

# save time per build
RUN umask 0002 \
  && gem install bundler -v 2.4.22

# Limitations in newer jekyll
RUN umask 0002 \
  && gem install jekyll --version="~> 4.2.0"
  
RUN sudo rm -rf /var/lib/apt/lists/*

#harbor.freshbrewed.science/freshbrewedprivate/myghrunner:1.1.16

One of my issues is it failed to push to my NAS hosted Docker registry. This was something I setup back in July

I immediately noticed the first issue; the certs had expired and I forgot about renewing them

/content/images/2024/02/opentofu-01.png

I needed to change, for a short bit, the 80/443 rules to forward to the NAS so it could engage with LE. This led me to the second issue, at some time in the last six months, the NAS moved IPs to .116 from .118. (that actually explains an NFS Provisioner issue as well, but we’ll come back to that later).

I forwarded 80/443 to the NAS

/content/images/2024/02/opentofu-02.png

Then chose to renew the cert in the Synology OS Certificate Management tab

/content/images/2024/02/opentofu-03.png

This sorted out the cert

/content/images/2024/02/opentofu-04.png

I also did the low-tech thing of dropping a calendar note so I won’t forget the next time

/content/images/2024/02/opentofu-05.png

Once I fix the destination, the Github build of the GH Runner image completed

/content/images/2024/02/opentofu-06.png

Next step, now that we have the image created, is to use it.

My internal endpoint is just for backups. So here (at this present moment I’m in Florida), I cannot view it

$ docker pull registry.freshbrewed.science:8443/freshbrewedprivate/myghrunner:1.1.16
Error response from daemon: error parsing HTTP 403 response body: invalid character '<' looking for beginning of value: "<!DOCTYPE html>\n<html>\n<head>\n<meta charset=\"utf-8\">\n<style>body{font-
...snip...
Sorry, the page you are looking...

/content/images/2024/02/ghimage-20.png

Note: though once back home within my own network, I could pull it from the NAS registry

$ docker pull registry.freshbrewed.science:8443/freshbrewedprivate/myghrunner:1.1.16
1.1.16: Pulling from freshbrewedprivate/myghrunner
7a2c55901189: Pull complete
86a15b8b43fd: Pull complete
899de82f73c8: Pull complete
3a7804f930bf: Pull complete
5ef23d707d32: Pull complete
8a92b0a07188: Pull complete
3cd94cb0993b: Pull complete
0083f7827ccc: Pull complete
ed1cc64a3a6c: Pull complete
4579b7542447: Pull complete
aad70dcdf9cf: Pull complete
b25b8a039516: Pull complete
2d8fff5f9f2e: Pull complete
e4eb98a09418: Pull complete
ec83ef1fa9e2: Pull complete
5f0ab36d8269: Pull complete
4fa851fa573e: Pull complete
353a3504c0bd: Extracting [============>                                      ]  58.49MB/232.3MB
6744a5d9324c: Download complete
4c128941d742: Downloading [========================================>          ]  96.71MB/120.3MB
be60f2561f9c: Downloading [=>                                                 ]  31.72MB/885.3MB
4f7af03eebcd: Downloading [====>                                              ]  5.283MB/53.36MB
0bfd6433096e: Waiting
cc34b4c02126: Waiting
a4e36d40893b: Waiting
b1f1ce2cd369: Waiting
f2477fce81f0: Waiting
0e7fae73cd25: Waiting
38bc2ff73624: Waiting
f6bf95c53988: Pulling fs layer

However, even while remote, I can see it from my Harbor registry

/content/images/2024/02/ghimage-21.png

Or I could also pull through the tgz via an ephemeral pod.

I just need to fire up an Ubuntu pod and add an SSH client

$  kubectl run my-shell2 -i --tty --image ubuntu -- bash
If you don't see a command prompt, try pressing enter.
root@my-shell2:/# apt update && apt install openssh-client -y

Then SFTP over to the NAS and get the tgz (transfer to the pod)

Processing triggers for libc-bin (2.35-0ubuntu3.6) ...
root@my-shell2:/# sftp ijohnson@sassynassy
The authenticity of host 'sassynassy (192.168.1.129)' can't be established.
ED25519 key fingerprint is SHA256:MuabaSeYR44fJqwzO9DF+6N4r4angX/aSdUyuwnCc7M.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'sassynassy' (ED25519) to the list of known hosts.
ijohnson@sassynassy's password:
Connected to sassynassy.
sftp> cd dockerBackup
sftp> ls
#recycle               myghrunner-1.1.11.tgz  myghrunner-1.1.12.tgz  myghrunner-1.1.13.tgz  myghrunner-1.1.14.tgz  myghrunner-1.1.16.tgz
myghrunner-1.1.9.tgz
sftp> get myghrunner-1.1.16.tgz
Fetching /dockerBackup/myghrunner-1.1.16.tgz to myghrunner-1.1.16.tgz
myghrunner-1.1.16.tgz                                                                                     7%  142MB  13.9MB/s   02:06 ETA

In another shell, I can use kubectl cp to get it to my laptop

$ kubectl cp my-shell2:/myghrunner-1.1.16.tgz  /tmp/myghrunner-1.1.16.tgz
tar: Removing leading `/' from member names

It was going very slow (guest wifi at the closest hotel to KSC on launch day along with VPN). However, before I killed the transfer, I could see it was coming down:

builder@LuiGi17:~$ ls -ltrah /tmp | grep myghrunner
-rw-r--r--  1 builder builder 101M Jan 18 06:09 myghrunner-1.1.16.tgz
builder@LuiGi17:~$ ls -ltrah /tmp | grep myghrunner
-rw-r--r--  1 builder builder 102M Jan 18 06:09 myghrunner-1.1.16.tgz
builder@LuiGi17:~$ ls -ltrah /tmp | grep myghrunner
-rw-r--r--  1 builder builder 104M Jan 18 06:09 myghrunner-1.1.16.tgz

That said, I do not need to pull it locally to use, I just need to update the GithubRunner image

We can see I have two

$ kubectl get runnerdeployment
NAME                          DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
new-tofurunner-deployment     1         1         1            1           111d
new-jekyllrunner-deployment   3         3         3            3           358d

The first one is tied to idjohnson/gcpimexample.

We can see the pod from when it was launched that last time

$ kubectl get pods -l runner-deployment-name=new-tofurunner-deployment
NAME                                    READY   STATUS    RESTARTS   AGE
new-tofurunner-deployment-qt9h8-9x6px   2/2     Running   0          104d

And that it was based on my last 1.1.15 image

$ kubectl get runnerdeployment new-tofurunner-deployment -o yaml | grep -i Image:
      image: harbor.freshbrewed.science/freshbrewedprivate/myghrunner:1.1.15

I’ll pull it down and update

builder@LuiGi17:~/Workspaces/jekyll-blog$ kubectl get runnerdeployment new-tofurunner-deployment -o yaml > new-tofurunner-deployment.yaml
builder@LuiGi17:~/Workspaces/jekyll-blog$ kubectl get runnerdeployment new-tofurunner-deployment -o yaml > new-tofurunner-deployment.yaml.bak
builder@LuiGi17:~/Workspaces/jekyll-blog$ vi new-tofurunner-deployment.yaml

see the change is what I expected

$ diff new-tofurunner-deployment.yaml new-tofurunner-deployment.yaml.bak
40c40
<       image: harbor.freshbrewed.science/freshbrewedprivate/myghrunner:1.1.16
---
>       image: harbor.freshbrewed.science/freshbrewedprivate/myghrunner:1.1.15

Then apply

$ kubectl apply -f ./new-tofurunner-deployment.yaml
runnerdeployment.actions.summerwind.dev/new-tofurunner-deployment configured

It took much longer than I would have thought to pull the image

$ kubectl get pods -l runner-deployment-name=new-tofurunner-deployment
NAME                                    READY   STATUS              RESTARTS   AGE
new-tofurunner-deployment-qt9h8-9x6px   2/2     Running             0          104d
new-tofurunner-deployment-62qwd-7r9n4   0/2     ContainerCreating   0          14s

$ kubectl get pods -l runner-deployment-name=new-tofurunner-deployment
NAME                                    READY   STATUS              RESTARTS   AGE
new-tofurunner-deployment-qt9h8-9x6px   2/2     Running             0          104d
new-tofurunner-deployment-62qwd-7r9n4   0/2     ContainerCreating   0          6m35s

$ kubectl get pods -l runner-deployment-name=new-tofurunner-deployment
NAME                                    READY   STATUS    RESTARTS   AGE
new-tofurunner-deployment-62qwd-7r9n4   2/2     Running   0          10m
new-tofurunner-deployment-qt9h8-9x6px   2/2     Running   0          104d

$ kubectl get pods -l runner-deployment-name=new-tofurunner-deployment
NAME                                    READY   STATUS    RESTARTS   AGE
new-tofurunner-deployment-62qwd-7r9n4   2/2     Running   0          10m

While it is large, it is worth noting that by using brew instead of compiling ourselves, we reduced the overall size by around 800 Mb.

/content/images/2024/02/ghimage-22.png

Let’s swap it up in the Example repo (last set to use Pulumi instead of Tofu).

builder@LuiGi17:~/Workspaces/gcpimexample$ git diff
diff --git a/.github/workflows/pulumi.yml b/.github/workflows/pulumi.yml
index 6063a6d..a6e7862 100644
--- a/.github/workflows/pulumi.yml
+++ b/.github/workflows/pulumi.yml
@@ -2,7 +2,7 @@ name: 'Pulumi'

 on:
   push:
-    branches: [ "main" ]
+    branches: [ "dontbuild" ]
   pull_request:

 permissions:
diff --git a/.github/workflows/tofu.yml b/.github/workflows/tofu.yml
index 159a56a..64daef1 100644
--- a/.github/workflows/tofu.yml
+++ b/.github/workflows/tofu.yml
@@ -2,7 +2,7 @@ name: 'Tofu'

 on:
   push:
-    branches: [ "dontbuild" ]
+    branches: [ "main" ]
   pull_request:

builder@LuiGi17:~/Workspaces/gcpimexample$ git add .github/workflows/
builder@LuiGi17:~/Workspaces/gcpimexample$ git commit -m "swap Pulumi with OpenTofu (release)"
[main 44eb553] swap Pulumi with OpenTofu (release)
 2 files changed, 2 insertions(+), 2 deletions(-)
builder@LuiGi17:~/Workspaces/gcpimexample$ git push
Enumerating objects: 11, done.
Counting objects: 100% (11/11), done.
Delta compression using up to 16 threads
Compressing objects: 100% (5/5), done.
Writing objects: 100% (6/6), 502 bytes | 502.00 KiB/s, done.
Total 6 (delta 3), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (3/3), completed with 3 local objects.
To https://github.com/idjohnson/gcpimexample.git
   dc3879e..44eb553  main -> main

I was reminded that I need to login and approve, a nice safety measure for an Open-Source project

/content/images/2024/02/ghimage-23.png

I can then approve and deploy

/content/images/2024/02/ghimage-24.png

I can see it start to deploy

/content/images/2024/02/ghimage-25.png

It threw an error because I already had created the bucket I asked it to make which is obviously errant

/content/images/2024/02/ghimage-26.png

I’ll change the bucketname and push

builder@LuiGi17:~/Workspaces/gcpimexample$ vi .github/workflows/tofu.yml
builder@LuiGi17:~/Workspaces/gcpimexample$ git diff .github/workflows/tofu.yml
diff --git a/.github/workflows/tofu.yml b/.github/workflows/tofu.yml
index 64daef1..e69f0c3 100644
--- a/.github/workflows/tofu.yml
+++ b/.github/workflows/tofu.yml
@@ -10,7 +10,7 @@ permissions:

 env:
   TF_VAR_projectid: myanthosproject2
-  TF_VAR_bucketname: mytestbucket223344
+  TF_VAR_bucketname: mytestbucket20240118

 jobs:
   tofu:
builder@LuiGi17:~/Workspaces/gcpimexample$ git add .github/workflows/tofu.yml
builder@LuiGi17:~/Workspaces/gcpimexample$ git commit -m 'change bucketname to 20240118'
[main f0e9bd6] change bucketname to 20240118
 1 file changed, 1 insertion(+), 1 deletion(-)
builder@LuiGi17:~/Workspaces/gcpimexample$ git push
Enumerating objects: 9, done.
Counting objects: 100% (9/9), done.
Delta compression using up to 16 threads
Compressing objects: 100% (4/4), done.
Writing objects: 100% (5/5), 443 bytes | 443.00 KiB/s, done.
Total 5 (delta 2), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (2/2), completed with 2 local objects.
To https://github.com/idjohnson/gcpimexample.git
   44eb553..f0e9bd6  main -> main

This time it succeeded

/content/images/2024/02/ghimage-27.png

And I can see the resulting bucket in GCP

/content/images/2024/02/ghimage-28.png

Summary

I had shared with others that I felt the anti-Open-Source move back in August by Hashicorp didn’t seem inline with Mitchell’s Open-Source ethos. Back in December, it was little surprise to me when he quit the company he helped found to pursue other endeavors.

When we first discussed OpenTofu it didn’t have its own registry. Now the OpenTofu Registry is full of modules and providers such as GCP and Azure.

I hope I don’t sound too harsh; Up until last August, I was a full Hashi fanboy. Even after that BUSL change, I went (for the 4th or 5th time) to Hashiconf 2023

/content/images/2024/02/20231010_144041.jpg

But the smell was different… It was not the same company. Things had changed. The announcements that would say “and this is all in the Open-Source version too!!” were gone. They didn’t even use the word “Open Source” to my recollection. All the “new things” were bolt-on premium features to the existing SaaS offerings (save for a nice terminal in Boundary).

I will stop bringing up Hashicorp as I talk about future OpenTofu releases. It is unhealthy. I don’t talk about reddit anymore either, nor X/Twatter. I moved on to Lemmy and Mastodon (and am trying BlueSky). For me to come back, I would need to see Hashicorp ditch the BSL/BUSL and I don’t think that is happening anytime soon. And with now forks of their other tools like OpenBao (for Vault) - and I would expect others for Packer soon too, it might be the train has left the station.

Github CICD Terraform OpenTofu Opensource

Have something to add? Feedback? You can use the feedback form

Isaac Johnson

Isaac Johnson

Cloud Solutions Architect

Isaac is a CSA and DevOps engineer who focuses on cloud migrations and devops processes. He also is a dad to three wonderful daughters (hence the references to Princess King sprinkled throughout the blog).

Theme built by C.S. Rhymes