New to Kestra?
Use blueprints to kickstart your first workflows.
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.
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.
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.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.verdict interpolates both values into a Slack message. Plan empty true is the green light, false means OpenTofu sees differences worth reading before migrating.errors block posts to Discord when either tool errored, keeping a broken check clearly separate from a negative verdict.plan_empty as a structured output, ready to gate an automated migration flow later.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.
env from {{ secret('...') }}.SLACK_WEBHOOK_URL: Slack incoming webhook URL.DISCORD_WEBHOOK_URL: Discord incoming webhook URL.SLACK_WEBHOOK_URL and DISCORD_WEBHOOK_URL secrets to your Kestra namespace.weekly trigger while the migration decision is pending.ForEach and aggregate the verdicts into one summary message.containerImage versions on both tasks to test the exact Terraform and OpenTofu versions in your fleet.