User data is a script that runs once on an instance’s first boot, before SSH is available. Use it to install packages, add users, drop config files, or kick off your provisioning tool of choice.
All Atlas Linux templates (Ubuntu, Debian, AlmaLinux, Rocky) ship with cloud-init — the de facto standard for this. Pass YAML in the #cloud-config format and cloud-init handles the rest.
Example: bootstrap a sudo user and install packages
#cloud-config
users:
- name: deploy
groups: sudo
shell: /bin/bash
ssh-authorized-keys:
- ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI...
package_update: true
package_upgrade: true
packages:
- curl
- vim
- jq
runcmd:
- echo "Welcome to Atlas Cloud!" > /etc/motdThis creates a deploy user with sudo, drops the SSH key, installs three packages, and writes a motd. The whole thing runs unattended on first boot.
How to pass user data
Console
In the New Instance wizard, expand User Data and paste the YAML.
CLI
cmk expects base64-encoded user data:
cmk deploy virtualmachine \
serviceofferingid=$SO templateid=$TMPL networkids=$NET zoneid=$ZONE \
keypair=mykey name=hello-atlas \
userdata=$(base64 -w0 < user-data.yaml)Terraform
resource "cloudstack_instance" "web" {
name = "web"
service_offering = "Atlas.a5"
template = "Ubuntu 24.04 LTS"
network_id = cloudstack_network.default.id
zone = "is1"
keypair = "mykey"
user_data = file("${path.module}/user-data.yaml")
}The provider base64-encodes for you.
User Data Library
If you reuse the same script across many instances, save it once via Compute → User Data Library and reference it by ID on deploy. This avoids duplicating the script in every Terraform module or cmk call.
USERDATA_ID=$(cmk register userdata name=bootstrap-deploy userdata=$(base64 -w0 < user-data.yaml) | jq -r '.userdata.id')
cmk deploy virtualmachine ... userdataid=$USERDATA_IDWhat runs when
Cloud-init runs once at first boot, before SSH is available. Subsequent boots skip it. Logs go to:
/var/log/cloud-init-output.log
tail -f that file while a VM is starting — it’s the canonical place to see what broke.
Common failures
- My user data didn’t run. Confirm the first line is
#cloud-config(literal text, no<!--etc.). Re-launch the VM after fixing — cloud-init only runs on first boot. - My SSH key wasn’t injected. You probably mixed up the
userdata=andkeypair=parameters. Thekeypair=argument ondeploy virtualmachineis what attaches a registered SSH key from your SSH Key Pairs library; user data is for everything else. apt updatehangs inside cloud-init. Your network’s egress rules likely block outbound TCP 80/443/53 and UDP 53. See Guest networks and allow them.