Linux VPS

Automate VPS setup with cloud-init user-data

Use cloud-init user-data to configure a new VPS at first boot: create users and SSH keys, install packages, write files and run commands, then test and debug with cloud-init logs.

IntermediateLinux VPS and cloud VMs2 min read

cloud-init is the standard tool that configures Linux cloud images on first boot. By passing cloud-init user-data when you create a VPS or VM, you can have users, keys, packages and services ready before you ever log in.

Before you start

  • A platform that accepts user-data: many cloud providers, Proxmox (via custom snippets, see Proxmox cloud-init templates), or virt-install --cloud-init on KVM.
  • An image with cloud-init installed (official cloud images include it).
  • Your SSH public key.

A basic user-data file

User-data must start with #cloud-config:

#cloud-config
hostname: web01
timezone: Europe/Berlin
users:
  - name: deploy
    groups: sudo
    shell: /bin/bash
    sudo: "ALL=(ALL) NOPASSWD:ALL"
    ssh_authorized_keys:
      - ssh-ed25519 AAAA...your-key... you@laptop
ssh_pwauth: false
disable_root: true
package_update: true
package_upgrade: true
packages:
  - nginx
  - ufw
  - fail2ban
write_files:
  - path: /var/www/html/index.html
    content: |
      <h1>Provisioned by cloud-init</h1>
runcmd:
  - ufw allow OpenSSH
  - ufw allow 'Nginx Full'
  - ufw --force enable
  - systemctl enable --now nginx

This mirrors the manual steps in first steps on a new VPS.

Key modules

KeyWhat it does
usersCreate accounts, groups, sudo rules and SSH keys
packagesInstall packages with the distro package manager
write_filesCreate files with content, owner and permissions
runcmdRun commands once at the end of first boot
bootcmdRun early on every boot
power_stateReboot or power off when finished

Validate before use

cloud-init schema --config-file user-data.yaml

Older versions use cloud-init devel schema. YAML indentation errors are the most common cause of failure.

Check results and debug

cloud-init status --long
sudo less /var/log/cloud-init-output.log

Detailed module logs are in /var/log/cloud-init.log. To re-run on a test VM: sudo cloud-init clean --logs && sudo reboot.

Security tips

  • User-data is often readable from inside the VM (metadata service). Do not put passwords, API keys or private keys in it; fetch secrets from a vault or inject them later.
  • Prefer SSH keys and disable password login, as above.

Troubleshooting

  • Nothing happened: the file does not start with #cloud-config, or the platform did not pass it.
  • Packages failed: network not ready or wrong package names for that distribution.
  • runcmd ran but service not running: check the output log for the failing command.

Frequently asked questions

Does cloud-init run on every boot?

Most modules run once per instance. bootcmd and some modules run every boot.

Can I use a shell script instead?

Yes, user-data starting with #!/bin/bash is executed as a script.

cloud-init or Ansible?

Use cloud-init for first-boot bootstrapping and Ansible for ongoing configuration; see Ansible for VPS setup.

Next steps

Was this guide helpful?

Still stuck?

Ask MdmHost AI for a quick answer, or open a ticket and our team will take a look. We are here 24/7.