Skip to main content
The provider drives the same REST API as the dashboard and CLI, with your own token, so every policy and approval rule still applies. It lives in its own Go module, terraform-provider/, and never ships inside the control plane binary.
Not published yet. The provider is built from source for now. Publishing to the Terraform and OpenTofu registries is a later step, so there is no terraform init download yet.

Where the name lives

Everything that carries the product name is in one file, terraform-provider/internal/provider/brand.go: the resource prefix, the registry address, and the environment variable names. A rename is that one edit plus the module path in terraform-provider/go.mod. Resource type names are built from the prefix at runtime, so no other Go file repeats it.

Configure

url and token fall back to the APP_API_URL and APP_API_TOKEN environment variables, the same ones the CLI reads. Prefer the variables over writing the token into a file.

Resources

Data sources: levelrail_apps lists every app with its image, port, project and domains. levelrail_nodes lists the fleet and needs a root token.

Complete example

Behavior worth knowing

  • levelrail_app and levelrail_domain both write the app’s domain list. Manage hostnames only with levelrail_domain, never through the app resource, which does not expose them.
  • levelrail_app.env is sensitive and, when set, replaces the live plain variables. Leave it unset to manage variables elsewhere.
  • levelrail_environment_variables only manages the keys you list. Other variables at that scope are left alone, and deleting the resource removes only its own keys.
  • Database engine and version never change in place. A change forces a replace, which destroys data, so use prevent_destroy on databases you care about.
  • Deleting a project follows the API’s own guard and is refused while it still holds apps.

What is not covered

  • App secrets and vault-backed variables (secret_env, vault_env): values would land in Terraform state, so use the secrets API or the CLI.
  • Volumes, bind mounts, resource limits, health checks, hooks, labels, commands and egress policy on apps.
  • Git and build sources, deploys and rollbacks (these are actions, not state).
  • Per-domain settings such as TLS certificates, redirects, headers, WAF, caching and auth gates.
  • Nodes (read only through the data source), load balancers, alerts, pipelines, notification channels, backups, teams, users, roles and tokens.
  • Database users, backup schedules, public access and upgrades.
For several of these, Platform as code covers them through the CLI.

Acceptance tests

They need a terraform or tofu binary and a live control plane, and are off unless TF_ACC=1. The recipe in scripts/smoke.sh starts a dev mode control plane with no Docker (SMOKE_KEEP=1 leaves it running and prints the URL):
The database resource has no acceptance test because creating a database needs a Docker host.
Last modified on October 14, 2026