Terraform Provider
Overview
The Durantic Terraform provider lets you manage your infrastructure as code. Machine configuration, roles, mesh networks, virtual IPs, BGP routing, secrets, and variables are all Terraform resources — version them in git, review changes through pull requests, and reproduce the same setup across environments.
The provider goes beyond configuration: the durantic_machine_deployment resource triggers a full OS install on a physical machine and waits until the machine comes back online. Change a role, run terraform apply, and your fleet rolls over to the new operating system.
Note
Terraform manages machines that are already enrolled in your account (via PXE, ISO, or the bootstrap command). It configures and provisions existing machines — it does not create new hardware. See Machine Provisioning for enrollment options.
Setting Up
Add the provider to your Terraform configuration:
terraform {
required_providers {
durantic = {
source = "durantic/durantic"
}
}
}
provider "durantic" {
# Credentials are read from environment variables:
# DURANTIC_API_TOKEN (required)
# DURANTIC_ENDPOINT (optional, defaults to https://api.durantic.io)
}
Create an API token on the API Tokens page in the dashboard — see Account Setup for details. Export it before running Terraform:
Resources
| Resource | Manages |
|---|---|
durantic_machine_deployment |
Configuration and OS provisioning for a machine — applies roles and mesh assignment, triggers the install, and blocks until it completes |
durantic_machine_config |
Desired configuration for a machine (roles, mesh network, tunnel settings) without triggering provisioning |
durantic_machine_role |
A reusable configuration template: OS image plus cloud-init template data |
durantic_mesh_network |
A WireGuard-based encrypted overlay network with a defined CIDR block |
durantic_vip |
A virtual IP with health checks and machine associations |
durantic_route |
A named set of BGP network prefixes with machine associations |
durantic_route_policy_set |
An ordered list of BGP route policy rules |
durantic_secret |
An encrypted account secret (write-only — the value is never returned by the API) |
durantic_variable |
A named key/value pair available to role templates |
durantic_secrets_backend |
An external secrets store (Vault or HTTP) that supplies secrets to machines |
durantic_registry_credential |
Authentication for a private OCI registry |
| Data Source | Looks Up |
|---|---|
durantic_machine |
An enrolled machine by UUID or hostname, including its status and IP addresses |
durantic_image |
A single OS image by UUID, name, or Docker image URL |
durantic_images |
All images available to your account (own and official) |
Provisioning with terraform apply
The durantic_machine_deployment resource ties a machine's configuration to its installed OS. When the resource is created or replaced, the machine reinstalls: it boots into the installer, streams the OCI image defined by its roles to disk, applies the rendered cloud-init configuration, and reboots into the new system. The apply blocks until provisioning reaches a terminal state.
What triggers a reinstall is explicit and predictable:
| Change | Effect |
|---|---|
role_names or force_provision |
Resource is replaced — new provision run |
mesh_network_uuid, tunnel settings, other config attributes |
In-place update — no provisioning |
terraform apply -replace=... on one instance |
New provision run for that machine only |
Bump the force_provision string (e.g. "v1" → "v2") to roll a new image across every machine in a group without touching their configuration. Destroying the resource only removes it from Terraform state — the machine itself is never deleted.
Example: From Role to Running Machine
# Find the base OS image
data "durantic_image" "ubuntu" {
docker_image_url = "ghcr.io/durantic/linux-ubuntu-25.10:latest"
}
# A reusable role: image + cloud-init
resource "durantic_machine_role" "web" {
name = "web-server"
description = "Nginx web server"
image_uuid = data.durantic_image.ubuntu.uuid
requires_mesh = true
template_data = <<-EOT
#cloud-config
packages:
- nginx
runcmd:
- systemctl enable --now nginx
EOT
}
# An encrypted overlay network
resource "durantic_mesh_network" "prod" {
name = "prod-mesh"
network_cidr = "10.50.0.0/24"
}
# Look up an enrolled machine and provision it
data "durantic_machine" "web01" {
hostname = "web-01"
}
resource "durantic_machine_deployment" "web01" {
machine_uuid = data.durantic_machine.web01.uuid
mesh_network_uuid = durantic_mesh_network.prod.uuid
role_names = [durantic_machine_role.web.name]
}
output "web01_mesh_ip" {
value = durantic_machine_deployment.web01.wg_ip_address
}
Running terraform apply creates the role and mesh network, assigns both to web-01, reinstalls its OS, and prints the machine's mesh IP once it is back online.
Importing Existing Resources
Everything you have already configured through the dashboard can be brought under Terraform management with terraform import:
terraform import durantic_machine_role.web "<role-uuid>"
terraform import durantic_mesh_network.prod "<mesh-uuid>"
terraform import durantic_machine_deployment.web01 "<machine-uuid>"
Secret values cannot be read back through the API, so durantic_secret resources need their value set manually after import.