New to Kestra?
Use blueprints to kickstart your first workflows.
Provision GCP Linux VMs with Terraform, join them to an AD domain over SSH, and register DNS records on the Windows DC via Ansible WinRM with Kestra.
A VM is not really provisioned until it is on the domain and resolvable by name. This blueprint chains the three toolchains that usually live in three different runbooks: Terraform creates the Google Cloud instance with a static internal IP and your SSH public key, an Ansible playbook over SSH installs realmd/sssd and joins the machine to Active Directory (including the /etc/hosts, DNS, and NTP prerequisites Kerberos demands), and a second Ansible playbook over WinRM registers the forward A and reverse PTR records on the Windows domain controller. The VM is tracked as a Kestra Asset for lifecycle governance.
createVM task (io.kestra.plugin.terraform.cli.TerraformCLI) applies an inlined main.tf with a GCS backend keyed by prefix={{ inputs.vmName }}, so each VM gets its own state and a teardown flow can reuse it. The external IP is exported to external_ip.txt, and an assets block registers the io.kestra.plugin.ee.assets.VM asset with full metadata.waitForStartupBootConfig task (io.kestra.plugin.core.flow.Sleep, PT5M) lets the instance finish booting.addVMtoAD task (io.kestra.plugin.ansible.cli.AnsibleCLI) targets the fresh external IP read from the Terraform output file. Its playbook pins the DC in /etc/hosts, waits for the DC's DNS port, installs realmd, sssd, and adcli, points systemd-resolved at the DC, syncs time with ntpdate (Kerberos tolerates less than 5 minutes of drift), then runs realm join with the admin password from secrets and enables home directory creation.addDNSentry task connects to the DC over WinRM using connection details from the dcConfig KV record (published by the domain controller deployment flow) and calls Add-DnsServerResourceRecordA -CreatePtr to register both DNS records.Terraform cannot join a machine to a domain; Ansible does not know the IP Terraform just allocated; the DNS registration needs credentials for a completely different host. Kestra threads it together: output files pass the external IP from Terraform into the Ansible inventory, the KV store supplies the DC's connection details across flows, secrets hold the SSH keys and domain password, and one execution log covers the entire provisioning story.
dcConfig KV record (internalIPAddress, externalIPAddress, username, domainName, vmName) created by the companion AD controller blueprint.assets block to run on OSS).GCP_SERVICE_ACCOUNT_JSON: JSON key used by Terraform.SSH_PUBLIC_KEY: public key injected into the VM metadata for root access.SSH_PRIVATE_KEY: matching private key used by Ansible to reach the new VM.AD_ADMIN_PASSWORD: domain administrator password used for realm join and the WinRM connection.backend.tf.dcConfig exists in the KV store.realm list on the VM and nslookup <vmName>.<domain> against the DC.io.kestra.plugin.core.trigger.Flow.