User data is currently supported on OVH clusters only. Other providers refuse the field with
User data is not supported for <provider> clusters.Prerequisites
- An OVH cluster in your organisation.
- Permission to operate the cluster (
clusters.operate). - Ankra CLI v0.12.0 or later for
--user-data-file. Earlier versions have no user-data flag; the API accepts the field regardless of CLI version.
Attach a document
Write the cloud-init document to a file and pass it with--user-data-file. It is a file flag rather than a string flag because the document is normally multi-KB YAML, which does not survive shell quoting well.
Read the first-boot output
A provisioning script that fails leaves a node that looks healthy to the cloud provider and wrong to you. Read the node’s own cloud-init output rather than inferring the failure from symptoms:cloud-init status --long plus the tail of /var/log/cloud-init-output.log, fetched over the platform’s own bastion lane - you do not need the cluster’s SSH key. It runs as a tracked read-only operation; if the fetch outruns the platform’s wait it hands back an operation id to poll with ankra cluster operations list. Calling it again while a fetch is in flight attaches to that fetch instead of starting a second one.
The same command is available for Hetzner, UpCloud, DigitalOcean and Scaleway clusters.
Carving a partition at provision time
The motivating case is encryption at rest. LUKS needs a real block device, but on single-disk flavors the only NVMe device is also the boot disk, and the image grows the root filesystem across the whole device - leaving no free partition to encrypt. Falling back to LUKS on a loopback file works but costs materially more overhead than LUKS on a real partition. The fix is to carve the disk inbootcmd, before the root filesystem is grown.
Leave growpart enabled
This ordering is a safety property, not a style preference.bootcmd runs before the growpart module, so:
- When your carve succeeds, it has already consumed the tail of the disk. growpart finds no free space to expand into and does nothing. Your layout stands.
- When your carve fails, growpart still runs and restores an ordinary full-disk root. You get a normal, usable node and a failed script to read in the log.
Grow root to its cap before appending
Append the new partitions after resizing root to the size you want it capped at, not before. If you append partitions directly after a small image root, they start immediately behind it, growpart has nowhere to expand into, and root stays at the image size. That failure looks exactly like the bricked node above, except it happens on the path where every command succeeded.Tooling present in the image
sfdiskis available.sgdiskandpartedare not - do not assume them.sfdisk --appendrefuses to run without--force.- Address the resulting partitions by GPT partlabel (
/dev/disk/by-partlabel/<name>), never by device path. Nodes are replaced, and a partlabel is the part of the layout that reliably comes back with them.
Example
/dev/disk/by-partlabel/pgdata and /dev/disk/by-partlabel/pgwal are real partitions that LUKS can take directly, and root settles at its 64 GiB cap.
Verify
1
Check cloud-init finished
Run
ankra cluster ovh nodes cloud-init-log <cluster-id> <node-id> against the first node the group creates. cloud-init status --long should report status: done. Anything else, read the output tail below it.2
Confirm the layout
The partitions you carved should be addressable by partlabel, and root should be at the size you capped it to and not the image default.
3
Replace one node
Delete a node and let the group recreate it, then repeat the two checks. This is the property the field exists for, so it is worth confirming once per document rather than assuming it.
Troubleshooting
The node joined but the partitions are missing
The node joined but the partitions are missing
Read the cloud-init log. A failed
bootcmd does not stop the node from joining the cluster: growpart restores a normal root and the node comes up looking healthy. That is the designed fallback, and the log is where the failure is recorded.Root is only a few GiB
Root is only a few GiB
Either growpart was disabled, or partitions were appended before root was resized so growpart had no free space to expand into. Both are covered above; fix the document and create a new node group, since user data cannot be edited on an existing one.
sfdisk did nothing and reported no error
sfdisk did nothing and reported no error
sfdisk --append needs --force. Without it the command declines to modify the table.The request was refused
The request was refused
User data is not supported for <provider> clusters means the cluster is not OVH. A size complaint means the document is over the 65535-byte cap.