For the complete documentation index, see llms.txt. This page is also available as Markdown.

Cloud-init user-data

Configure a VM on its first boot with cloud-init user-data, on both Linux and Windows images.

When you create a VM you can pass a user_data object along with the request. Its contents are handed to the VM as cloud-init user-data and processed by the guest on first boot only — it is not re-applied on later reboots.

Use it to create users, install SSH keys, write files, install packages, or run a provisioning script, so that a VM comes up ready for your workload without a second configuration pass.

User-data is supported on both Linux and Windows images. See Windows images for the specifics.

Passing user-data

Add user_data to the create-VM request body:

POST /v3/flexVM/clouds/{cloudUuid}/vms
Host: api.i3d.net
PRIVATE-TOKEN: YOUR_API_KEY
Content-Type: application/json

{
  "name": "development.ubuntu-2404",
  "description": "DB1 VM",
  "image_name": "ubuntu-2404-server-amd64",
  "instance_type_name": "vm.gpu.1rtx4000.30c.240g",
  "user_data": {
    "data": "#cloud-config\nusers:\n  - name: deploy\n    sudo: ALL=(ALL) NOPASSWD:ALL\n    shell: /bin/bash\n    ssh_authorized_keys:\n      - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHwdgjY0AlmkeLknBpoVmJg/quNSifyBHEK1MREpV4Ri john.doe@i3d.net\npackage_update: true\npackages:\n  - htop\n",
    "is_base64": false
  }
}

For a Terraform example, see Using Terraform — the provider takes the user-data from a file through user_data_file.

ssh_keys or user_data

ssh_keys and user_data are two alternative ways to get access to a new VM, and they cannot be combined:

Request
Result

ssh_keys only

FlexVM generates the cloud-init configuration and installs your keys.

user_data only

Your user-data is used as-is. You configure access yourself.

Both

Rejected with 422.

Neither

Rejected with 422 on Linux images. Allowed on Windows images.

Your VM's network configuration (IP address, prefix, and gateway from your Tenant VLAN) is applied separately by FlexVM and is not affected by custom user-data. See Network Configuration.

Format and size

user_data.data accepts any format cloud-init itself supports — most commonly a #cloud-config document or a shell script. See the cloud-init user-data formats and example configurations.

  • Length must be between 1 and 64000 characters.

  • Set is_base64 to true when data is base64-encoded. Use this for content that cannot be carried as JSON text — for example gzip-compressed user-data, which is also a way to stay within the size limit. Default is false. If is_base64 is true and data is not valid base64, the request is rejected with a 400.

Write-only and immutable

  • User-data is write-only: it is never returned by the GET VM endpoints. Keep your own copy of what you sent — for example the file you feed to Terraform's user_data_file.

  • It is set at creation only. To change a VM's user-data, delete the VM and create a new one.

  • It is stored encrypted at rest, so it is a valid place for tokens or passwords your first-boot configuration needs. As with any provisioning data, prefer short-lived credentials.

Linux images

Linux images run cloud-init, so #cloud-config and script formats work as documented upstream. A minimal configuration that keeps you in control of access:

Windows images

i3D.net Windows images ship with Cloudbase-Init, the Windows implementation of cloud-init, so the same user_data field applies.

  • user_data is optional on Windows. i3D.net Windows images are created with a default Administrator password, which i3D.net provides to you, so a Windows VM is reachable without any user-data. ssh_keys has no effect on Windows images.

  • Supply user_data when you want the VM configured on first boot anyway — to rotate that default password, add accounts, enable a remote-access method, or run your own provisioning script.

  • Cloudbase-Init supports a subset of #cloud-config plus plain scripts (PowerShell, batch, bash). A PowerShell script is the most predictable option; see the Cloudbase-Init user-data documentation for what each format covers.

  • Windows Firewall is on by default and blocks inbound SSH. Windows OpenSSH listens on port 22, the same as Linux, but nothing reaches it until an inbound rule allows it for the firewall profile the VM's network is in. Windows classifies an unidentified network as Public, so a rule scoped to Private or Domain has no effect and SSH still times out even though sshd is running. The examples below scope the rule to Any for that reason.

Allow several minutes before the VM answers. A Windows VM reports running well before Cloudbase-Init has finished with it. The network configuration is applied partway through first boot — the interface switches from DHCP to its static address at that point — and a script that installs the OpenSSH server capability adds a few minutes more on top.

In our testing, a Windows VM first accepted an SSH connection roughly 7 minutes after boot. Connections attempted before that are refused or time out, which looks identical to a misconfigured VM. Wait out the first ten minutes or so before you start troubleshooting access.

Example: enable OpenSSH with a key, without a password

This variant sets no password at all, so nothing secret goes into the request body. Note that members of the Administrators group share one authorized-keys file, and OpenSSH ignores that file unless its permissions are tightened:

This adds key-based SSH access but leaves the image's default Administrator password in place, so password logins (for example over RDP) remain possible with it. Rotate or disable that password separately if you want key-only access to be the only way in.

Example: enable OpenSSH, rotate the default Administrator password

Example: Enable OpenSSH, RDP and rotate the default Administrator password

Example: enable WinRM, rotate the default Administrator password

WinRM is the transport behind PowerShell Remoting (Enter-PSSession, Invoke-Command) and Ansible's winrm connection. The service is installed on every Windows image but is not listening, and the same restrictive firewall applies to its port 5985 as to SSH:

Because the VM is not domain-joined, your client has to be told to trust it before it will send credentials over HTTP:

Port 5985 is HTTP, but the payload is still encrypted by the Negotiate/NTLM session, so AllowUnencrypted does not need to be turned on — leave it off. Because HTTP WinRM does not validate the server identity, use 5985 only on trusted networks/VPN; for exposure beyond that, prefer a TLS listener on 5986 (requires a certificate in the image or installed by the script).

This example authenticates as the built-in Administrator. Any other local administrator is filtered by remote UAC over WinRM and comes back as access denied; if you provision one, also set LocalAccountTokenFilterPolicy to 1 under HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System.

Bringing your own Windows image

You can supply your own Windows image. Cloudbase-Init must be installed in it for user_data to be processed — if it isn't, the field is ignored and the image must already contain whatever access method you intend to use. Preparing your own image also means the default-Administrator-password behaviour above does not apply: your image defines its own initial access. Contact i3D.net support to have a custom image onboarded.

Troubleshooting

If a VM reaches running but you cannot log in, the most likely cause is user-data that did not configure access. See Cannot SSH into a running VM.

Last updated

Was this helpful?