OpenTofuCLI icon
Log icon
SlackIncomingWebhook icon

Ephemeral Preview Environments with OpenTofu

Spin up an OpenTofu preview stack, run tests, and destroy it in a Kestra finally block so ephemeral environments never leak, with Slack alerts on failure.

Categories
Infrastructure

Preview environments leak when the teardown lives in a script that only runs on success. This blueprint makes destruction structural: io.kestra.plugin.opentofu.cli.OpenTofuCLI applies a preview stack with the execution ID baked into resource names, the test placeholder runs against it, and the destroy sits in Kestra's finally block, which executes whether the tests passed, failed, or something between them crashed. The destroy consumes the exact state file the apply produced, handed over through internal storage, so it tears down precisely this execution's stack and nothing else. The same guarantee this flow gives a local demo stack applies to real cloud previews, such as the ephemeral droplet pattern on DigitalOcean.

How it works

  1. apply_preview receives main.tf through inputFiles and the execution ID through env as TF_VAR_execution_id, so every resource name is unique per run and two concurrent previews cannot collide. outputFiles uploads terraform.tfstate to internal storage.
  2. run_e2e_tests is a Log placeholder standing in for your real test suite, whether that is a container running Playwright, a shell task running k6, or a subflow.
  3. destroy_preview lives in the finally block. It receives the same configuration plus the state file from the apply task's outputs, reinitializes the provider, and runs tofu destroy -auto-approve. Kestra runs finally tasks regardless of what happened upstream.
  4. The errors block posts to Slack on any failure and explicitly tells the responder to verify the teardown, covering the rare case where the apply itself broke before producing state.

What you get

  • Teardown as flow structure instead of script discipline, surviving test failures and crashes.
  • Per-execution stack naming, so concurrent previews from parallel executions never collide.
  • The destroy bound to the apply's own state file, never a shared or stale one.
  • A demo that runs with zero cloud credentials, using only the local_file provider.

Who it's for

  • Teams giving every pull request a live environment without paying for forgotten ones.
  • QA engineers who need real infrastructure for end to end tests, briefly.
  • Anyone who has found a month-old preview VPC on the cloud bill.

Why orchestrate this with Kestra

OpenTofu can create and destroy a stack, but nothing in OpenTofu guarantees the destroy runs after a failed test suite. Kestra's finally block is that guarantee, and internal storage is the thread that connects the two invocations: the state travels from apply to destroy as a typed artifact of this execution, visible in the UI, never parked in a shared backend where a concurrent run could touch it.

Prerequisites

  • A Slack incoming webhook for failure alerts.
  • No cloud credentials are needed for the demo stack; for real previews, pass provider credentials through task env from {{ secret('...') }} in both OpenTofu tasks.

Secrets

  • SLACK_WEBHOOK_URL: Slack incoming webhook URL.

Quick start

  1. Add the SLACK_WEBHOOK_URL secret to your Kestra namespace.
  2. Execute the flow and watch the execution view: apply, tests, then the destroy in the finally block.
  3. Replace main.tf in both tasks with your real preview stack and swap the Log placeholder for your test runner.

How to extend

  • Trigger the flow from a pull request webhook and interpolate the branch name into TF_VAR variables alongside the execution ID.
  • Replace the placeholder with a real test task and pass the preview endpoint to it through OpenTofu outputs.
  • Keep the stack alive on demand by putting a Pause before the finally teardown for manual exploration windows.
  • Post a success summary with the preview lifetime to Slack by adding a notification task after the tests.

Links

Orchestrate with Kestra
Orchestrate Slack with Kestra
Share this Blueprint
See How

New to Kestra?

Use blueprints to kickstart your first workflows.