Skip to content

feat(tfenv): allow installing a custom Terraform version using tfenv#178

Open
FalcoSuessgott wants to merge 1 commit intopatrickchugh:mainfrom
FalcoSuessgott:tenv
Open

feat(tfenv): allow installing a custom Terraform version using tfenv#178
FalcoSuessgott wants to merge 1 commit intopatrickchugh:mainfrom
FalcoSuessgott:tenv

Conversation

@FalcoSuessgott
Copy link

@FalcoSuessgott FalcoSuessgott commented Mar 23, 2026

Currently terravision hardodes the TF version in its Dockerfile. This makes it difficult to use terravision with TF setups that differ from the upstream image versions.

This PR adds tfenv to the Dockerfile and invokes tfenv only when TFENV_TERRAFORM_VERSION has been specified, which then downloads and installs the specified TF version before invoking terravision:

Example: specifying no custom Terraform version:

> docker run -e TFENV_TERRAFORM_VERSION=1.13.0 test draw --source .
Installing Terraform v1.13.0
Downloading release tarball from https://releases.hashicorp.com/terraform/1.13.0/terraform_1.13.0_linux_amd64.zip
######################################################################## 100.0%
Downloading SHA hash file from https://releases.hashicorp.com/terraform/1.13.0/terraform_1.13.0_SHA256SUMS
Not instructed to use Local PGP (/home/terravision/.tfenv/use-{gpgv,gnupg}) & No keybase install found, skipping OpenPGP signature verification
terraform_1.13.0_linux_amd64.zip: OK
Archive:  /tmp/tfenv_download.JIDCBm/terraform_1.13.0_linux_amd64.zip
  inflating: /home/terravision/.tfenv/versions/1.13.0/LICENSE.txt  
  inflating: /home/terravision/.tfenv/versions/1.13.0/terraform  
Installation of terraform v1.13.0 successful. To make this your default version, run 'tfenv use 1.13.0'
Switching default version to v1.13.0
Default version (when not overridden by .terraform-version or TFENV_TERRAFORM_VERSION) is now: 1.13.0


 _____                          _     _             
/__   \___ _ __ _ __ __ ___   _(_)___(_) ___  _ __  
  / /\/ _ \ '__| '__/ _` \ \ / / / __| |/ _ \| '_ \ 
 / / |  __/ |  | | | (_| |\ V /| \__ \ | (_) | | | |
 \/   \___|_|  |_|  \__,_| \_/ |_|___/_|\___/|_| |_|



Preflight check..
  dot command detected: /usr/bin/dot
  gvpr command detected: /usr/bin/gvpr
  git command detected: /usr/bin/git
  terraform command detected: /home/terravision/.tfenv/bin/terraform
  terraform version detected: Terraform v1.13.0
...

Example: specifying a custom Terraform version:

> docker run test draw --source .
docker run test draw --source .
Alias tip: d run test draw --source .


 _____                          _     _             
/__   \___ _ __ _ __ __ ___   _(_)___(_) ___  _ __  
  / /\/ _ \ '__| '__/ _` \ \ / / / __| |/ _ \| '_ \ 
 / / |  __/ |  | | | (_| |\ V /| \__ \ | (_) | | | |
 \/   \___|_|  |_|  \__,_| \_/ |_|___/_|\___/|_| |_|



Preflight check..
  dot command detected: /usr/bin/dot
  gvpr command detected: /usr/bin/gvpr
  git command detected: /usr/bin/git
  terraform command detected: /usr/local/bin/terraform
  terraform version detected: Terraform v1.10.5
...

Signed-off-by: Tom Morelly <tom.morelly@clearroute.io>
Copy link
Owner

@patrickchugh patrickchugh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR! I understand the problem — being locked to a single Terraform version in the Docker image is limiting. However, I have some concerns with the tfenv approach and would suggest a simpler alternative.

Concerns

  1. Image bloat for all users — cloning the tfenv repo and adding bash (Alpine defaults to sh) increases the image size for everyone, even those who never use this feature.

  2. Runtime downloads are fragiletfenv install hits HashiCorp's servers on every docker run. This breaks in air-gapped environments, adds startup latency, and is subject to network failures.

  3. Entrypoint wrapper — replacing the clean ENTRYPOINT ["terravision"] with a shell script affects signal handling and adds a layer of indirection for debugging.

Suggested alternative

Since Terraform is a single static binary, a build-time ARG achieves the same goal without any runtime dependencies:

ARG TERRAFORM_VERSION=1.10.5
RUN wget -q https://releases.hashicorp.com/terraform/${TERRAFORM_VERSION}/terraform_${TERRAFORM_VERSION}_linux_amd64.zip \
    && unzip terraform_${TERRAFORM_VERSION}_linux_amd64.zip -d /usr/local/bin/ \
    && rm terraform_${TERRAFORM_VERSION}_linux_amd64.zip

Usage:

docker build --build-arg TERRAFORM_VERSION=1.13.0 -t terravision .

This keeps the image lean, works offline after build, and doesn't require tfenv, bash, or an entrypoint script.

Would you be open to reworking the PR with this approach?

@FalcoSuessgott
Copy link
Author

  1. Image bloat for all users — cloning the tfenv repo and adding bash (Alpine defaults to sh) increases the image size for everyone, even those who never use this feature.

Image size when building terravision including the changes in this PR: 746MB
Image size when building terravision on current main: 743MB

I think that's a good trade-off given the fact that now users can specify their own TF version.

  1. Runtime downloads are fragile — tfenv install hits HashiCorp's servers on every docker run. This breaks in air-gapped environments, adds startup latency, and is subject to network failures.

Users can specify a local HTTP server to fetch the binaries from by simply specifying TFENV_REVERSE_REMOTE allowing it to be used in air gapped environments

  1. Entrypoint wrapper — replacing the clean ENTRYPOINT ["terravision"] with a shell script affects signal handling and adds a layer of indirection for debugging.

I don't understand how overwriting the ENTRYPOINT to a docker-entry point script (which just passes through all args to terravision), affects troubleshooting. However I see your point regarding signal handling (even though I don't think that terravision is handling signals currently either). But we could use something like https://github.com/krallin/tini to ensure proper signal handling

Since Terraform is a single static binary, a build-time ARG achieves the same goal without any runtime dependencies:

The point of this PR is to allow users specify their own TF version without having to build, publish & maintain a custom container image of terravision by using tfenv the de-facto standards tool for managing multiple TF versions. As of now this tool hardcoded TF version 1.10.5 (mind you the latest version 1.14.7). For every user that is not using 1.10.5, this tool is unusable. Especially because this tool is designed to run in CI, I think many users will restrain from using it simply because their version doesn't allow them and they don't want to either downgrade their TF projects or manage another Container image. This PR aims to solve that problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants