TerraformCLI icon
AnsibleCLI icon

GCP VM Teardown with Terraform and AD/DNS Cleanup

Destroy a GCP VM with Terraform from shared state, then remove its Active Directory account and DNS A/PTR records via Ansible over WinRM with Kestra.

Categories
Infrastructure

Deleting a VM is the easy part; the orphaned AD computer account and stale DNS records are what bite you later. This blueprint does the full teardown: Terraform destroys the Google Cloud instance from the same remote state that provisioned it, the VM asset is flipped to state: deleted, and an Ansible playbook connects to your Windows domain controller over WinRM to remove the computer account, the forward A record, and the reverse PTR record.

How it works

  1. The deleteVM task (io.kestra.plugin.terraform.cli.TerraformCLI) reconstructs the instance definition from the flow inputs, runs terraform init -backend-config="prefix={{ inputs.vmName }}" against a shared GCS backend so each VM has its own state prefix, and executes terraform destroy -auto-approve -json. Its assets block records lineage and marks the io.kestra.plugin.ee.assets.VM asset deleted.
  2. The removeDNSentry task (io.kestra.plugin.ansible.cli.AnsibleCLI) installs pywinrm, builds a WinRM inventory from the dcConfig KV record published by the domain controller deployment flow, and runs a playbook whose ansible.windows.win_shell task calls Remove-ADComputer, then Remove-DnsServerResourceRecord for both the A record in the domain zone and the PTR record in the computed in-addr.arpa reverse zone.
  3. Zone names and PTR labels are derived from kv('dcConfig').subnetCIDR and the VM's IP octets, so no DNS math is hardcoded.

What you get

  • Symmetric teardown: the destroy consumes the exact Terraform state written at provisioning.
  • No orphaned AD objects or stale DNS entries after decommissioning.
  • Asset catalog updated to reflect the VM's deleted state.
  • All credentials (GCP key, AD admin password) pulled from secrets.

Who it's for

  • Windows-integrated Linux estates where every VM is domain-joined and DNS-registered.
  • Platform teams pairing this with a provisioning flow for a complete VM lifecycle.
  • IT operations tired of cleaning up AD and DNS by hand after VM deletions.

Why orchestrate this with Kestra

Terraform knows nothing about your directory or DNS zones, and Ansible has no idea which Terraform state to touch. Kestra binds them: shared inputs drive both tools, the KV store carries the domain controller's connection details between flows, secrets stay out of playbooks, and the execution log proves that the instance, the AD account, and both DNS records were removed in one auditable run.

Prerequisites

  • A GCS bucket holding the Terraform state written by your provisioning flow (prefix per VM name).
  • A Windows domain controller reachable over WinRM (port 5985) and a dcConfig KV record with externalIPAddress, username, domainName, and subnetCIDR (created by the companion AD controller blueprint).
  • Kestra Enterprise Edition for the Assets tracking (remove the assets block to run on OSS).

Secrets

  • GCP_SERVICE_ACCOUNT_JSON: JSON key of the service account allowed to delete instances and read the state bucket.
  • AD_ADMIN_PASSWORD: password of the AD admin user Ansible connects with.

Quick start

  1. Add the secrets above to your Kestra namespace.
  2. Replace the state bucket in backend.tf and align main.tf with your provisioning configuration.
  3. Ensure the dcConfig KV entry exists (deploy the AD controller blueprint first).
  4. Execute with the target vmName and ipAddress; verify the instance, AD account, and DNS records are gone.

How to extend

  • Add a io.kestra.plugin.core.flow.Pause approval gate before the destroy for production hosts.
  • Notify the owner via io.kestra.plugin.notifications.slack.SlackIncomingWebhook when cleanup completes.
  • Release the IP back to your IPAM with an io.kestra.plugin.core.http.Request task.
  • Drive it from the asset catalog with a SELECT input using the assets() function.

Links

See How

New to Kestra?

Use blueprints to kickstart your first workflows.