OpenTofuCLI icon
SlackIncomingWebhook icon

Plan and Apply Infrastructure with OpenTofu

Run tofu init, plan, and apply as one audited Kestra execution with a saved plan, captured artifacts, and Slack reporting instead of laptop applies.

Categories
Infrastructure

Infrastructure applied from a laptop leaves no trace of what was planned, what changed, or who was told. This blueprint moves the whole OpenTofu lifecycle into one Kestra execution through io.kestra.plugin.opentofu.cli.OpenTofuCLI. The configuration arrives through inputFiles, the task saves a plan and applies exactly that saved plan, outputFiles uploads the rendered artifact and the state file to Kestra internal storage, and Slack receives the result with the execution ID. Every apply becomes a versioned run with full logs.

How it works

  1. plan_and_apply (io.kestra.plugin.opentofu.cli.OpenTofuCLI) receives main.tf through inputFiles. The demo config uses the local_file provider to render an app-config.json, so it runs anywhere with no cloud credentials.
  2. commands runs tofu init, then tofu plan -out=plan.tfplan, then tofu apply plan.tfplan. Applying the saved plan file means the apply executes exactly what the plan computed, never a fresh evaluation.
  3. outputFiles uploads app-config.json and terraform.tfstate to Kestra internal storage, so downstream tasks and humans can inspect exactly what this run produced.
  4. notify posts the outcome to Slack, and the errors block posts a distinct alert when init, plan, or apply fails.

What you get

  • Every apply as an auditable execution with logs, timing, and the exact config that ran.
  • A saved-plan workflow by default, so what was applied is provably what was planned.
  • Produced artifacts and state captured as task outputs, ready for downstream tasks.
  • A pattern that swaps to any real stack by replacing main.tf and adding provider credentials.

Who it's for

  • Platform engineers replacing ad hoc laptop applies with versioned, logged runs.
  • Teams that want OpenTofu executions stored next to the rest of their orchestration, not in a separate CI system.
  • Anyone adopting OpenTofu who wants a working init, plan, apply pipeline in one copy-paste.

Why orchestrate this with Kestra

OpenTofu computes and applies changes, but it does not schedule itself, keep an execution history, retry container-level failures, or notify anyone. Kestra wraps the unchanged tofu commands with all of that: the flow YAML lives in Git, the execution view shows every command's logs, secrets stay in Kestra's secret backend, and outputs flow into notifications and downstream tasks.

Prerequisites

  • A Slack incoming webhook for run reports.
  • No cloud credentials are needed for the demo config; for real providers, pass credentials through task env from {{ secret('...') }}.

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 check that Slack reports the finished apply.
  3. Open the plan_and_apply task outputs to download app-config.json and terraform.tfstate.
  4. Replace main.tf with your real configuration and add provider credentials through env.

How to extend

  • Add a human approval between plan and apply, as shown in the OpenTofu approval gate blueprint.
  • Run tofu plan -detailed-exitcode on a schedule to catch drift, as shown in the OpenTofu drift detection blueprint.
  • Keep the configuration in Git and load it with namespaceFiles instead of inline inputFiles.
  • Point the config at a remote state backend so state persists across runs, with backend credentials from secrets.

Links

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

New to Kestra?

Use blueprints to kickstart your first workflows.