The official TrueNAS Terraform provider, now available for deployment!
We’ve published the official TrueNAS Terraform provider. The source is at github.com/truenas/terraform-provider-truenas, and it’s live on the Terraform Registry as truenas/truenas. Instead of relying on midclt wrapper scripts, third-party tooling, or manually clicking through the web interface and trying to recall your configuration later, you can now manage your TrueNAS infrastructure using our official provider, built directly on top of the new TrueNAS versioned API.
If you haven’t used Terraform before: it is an infrastructure-as-code tool. You describe the state you want in plain text files, run terraform plan to see exactly what would change, and terraform apply to make it happen. The useful part for TrueNAS is that the description lives in Git rather than in your memory of which buttons you clicked six months ago. A set of datasets with their permissions and ACLs, the NFS and SMB shares on top of them, the snapshot and replication tasks behind them, all of it becomes a file you can review in a pull request, diff against what is actually running, and reapply to a second system to get an identical setup. That matters if you run more than one box, if you want staging to match production, or if you’ve ever rebuilt a NAS after a reinstall and spent the evening trying to remember how the shares were configured. It also means TrueNAS stops being the manual island in an otherwise automated environment.
The short technical version: the provider is built on the Terraform Plugin Framework, with a self-contained JSON-RPC 2.0 client inside the provider. No REST, no SSH, no external client dependency; it speaks to /api/current over a WebSocket, same as the rest of the family. There are 85 resources, 84 of them with a matching data source, covering pools, datasets, zvols and snapshots, NFS and SMB shares, permissions and ACLs, users and groups, API keys, certificates and ACME, directory services, apps, VMs and LXC containers, replication and cloud sync, networking, services, alerts, and the HA and enclosure resources on Enterprise.
Both block stacks are expressible end-to-end in HCL: iSCSI from portal through target, extent, LUN association and CHAP auth, and NVMe-oF from port through subsystem, namespace, host grant and port binding. You will need Terraform 1.11 or later and a TrueNAS system on 25.10 or later. There is a working example for every resource under examples/resources/.
Two things worth calling out. Secrets are write-only: passwords, CHAP secrets and DH-CHAP keys are never read back into state and never show up in data sources. And on TrueNAS 26.0, naming the key owner with username alongside api_key switches authentication to SCRAM-SHA-512, so the raw key never crosses the wire. The provider is licensed MPL-2.0. Our acceptance suite runs against live boxes on 25.10 and 26.0, including a real controlled failover on a disposable HA controller pair.
As mentioned in the recent Cinder announcement, the Terraform provider isn’t a one-off. The versioned API that landed in 25.10 and carries forward into TrueNAS 26 is what makes integrations like this practical to build and maintain, because they can target a stable contract instead of chasing internals between releases. The rest of the set:
-
TrueNAS CSI driver for Kubernetes and OpenShift: docs | source | Red Hat certified listing
-
Cinder driver for OpenStack: source
Terraform, CSI and Cinder all ride that same versioned API whether you are on an HA appliance or Community Edition, with no separate enterprise-only path. The Proxmox plugin is still Early Access and Community-focused today; see its docs for current support boundaries.
Getting started is one terraform init away. Declare it and Terraform downloads and signature-verifies the provider for you:
terraform {
required_providers {
truenas = {
source = "truenas/truenas"
version = "~> 1.0"
}
}
}
provider "truenas" {
endpoint = "wss://truenas.example.com/api/current"
api_key = var.truenas_api_key
username = "svc_terraform" # key owner; enables SCRAM-SHA-512 on 26.0+
}
We tagged this 1.0 rather than 0.x on purpose. Within the 1.x line, minor and patch releases stay backward compatible, existing configurations keep planning and applying unchanged, and state written by one version stays readable by later ones. The full policy is in VERSIONING.md. If you would rather build from source, or you are installing air-gapped, make install still works.
We’d love feedback from the community, so what would help most right now is people pointing this at real systems and real state files. Let us know if you hit resources that drift, imports that do not round-trip, or gaps in the docs by opening an issue on the repo.