Terraform provider
Manage Odinex Cloud with Terraform or OpenTofu.
The odinex/odinex provider manages servers, networks, volumes, firewalls, floating IPs, load balancers and more with
Terraform or OpenTofu. It is modelled on
Hetzner's hcloud provider: resource names, arguments, import IDs and timeouts follow it wherever the Odinex API
allows.
Configure the provider
terraform {
required_providers {
odinex = {
source = "odinex/odinex"
}
}
}
provider "odinex" {} # reads the token from ODINEX_TOKEN| Argument | Environment variable | Default |
|---|---|---|
token | ODINEX_TOKEN | Required. A project API token (odx_…) |
endpoint | ODINEX_ENDPOINT | https://api.odinex.cloud/v1 |
poll_interval | ODINEX_POLL_INTERVAL | 1s (a Go duration such as 500ms) |
Everything the provider manages lives in the token's project. Use a token with the read_write scope to make
changes. Keep the token out of your code: set ODINEX_TOKEN or pass it as a sensitive variable.
export ODINEX_TOKEN=odx_...
terraform init
terraform applyA first server
resource "odinex_ssh_key" "admin" {
name = "admin"
public_key = file("~/.ssh/id_ed25519.pub")
}
resource "odinex_server" "web" {
name = "web-1"
server_type = "t1"
image = "ubuntu-24.04"
location = "fra1"
ssh_keys = [odinex_ssh_key.admin.id]
labels = { role = "web" }
}
output "ipv4" {
value = odinex_server.web.ipv4_address
}How the provider behaves
- Actions. Long-running operations return an action; the provider polls it every
poll_intervaland reports a failed action as an error with the action's code and message. - Retries. Requests answered with
429are retried afterRetry-After(see Rate limits), and409 resource_busy(another action is running on the resource) is retried with a short back-off. - Changing a server type happens in place: the provider powers the server off, changes the type and powers it on
again. With
keep_disk = truethe disk keeps its size so you can downgrade later. Changingimagerebuilds the server, which erases its disk. - Drift. If a resource was deleted outside Terraform (the API answers 404), it is removed from the state and planned again.
- Import. Most resources can be imported by ID or name, e.g.
terraform import odinex_server.web web-1.
One way per relationship
Some relationships can be managed in two ways. Use only one of them for the same object:
| Inline | Separate resource |
|---|---|
odinex_server network blocks | odinex_server_network |
odinex_firewall apply_to blocks | odinex_firewall_attachment |
odinex_volume.server_id | odinex_volume_attachment |
odinex_floating_ip.server_id | odinex_floating_ip_assignment |
Floating IPs still need guest configuration
Assigning a floating IP with Terraform routes it to the server, but the address must still be configured inside the server and announced with a gratuitous ARP. See Floating IPs.
Reference
Every resource and data source, with all arguments and attributes, is documented in the reference, generated from the provider's schema.
Resources: odinex_server, odinex_ssh_key, odinex_volume, odinex_volume_attachment, odinex_network,
odinex_server_network, odinex_firewall, odinex_firewall_attachment, odinex_floating_ip,
odinex_floating_ip_assignment, odinex_rdns, odinex_load_balancer, odinex_placement_group, odinex_snapshot.
Data sources: odinex_location(s), odinex_server_type(s), odinex_image, odinex_ssh_key(s), odinex_server(s),
odinex_network, odinex_load_balancer_type(s), odinex_pricing.