How TerraDart is built
If you are deciding whether to depend on TerraDart, two questions matter more than any feature list: why should I trust hundreds of generated factory classes? and why should I expect this project to keep up with its providers? This page answers both with mechanisms you can inspect in the repository — every claim below names something that actually runs, not an aspiration.
The generation pipeline
Section titled “The generation pipeline”Curated factories are not written by hand. They are generated by a maintainer
CLI (terradart-codegen wrap) from pinned inputs: the Terraform provider schema
of each provider (hashicorp/google, hashicorp/google-beta, hashicorp/aws,
cloudflare/cloudflare, appwrite/appwrite, hashicorp/azurerm), plus what
the schema leaves out. For Google that is Magic Modules metadata — the
upstream YAML Google uses to generate the provider itself, synced per-resource
with provenance recorded for every file. For AWS, Cloudflare, Appwrite and
Azure it is validator hints extracted from the provider’s Go source at the
pinned release: the value sets that become enums and the exclusive groups that
become sealed types.
Generation is byte-deterministic: CI re-runs the generator against the pinned inputs on every pull request and fails if a single generated file differs from what is committed. There is no “mostly generated, occasionally hand-patched” gray zone — generated files carry a do-not-edit banner, repo tooling blocks direct edits, and the parser that extracts enum values from schema descriptions is the same code the coverage checker runs, so the generator and its auditor cannot drift apart.
Where the Google inputs come from
Section titled “Where the Google inputs come from”Google generates its own Terraform provider from Magic Modules, and TerraDart reads both ends of that pipeline:
The MM YAML overlay carries metadata the provider schema does not surface —
enum values, exactly-one-of groups, sensitive fields, force_new, free-form
description text — read at the Magic Modules commit the provider release was
generated from. Google tracking is pinned to GA ~> 8.0; beta-only types live
in terradart_google_beta, and names GA also has stay in terradart_google.
The weekly loop under Sustainability refreshes these fixtures. You don’t need to track it to use TerraDart; it is documented so that, when a release adds factories or shifts an existing one, you can see which upstream change drove it.
The curation philosophy
Section titled “The curation philosophy”The rule is simple: facts are derived, judgment is declared, and both are auditable.
- Anything the schema, Magic Modules or the provider’s validators can state — parameters, enum values, output getters, nested block shapes, documentation — is derived, so it moves automatically when upstream moves.
- Human decisions — how to model an exactly-one-of block as a sealed class hierarchy, what to name it, and which surfaces to freeze deliberately — live in thin, reviewable override files.
- Every escape hatch is a fail-closed ledger: frozen surfaces, coverage debts, and migrator round-trip exceptions are recorded lines with reasons, and CI fails when an entry goes stale. Forgetting is impossible to do silently.
This is also why the API is opinionated: IAM adjuncts default to additive
*_iam_member variants, and mutually-exclusive nested blocks are enforced at
compile time with sealed classes instead of documented conventions.
The verification harness
Section titled “The verification harness”Type-checking generated code proves it compiles, not that it works. Verification is layered from cheap to expensive:
The second layer asks Terraform itself. On every pull request, each example’s
synthesized JSON is checked with terraform validate against the real
provider plugin, and the migrator round-trips every example — synthesize,
migrate the JSON back to Dart, synthesize again — and requires identical
output. CI does not apply examples to a live project; real-apply evidence is
tracked through the cookbook (see Status). When you upgrade
TerraDart and your synthesized JSON is unchanged, that is not luck; it is the
property this harness exists to protect.
Sustainability
Section titled “Sustainability”TerraDart is a single-maintainer project, and you should weigh that honestly. Here is what makes it a smaller risk than the label suggests: the routine work does not depend on the maintainer being present.
Bumps run on different weekdays, so one can merge before the next opens.
This table is rendered from tool/providers.yaml, and the docs consistency
check fails when the two disagree:
| Provider | Day (UTC) | Routine bump |
|---|---|---|
| Google Cloud (with google-beta) | Sunday | auto-merges when CI is green |
| AWS | Monday | auto-merges when CI is green |
| Cloudflare | Tuesday | waits for review |
| Appwrite | Wednesday | auto-merges when CI is green |
| Azure | Thursday | auto-merges when CI is green |
- The update loop runs on a schedule. Provider schema updates arrive as
automatic weekly pull requests on the days above. A new resource type
arrives as a generated factory queued for API polish. A routine bump, one
with no removed type and no breaking change to the generated Dart API,
enables auto-merge and lands once the full CI battery is green, without
waiting on anyone’s availability. A provider set to
bump.mode: pr-onlyintool/providers.yamlalways waits for review. - The repository is deliberately maintainable by others — human or AI. A single agent guide is the source of truth for how to work on the codebase; the ledgers make every standing decision explicit; determinism makes every regeneration verifiable. A successor does not need tribal knowledge, and routine maintenance runs under the gates above.
- Lock-in is shallow by design. The output is standard Terraform JSON. If the project stopped tomorrow, your existing configurations would keep working with plain OpenTofu or Terraform — and migrating away is a file-format decision, not a re-architecture.
What is not promised: there is no SLA. Issue triage and reviews are best-effort, and security response targets are documented in SECURITY.md. The status page states the current release phase and change policy in the same spirit.
Read more
Section titled “Read more”- How TerraDart works — what a Stack becomes: synth, plan and apply, and the constants and outputs your app reads.
- Coverage — every factory of every provider package and the examples that exercise it; the provider pages cover the rest.
- Contributing or pointing an agent at the repo? Start with AGENTS.md.