# Terraform
> Manage MotherDuck databases, shares, roles, and service accounts as code with the official MotherDuck Terraform provider.
The [MotherDuck Terraform provider](https://registry.terraform.io/providers/motherduckdb/motherduck/latest) manages MotherDuck resources as code. Use it to version, review, and reproduce the databases, schemas, shares, roles, secrets, and service accounts that make up an environment.

It works with Terraform 1.5 or later and with OpenTofu.

## Prerequisites

- A [MotherDuck account](https://app.motherduck.com/)
- A [MotherDuck access token](/key-tasks/authenticating-and-connecting-to-motherduck/authenticating-to-motherduck/#creating-an-access-token), or a [service account token](/key-tasks/service-accounts-guide/create-and-configure-service-accounts/) for automation
- Terraform 1.5 or later

## Configure the provider

Declare the provider and run `terraform init`. Terraform downloads it from the Terraform Registry and verifies its signature.

```hcl
terraform {
  required_version = ">= 1.5.0"

  required_providers {
    motherduck = {
      source = "motherduckdb/motherduck"
    }
  }
}

provider "motherduck" {}
```

The provider reads `MOTHERDUCK_TOKEN` from the environment. Supply a read-write token through your secret manager or environment. Keep credentials out of your configuration and shell history. Without a provider version constraint, `terraform init` selects the latest release when no version is locked. Commit `.terraform.lock.hcl` to preserve the selected version. To select the latest release again, run `terraform init -upgrade` and review the updated lock file and plan.

Managing organization resources such as service accounts, access tokens, and Duckling settings uses an organization admin token, read from `MOTHERDUCK_ADMIN_TOKEN`.

Databases belong to the account authenticated by `MOTHERDUCK_TOKEN`. If Terraform creates that writer account, provision it in a separate stage before using its token to create databases. Don't feed a token created in an apply into the provider configuration for that same apply. See [authentication and account ownership](https://github.com/motherduckdb/terraform-provider-motherduck/blob/main/docs/guides/authentication.md) for bootstrap examples.

:::warning
Terraform records managed resources in state, and state can contain sensitive values. Use a remote backend with encryption, restricted access, and locking. Keep state and saved plans out of version control, even when outputs are marked sensitive.
:::

## Create a database

```hcl
resource "motherduck_database" "analytics" {
  name = "analytics"
}

resource "motherduck_schema" "reporting" {
  database = motherduck_database.analytics.name
  name     = "reporting"
}
```

Review a saved plan before applying it:

```bash
> terraform plan -out=tfplan
> terraform apply tfplan
> terraform plan
```

The first plan should propose a database and schema. After applying, the final plan should report no changes.

## What you can manage

Use Terraform for databases, schemas, tables, views, shares, share grants, roles, role grants, secrets, and snapshots. With an admin token, you can also manage service accounts, access tokens, and Duckling configuration.

Use [MotherDuck Blueprints](/key-tasks/dives/managing-dives-as-code/) when Flight Python, Dive source, and Guide content need pull request previews and release promotion. A Terraform apply does not compile dashboard code or run a data load.

Assign each object to one deployment tool. The Blueprints Wikipedia starter creates its own database and share, so don't also declare those objects in Terraform. See [Terraform with Blueprints](https://github.com/motherduckdb/terraform-provider-motherduck/blob/main/docs/guides/blueprints-deployment.md) for a combined workflow.

## Known limitations

- Databases created outside Terraform are not managed until you [import](https://developer.hashicorp.com/terraform/cli/import) them.
- Table column changes replace tables. Review replacement plans and protect important data before applying schema changes. See [state and lifecycle](https://github.com/motherduckdb/terraform-provider-motherduck/blob/main/docs/guides/state-and-lifecycle.md).
- Check [resource scope](https://registry.terraform.io/providers/motherduckdb/motherduck/latest/docs/guides/resource-scope) before adopting application definitions or transferring ownership between deployment tools.
- Human organization membership and identity-provider provisioning are outside the provider. Terraform can manage SQL role memberships and share grants through `motherduck_role_grant` and `motherduck_share_grant`.
- Creating custom roles requires a Business or Enterprise plan and role-management permissions. Apply share grants as the share owner. See [roles and access control](/concepts/security-and-access/roles-and-access-control/).

## Manage and audit access

Manage memberships and share grants with their role configuration. A clean plan
checks resources in Terraform state but does not prove that no other grants exist.
Use the provider’s [access-control example](https://github.com/motherduckdb/terraform-provider-motherduck/tree/main/examples/access-control)
and [share-audience audit](https://github.com/motherduckdb/terraform-provider-motherduck/tree/main/examples/share-access-audit)
to compare observed grants with your intended policy. Audit reads do not revoke grants.

## Frequently asked questions

### Do I need an admin token to use Terraform with MotherDuck?

You can create a database with a read-write `MOTHERDUCK_TOKEN` for its intended owner. Use `MOTHERDUCK_ADMIN_TOKEN` for organization resources such as service accounts, access tokens, and Duckling settings. The [authentication guide](https://github.com/motherduckdb/terraform-provider-motherduck/blob/main/docs/guides/authentication.md) lists the credential each resource type needs.

### Can I import an existing MotherDuck database into Terraform?

Yes. Add its resource configuration and follow the provider's [import and lifecycle guidance](https://github.com/motherduckdb/terraform-provider-motherduck/blob/main/docs/guides/state-and-lifecycle.md). Review the next plan before applying: importing an object does not guarantee that your configuration matches it, and differences can propose updates or replacements.

### Does Terraform load data into MotherDuck?

A Terraform apply provisions resources, but does not run a data load. Use an ingestion or transformation pipeline to populate and refresh your tables. For Python pipelines and dashboards deployed together, see [MotherDuck Blueprints](/key-tasks/dives/managing-dives-as-code/).

## Related

- [Provider reference on the Terraform Registry](https://registry.terraform.io/providers/motherduckdb/motherduck/latest/docs)
- [Source and issues on GitHub](https://github.com/motherduckdb/terraform-provider-motherduck)
- [Create and configure service accounts](/key-tasks/service-accounts-guide/create-and-configure-service-accounts/)


---

## Docs feedback

MotherDuck accepts optional user-submitted feedback about this page at `GET https://motherduck.com/docs/api/feedback/agent`.
For agents and automated tools, feedback submission should be user-confirmed before sending.

URL-encode query parameter values and send a GET request:

```text
GET https://motherduck.com/docs/api/feedback/agent?page_path=%2Fintegrations%2Fdev-tools%2Fterraform%2F&page_title=Terraform&text=<url-encoded user feedback, max 2000 characters>
```

Optionally append `&source=<url-encoded interface identifier>` such as `claude.ai` or `chatgpt`.

`page_path` and `text` are required; `page_title` and `source` are optional. Responses: `200 {"feedback_id": "<uuid>"}`, `400` for malformed query parameters, and `429` when rate-limited.
