Skip to content

Feature/opentofu support#199

Merged
patrickchugh merged 3 commits into
patrickchugh:mainfrom
dhararon:feature/opentofu-support
Jun 6, 2026
Merged

Feature/opentofu support#199
patrickchugh merged 3 commits into
patrickchugh:mainfrom
dhararon:feature/opentofu-support

Conversation

@dhararon
Copy link
Copy Markdown
Contributor

@dhararon dhararon commented Jun 1, 2026

feat(engine): add OpenTofu support via --engine flag

Type of Change

  • Bug Fix
  • New Feature
  • Refactor
  • Documentation

Summary

Adds first-class OpenTofu support as a drop-in alternative to
Terraform. Terraform and OpenTofu share an identical CLI for every subcommand TerraVision
relies on (init, workspace, plan, show -json, graph, -v), so the only real
difference is the executable name.

What changed

  • New binary resolver in helpers.py (set_tf_binary() / get_tf_binary()):
    auto prefers terraform on PATH and falls back to tofu, or the engine can be forced.
  • Replaced the 9 hardcoded "terraform" invocations across tfwrapper.py and
    tgwrapper.py with the resolved binary.
  • Generalised check_terraform_version() / check_dependencies() to report the active
    engine (both Terraform and OpenTofu are v1.x, so the existing major-version check holds).
  • Exposed --engine [auto|terraform|tofu] on the draw, visualise and graphdata commands.

Why
Many teams have migrated from Terraform to OpenTofu after the licence change. Previously the
binary name was hardcoded, so TerraVision could not run against an OpenTofu-only toolchain.
This is a low-risk change because the two CLIs are command-compatible.

Manual verification
Ran draw end-to-end with --engine tofu (OpenTofu v1.12.1) against a credential-free AWS
fixture — tofu init/plan/show -json/graph all executed correctly and a valid architecture
diagram was rendered.

Terragrunt note: the direct init/show/graph calls in tgwrapper.py now honour
--engine tofu, but Terragrunt invokes its own configured binary internally. To make
Terragrunt drive OpenTofu, also set TG_TF_PATH=tofu (documented in the usage guide).

Checklist

All Submissions:

  • Have you checked to ensure there aren't other open Pull Requests for the same
    update/change?
  • Have you written Documentation/Tests?
  • Have you done your own code-review?
  • Have you disclosed any use of AI tools and models with their version?

AI Assistance Declaration

  • Tools used: Claude Code
  • Model: Claude Opus 4.8 (1M context)
  • Scope: wrote the BDD unit tests for the resolver.

Checklist for Changes to Core Features:

  • Have you discussed any major revamp with a reviewer/maintainer first? (Minor, additive change —
    defaults to auto, so existing Terraform behaviour is unchanged.)
  • Have you ensured your PR is focused on one major improvement and is not trying to do too many changes
    at once?
  • Have you added an explanation of what your changes do and why you'd like us to include them?
  • Have you written new tests for your core changes, as applicable, and made sure the new tests PASS? (7
    BDD scenarios in tests/helpers_unit_test.py, 15/15 pass.)
  • Have you successfully run all previous system wide tests with your changes locally?
    (470 passed. The 34 failures are pre-existing and environment-specific — my local
    terraform is a tenv wrapper with no version installed, so terraform -v exits 42 and
    the integration/visualise tests that shell out to the CLI fail at preflight. Verified the
    identical failures on upstream main (b06b9c1) without my changes, so they are not a
    regression. The new resolver tests pass 15/15 and black --check modules is clean.)

dhararon added 3 commits June 1, 2026 17:43
Terraform and OpenTofu share an identical CLI for the subcommands
Terravision relies on (init, workspace, plan, show -json, graph), so the
only difference is the executable name.

Centralise binary resolution in helpers.set_tf_binary()/get_tf_binary():
'auto' prefers terraform on PATH and falls back to tofu, or the engine can
be forced. Replace the nine hardcoded "terraform" invocations across
tfwrapper.py and tgwrapper.py with the resolved binary, generalise
check_terraform_version()/check_dependencies(), and expose --engine
[auto|terraform|tofu] on the draw, visualise and graphdata commands. The
flag also reads the TERRAVISION_ENGINE environment variable, which lets CI
and OpenTofu-only hosts select the engine without a terraform binary.
Add BDD scenarios for set_tf_binary()/get_tf_binary(): explicit
terraform/tofu selection, case-insensitive engine names, and auto
detection preferring terraform, falling back to tofu, and defaulting to
terraform when neither is on PATH. PATH is mocked at the shutil.which
boundary.
Add the --engine option to the draw, visualise and graphdata option
tables and an OpenTofu section covering autodetection, forcing an engine,
the TERRAVISION_ENGINE environment variable, the v1.x requirement, and the
Terragrunt TG_TF_PATH caveat.
@dhararon dhararon mentioned this pull request Jun 1, 2026
@patrickchugh patrickchugh merged commit 96fb68e into patrickchugh:main Jun 6, 2026
1 check passed
@patrickchugh
Copy link
Copy Markdown
Owner

Very grateful for your PR @dhararon - I also made another set of cosmetic changes after merging your PR where errors messages mention terraform, and now they fetch the binary name and say tofu or terraform as appropriate.

pull Bot pushed a commit to TheTechOddBug/terravision that referenced this pull request Jun 6, 2026
Status banners and error messages in tfwrapper, tgwrapper, and
validators still hardcoded "terraform" after the --engine flag was added
in patrickchugh#199. Now they use helpers.get_tf_binary() so OpenTofu users see the
correct binary name in all output.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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