Docs
Open the console →
Guides

Import Terraform Registry modules as blueprints

Platform staff can crawl the public Terraform Registry and import verified modules as platform-global blueprints — available in every organization's deploy form, with the honest limits of an opaque module.

Cloud Control's staff console can import public Terraform Registry modules and turn them into platform-global blueprints. Once imported, a module shows up in every organization's Deploy a blueprint form exactly like a built-in blueprint — no customer-side change.

Staff only

This lives in the staff realm (/admin/blueprintsTerraform Registry), gated by the platform.blueprint:manage policy. Customers consume the imported blueprints; they do not run the crawler.

Two ways to import

  • Browse & import — search the registry (by text, provider, verified-only), preview a module's mapped input fields, then Import as blueprint.
  • Seed top verified — bulk-import the top-N verified modules by downloads (optionally filtered to one provider). Non-mappable providers are skipped and reported.

How a module becomes a blueprint

The crawler maps the registry provider to a cloud (aws→AWS, google→GCP, azurerm→AZR, alicloud→ALI — anything else is skipped), turns the module's required inputs into form fields (a module can have hundreds of inputs; only the required ones, capped at 24, are surfaced), and stores a module-block template. It reuses the existing custom-blueprints catalog, so there is no new storage and the blueprint id is custom/platform/<namespace>-<name>-<provider>.

  • string → text field · bool → toggle · number → text with a numeric pattern.
  • list/set/map/object/tuple → a passthrough text field (paste raw HCL/JSON, e.g. ["a","b"] or {"k":"v"}) — coerced when the plan is composed.
  • A tags map becomes the standard tags field so the mandatory-tags policy is satisfiable.

Planning a registry-module blueprint

Composing the plan wraps the module in a single Terraform module block: module "<slug>" { source = "ns/name/provider" version = "…" …your inputs }, plus the platform-stamped terraform/provider/backend blocks. Your form values become the module arguments (booleans stay booleans, number-looking strings become numbers, JSON list/map strings are parsed).

Policy and cost are approximate for a module

A registry module is opaque at compose time — Cloud Control cannot see the resources it will create until tofu plan expands it. So the plan shows ONE placeholder resource, and the policy (no-public-bucket / mandatory-tags / region-allowlist) and cost estimate run on that placeholder. The real, per-resource policy and cost only materialize when the real runner runs tofu plan on the expanded module — exactly how the real-apply runner already works for every blueprint.

Limitations

  • Apply is the mock runner unless real provisioning is enabled for the target account — same as every blueprint. "Imported" means the module is a first-class, deployable blueprint in the catalog.
  • At most 24 required inputs are surfaced as fields; any overflow uses the module's own defaults (noted on the first field).
  • Field coercion is app-side (numbers, booleans, JSON) — it is not full HCL type-checking; a malformed complex value passes through verbatim and is validated by tofu.
  • The resource-type classification is a best-effort name heuristic (fallback compute); it only affects which inventory bucket the placeholder lands in.
  • Removing an imported blueprint disables it (platform rows are never hard-deleted, so a re-import can't silently resurrect a removed one).
Where the crawler points

By default the crawler talks to the public Terraform Registry. Operators can point it at a private mirror (or the hermetic test mock) with CC_TF_REGISTRY_BASE. Requests are bounded (hard search/seed caps + per-call timeouts) and degrade to an honest error if the registry is unreachable — never a fabricated blueprint.