Terraform export
Snapshots and live state as HCL for the official providers, with import blocks.
What it is
Terraform export (included with Business and MSP licenses) turns your IdP configuration into HCL for the official Terraform providers: goauthentik/authentik, okta/okta, and auth0/auth0. Two ways to use it:
Per object: every row in Live State (and in a snapshot's Browse view) has a Terraform button showing that object as a resource block, plus a matching import block, with copy and download.
Whole tenant: every backup row on the Backups page has a Terraform... export: pick resource types, download a zip with one .tf file per type, provider setup, variables, import blocks, and a coverage README.
Blocks are generated against each provider's own published schema. You need Terraform 1.5 or newer (import blocks). Export is read-only: it never writes anything to your identity provider.
The import block
Every exported resource comes with an import block like this:
import {
to = okta_app_saml.duo_admin_panel
id = "0oaim59q48RDNPzik357"
}
Terraform only manages what is in its state file, and a fresh state file is empty. Without the import block, terraform plan against your tenant would try to CREATE a duplicate of every object. The import block tells Terraform "this resource is the EXISTING object with this id, adopt it into state". Your first plan then shows will be imported instead of will be created, and Terraform manages the real object from then on. It replaces running the legacy terraform import command once per object by hand.
Same tenant, or a different one?
Bringing THIS tenant under Terraform management: keep the import blocks. Plan, review, apply: your existing objects are adopted, nothing is recreated.
Promoting to a DIFFERENT instance (staging to prod, a fresh tenant, disaster recovery): remove the import blocks. Those ids only exist in the source tenant; in the target you want Terraform to create the objects. In the zip bundle that is one file (import.tf) to delete.
The target already has some of the objects (created by hand earlier): write import blocks using the TARGET tenant's ids. If the target tenant is also in IdPVault, its own Terraform view gives you each object's id.
Cross-references between objects
Provider-assigned ids are per-instance: an application whose provider is #48 in staging points at some unrelated object (or nothing) in prod, and a group created in the target (by hand or by Terraform) always gets a NEW id - ids are never portable. The bundle export handles this for you: when a referenced object is part of the same export, the reference is rewritten to a Terraform expression (for example groups_included = [okta_group.slack_users.id]), which resolves at apply time to whatever id the target assigns, in the right order. A single copied block keeps literal source ids: fine for self-contained objects, but anything with wiring should either travel via the bundle or have its ids reviewed against the target.
Built-in objects (like Okta's Everyone group) are never exported, so references to them stay literal. Use the provider's data sources instead, for example data "okta_everyone_group" "all" {} with groups_included = [data.okta_everyone_group.all.id].
Secrets are never exported
Secret values (client secrets, private keys, passwords) are NEVER written into HCL, even though IdPVault holds them in the snapshot. Every secret becomes a Terraform variable marked sensitive = true in variables.tf; you supply values at plan time (tfvars, environment, or your secret manager). Provider credentials (API URL and token) are variables too.
Honest coverage
Not everything can be represented in the official providers, and IdPVault never drops anything silently:
- The bundle README lists every skipped object with its reason (for example Okta system apps like the Admin Console, which Terraform cannot manage, or built-in groups).
- Fields with no argument in the official provider (usually computed or read-only) are listed per type in the README and in the per-object view.
- Known provider-side gaps: Okta user and app schemas map to per-property Terraform resources (not exported yet); Okta policy conditions beyond the included-groups piece live on policy rules; Auth0 resource server scopes and client token_endpoint_auth_method moved to separate Terraform resource types.
Convergence check
After importing, run terraform plan again and review the remaining diffs: variable placeholders you have not filled in yet and provider defaults account for most of them. The apply is in your hands; IdPVault only generates the code.