Skip to content
NimbusVPS
API & automation

cloud-init recipes

Prepare guest configuration recipes and confirm cloud-init support for the selected image before using them.

6 min readUpdated

Confirm that the selected image supports cloud-init and how user data is supplied for your order. The recipes below are starting points: replace example values, review the commands and verify the resulting guest configuration after delivery.

A hardened baseline

#cloud-config
hostname: node-01
fqdn: node-01.example.com

users:
  - name: deploy
    groups: [sudo]
    shell: /bin/bash
    sudo: ['ALL=(ALL) NOPASSWD:ALL']
    ssh_authorized_keys:
      - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI...

package_update: true
package_upgrade: true
packages:
  - ufw
  - fail2ban
  - unattended-upgrades
  - nftables

write_files:
  - path: /etc/ssh/sshd_config.d/99-hardening.conf
    content: |
      PermitRootLogin no
      PasswordAuthentication no
      AuthenticationMethods publickey
      MaxAuthTries 3

runcmd:
  - ufw default deny incoming
  - ufw default allow outgoing
  - ufw allow 22/tcp
  - ufw --force enable
  - systemctl enable --now fail2ban
  - systemctl restart sshd

power_state:
  mode: reboot
  message: cloud-init complete
  timeout: 30

Docker host

#cloud-config
packages: [ca-certificates, curl, gnupg]
runcmd:
  - install -m 0755 -d /etc/apt/keyrings
  - curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc
  - echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian bookworm stable" > /etc/apt/sources.list.d/docker.list
  - apt-get update
  - apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
  - usermod -aG docker deploy

WireGuard endpoint

#cloud-config
packages: [wireguard, nftables]
write_files:
  - path: /etc/wireguard/wg0.conf
    permissions: '0600'
    content: |
      [Interface]
      Address = 10.66.66.1/24
      ListenPort = 51820
      PrivateKey = SERVER_PRIVATE_KEY
      PostUp = nft add rule inet filter forward iifname wg0 accept
      PostUp = nft add rule inet nat postrouting oifname eth0 masquerade

      [Peer]
      PublicKey = CLIENT_PUBLIC_KEY
      AllowedIPs = 10.66.66.2/32
runcmd:
  - sysctl -w net.ipv4.ip_forward=1
  - echo 'net.ipv4.ip_forward=1' >> /etc/sysctl.conf
  - systemctl enable --now wg-quick@wg0

Verifying

cloud-init status --wait
cloud-init analyze show
journalctl -u cloud-final

If something did not apply, /var/log/cloud-init-output.log has the answer. Check YAML indentation, supported modules and the commands reported in the log.

Choose your server and see the total.

Choose your location, resources and term. Pay in crypto after reviewing the total; payment is verified automatically before your VPS is prepared.

Minimum 3-month VPS term ยท No ID upload in checkout ยท 7-day refund policy with exclusions