Skip to content

cloud init

Jesús Daniel Colmenares Oviedo edited this page Aug 4, 2025 · 1 revision

Deploying virtual machines using cloud-init

Provisioning a virtual machine shouldn't be difficult, and it isn't thanks to the industry-standard tool for customizing cloud instances, namely cloud-init. Overlord can customize a FreeBSD virtual machine before it starts up, but although this works in almost all cases, you may sometimes want to customize the virtual machine using tools that are only available on the guest operating system. Another disadvantage of the above method is that it only works with FreeBSD. In some cases, you may not want to customize the virtual machine itself, but rather use it to perform temporary tasks, such as compiling software, so why not use YAML for that?

debian.yml:

kind: vmJail
datacenters:
  main:
    entrypoint: !ENV '${ENTRYPOINT}'
    access_token: !ENV '${TOKEN}'
deployIn:
  labels:
    - provider
vmName: 'debian'
makejail: 'gh+DtxdF/vm-makejail'
options:
  - fstab: '"/var/os-images/uploads" /vm/.img nullfs ro'
  - pkg: grub2-bhyve
  - pkg: qemu-tools
template:
  loader: 'grub'
  cpu: '1'
  memory: '512M'
  network0_type: 'virtio-net'
  network0_switch: 'public'
  wired_memory: 'YES'
  grub_run_partition: '1'
  grub_run_dir: '/boot/grub'
  uuid: !ENV '${INSTANCE_ID}'
diskLayout:
  driver: 'ahci-hd'
  size: '40G'
  from:
    type: 'img'
    imgFile: 'debian-13-generic-amd64-daily.qcow2'
cloud-init:
  meta-data:
    instance-id: !ENV '${INSTANCE_ID}'
    local-hostname: debian.lan
  network-config:
    version: 2
    ethernets:
      id0:
        match:
            name: 'enp0s5'
        addresses:
          - 192.168.8.2/24
        routes:
            - to: default
              via: 192.168.8.1
        nameservers:
          search: []
          addresses: [172.0.0.1]
  user-data:
    resize_rootfs: True
    manage_etc_hosts: localhost
    user:
        name: user
        homedir: '/user'
        ssh_authorized_keys:
            - !ENV '${SSH_KEY}'
        sudo: 'ALL=(ALL) NOPASSWD:ALL'
    package_update: True
    package_upgrade: True
    runcmd:
      - ['sh', '-c', 'curl -fsSL https://tailscale.com/install.sh | sh']
      - ['tailscale', 'up', !ENV '--auth-key=${TS_AUTH_KEY}']

It's easy to understand even if you're not familiar with cloud-init. Basically, we'll create a virtual machine with 512 MiB of memory, 40 GiB of virtual disk space, and 1 CPU core assigned. We'll use Debian (Trixie) cloud image. The network configuration is the same as in other types of installation (in this case, static). The user (user) is created with a public SSH key and a sudo rule that allows me to perform administrative tasks. And last but not least, we will install tailscale and initialize it so that we can access from anywhere.

console:

$ overlord apply -f debian/app.yml
$ overlord get-info -f debian/app.yml -t projects --filter-per-project
datacenter: http://controller.namespace.lan:8888
  entrypoint: main
  chain: provider
  labels:
    - all
    - provider
    - vm-only
  projects:
    debian:
      state: DONE
      last_log: 2025-08-04_12h43m53s
      locked: False
      services:
        - {'name': 'vm', 'status': 0, 'jail': 'debian'}
      up:
        operation: COMPLETED
        output:
         rc: 0
         stdout: {'errlevel': 0, 'message': None, 'failed': []}
        last_update: 5 minutes and 55.49 seconds
        job_id: 1
        restarted: False
$ overlord get-info -f debian/app.yml -t vm --filter-per-project
datacenter: http://controller.namespace.lan:8888
  entrypoint: main
  chain: provider
  labels:
    - all
    - provider
    - vm-only
  projects:
    debian:
      virtual-machines:
          operation: COMPLETED
          output: |
            vm_list:  -> debian
             Starting debian
               * found guest in /vm/debian
               * booting...
          last_update: 5 minutes and 0.34 seconds
          job_id: 1

The output of cloud-init can be viewed from the console or from the /var/log/cloud-init*.log files inside the virtual machine. In any case, after deploying the virtual machine, cloud-init will run, so let's check our tailnet:

$ tailscale status | grep debian
100.84.224.49   debian               REDACTED@    linux   -
$ ssh user@100.84.224.49
The authenticity of host '100.84.224.49 (100.84.224.49)' can't be established.
ED25519 key fingerprint is SHA256:xirQAVqcoX8ulj1lp32+blVI03Zth6f9HxpMk8KJSc4.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '100.84.224.49' (ED25519) to the list of known hosts.
Linux debian 6.12.38+deb13-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.12.38-1 (2025-07-16) x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
user@debian:~$

Clone this wiki locally