New to Kestra?
Use blueprints to kickstart your first workflows.
Webhook-triggered Terraform pipeline that plans, emails a reviewer, pauses for approval, and applies the exact saved plan with full audit trail.
Enforce human review before infrastructure changes land. This Kestra blueprint turns Terraform plan and apply into a governed, auditable pipeline: a webhook kicks off the run, terraform plan produces a saved tfplan artifact, a reviewer is emailed, the execution pauses for explicit approval, and terraform apply then runs against the exact reviewed plan so what ships is what was approved. It closes the classic gap between CI driven Terraform and ad hoc local applies, giving platform and SRE teams a single, declarative approval gate with full execution lineage.
on_apply_request trigger (io.kestra.plugin.core.trigger.Webhook) accepts a POST from a change management system, chat bot, or ITSM tool, secured by TERRAFORM_APPLY_WEBHOOK_KEY.plan task (io.kestra.plugin.terraform.cli.TerraformCLI) runs terraform init then terraform plan -no-color -out=tfplan inside the hashicorp/terraform:latest container via the Docker task runner. It uses an S3 remote backend so state is shared between containers, and exports tfplan as an output file.notify_approval task (io.kestra.plugin.email.MailSend) emails the on-call reviewer with the execution id and a link target.approve task (io.kestra.plugin.core.flow.Pause) holds the execution for up to PT2H waiting for a human to resume it from the Kestra UI or API.apply task replays the saved tfplan via terraform apply -no-color -auto-approve tfplan, guaranteeing zero drift from what was reviewed.log_result task (io.kestra.plugin.core.log.Log) records completion for the audit trail.Terraform itself has no scheduler, no human-in-the-loop primitive, and no native way to bind a plan artifact to a later approved apply. Kestra adds the missing layer: an event-driven webhook trigger, a first-class Pause task for human approval, automatic retries on transient failures, persisted inputs and output files that link plan to apply, and declarative YAML you can version control next to your Terraform code. You get lineage across the whole change, not just the CLI output of a single command.
backend block. Remote state is required because plan and apply run in separate containers.AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY: credentials for the S3 remote backend and any AWS provider resources.TERRAFORM_APPLY_WEBHOOK_KEY: shared secret guarding the Webhook trigger.SMTP_HOST, SMTP_USERNAME, SMTP_PASSWORD: SMTP relay used by MailSend to notify the reviewer.main.tf and backend block with your real Terraform configuration.from, to, and subject of the notification email to your team.backend block and provider env vars.MailSend with io.kestra.plugin.notifications.slack.SlackIncomingWebhook or a ServiceNow change ticket update.Switch task after plan to auto-approve no-op plans and only pause when there are real changes.tfplan with terraform show -json.tfsec or checkov task between plan and notify_approval to block applies on policy violations.terraform destroy through the same approval gate.