TerraformCLI icon
Docker icon
OpenTofuCLI icon
SlackIncomingWebhook icon
DiscordIncomingWebhook icon
Schedule icon

Verify OpenTofu as a Drop-in Terraform Replacement

Prove OpenTofu is a drop-in Terraform replacement. Kestra runs tofu plan against Terraform-written state and posts whether the plan is empty to Slack.

Categories
Infrastructure

The whole OpenTofu migration promise is one sentence: point tofu at your existing Terraform state and nothing changes. This blueprint turns that promise into a repeatable, evidence-producing check. io.kestra.plugin.terraform.cli.TerraformCLI applies a stack and writes genuine Terraform state, io.kestra.plugin.opentofu.cli.OpenTofuCLI receives that exact state file through inputFiles and runs tofu plan -detailed-exitcode, the exit code becomes a plan_empty boolean through Kestra's output protocol, and Slack receives the verdict. Exit code 0 means OpenTofu read the Terraform state and proposes zero changes, which is the drop-in proof a migration sign-off needs.

How it works

  1. terraform_baseline runs in a hashicorp/terraform:latest container, applies the demo stack with terraform apply -auto-approve, and uploads terraform.tfstate to Kestra internal storage. In a real migration check, this task stands in for the state your project already has.
  2. opentofu_check receives the same configuration plus the Terraform-written state through inputFiles, runs tofu init, then tofu plan -detailed-exitcode. The exit code is captured without failing the task, exit code 1 still fails because the check itself broke, and the final echo emits plan_empty and plan_exit_code through Kestra's output protocol.
  3. verdict interpolates both values into a Slack message. Plan empty true is the green light, false means OpenTofu sees differences worth reading before migrating.
  4. The errors block posts to Discord when either tool errored, keeping a broken check clearly separate from a negative verdict.

What you get

  • A migration verdict backed by logs from both tools in one execution, not a blog post's assurance.
  • The check bound to genuine Terraform-written state, handed between tasks through internal storage.
  • plan_empty as a structured output, ready to gate an automated migration flow later.
  • A repeatable governance artifact you can rerun weekly while the decision is pending.

Who it's for

  • Platform teams evaluating the move from Terraform to OpenTofu after the license change.
  • Compliance-minded organizations that need documented evidence before switching tooling.
  • Anyone who wants the drop-in claim verified against their own stacks, not example code.

Why orchestrate this with Kestra

Running two CLIs and comparing behavior is exactly the kind of glue that ends up in a wiki page and a shell script nobody reruns. Kestra makes the check an execution: both tools run in isolated containers with their own images, the state file travels between them as a typed artifact, the verdict lands in Slack with an execution ID, and rerunning the proof is one click. When the real migration happens, the same flow shape becomes the migration itself.

Prerequisites

  • A Slack incoming webhook for the verdict and a Discord incoming webhook for failure alerts.
  • No cloud credentials are needed for the demo stack; to check a real stack, load your configuration from Git or namespace files and pass provider and backend credentials through task env from {{ secret('...') }}.

Secrets

  • SLACK_WEBHOOK_URL: Slack incoming webhook URL.
  • DISCORD_WEBHOOK_URL: Discord incoming webhook URL.

Quick start

  1. Add the SLACK_WEBHOOK_URL and DISCORD_WEBHOOK_URL secrets to your Kestra namespace.
  2. Execute the flow and check the Slack verdict reports plan empty true with exit code 0.
  3. Swap the demo configuration for one of your real stacks, feeding the OpenTofu task your actual state, and rerun.
  4. Enable the weekly trigger while the migration decision is pending.

How to extend

  • Fan the check out over several stacks with ForEach and aggregate the verdicts into one summary message.
  • Gate an actual migration apply behind the verdict plus a human approval, as shown in the OpenTofu approval gate blueprint.
  • Store the rendered plan as an output file when the plan is not empty, so reviewers see exactly what OpenTofu would change.
  • Pin specific containerImage versions on both tasks to test the exact Terraform and OpenTofu versions in your fleet.

Links

See How

New to Kestra?

Use blueprints to kickstart your first workflows.