NoCloud#

The data source NoCloud is a flexible datasource that can be used in multiple different ways. With NoCloud, the user can provide user data and metadata to the instance without running a network service (or even without having a network at all). Alternatively, one may use a custom webserver to provide configurations.

Configuration Methods:#

Warning

User data placed under /etc/cloud/ will not be recognized as a source of configuration data by the NoCloud datasource. While it may be acted upon by cloud-init, using DataSourceNone should be preferred.

Method 1: Labeled filesystem#

A labeled vfat or iso9660 filesystem containing user data and metadata files may be used. The filesystem volume must be labelled CIDATA.

Method 2: Custom webserver#

Configuration files can be provided to cloud-init over HTTP(s). To tell cloud-init the URI to use, arguments must be passed to the instance via the kernel commandline or SMBIOS serial number. This argument might look like:

ds=nocloud;s=https://10.42.42.42/cloud-init/configs/

Note

If using kernel command line arguments with GRUB, note that an unescaped semicolon is intepreted as the end of a statement. Consider using single-quotes to avoid this pitfall. See: GRUB quoting ds=nocloud;s=http://10.42.42.42/cloud-init/configs/

Method 3: FTP Server#

Configuration files can be provided to cloud-init over unsecured FTP or alternatively with FTP over TLS. To tell cloud-init the URL to use, arguments must be passed to the instance via the kernel commandline or SMBIOS serial number. This argument might look like:

ds=nocloud;s=ftps://10.42.42.42/cloud-init/configs/

Method 4: Local filesystem, kernel commandline or SMBIOS#

Configuration files can be provided on the local filesystem at specific filesystem paths using kernel commandline arguments or SMBIOS serial number to tell cloud-init where on the filesystem to look.

Note

Unless arbitrary filesystem paths are required, one might prefer to use DataSourceNone, since it does not require modifying the kernel commandline or SMBIOS.

This argument might look like:

ds=nocloud;s=file://path/to/directory/;h=node-42

Permitted keys#

The permitted keys are:

  • h or local-hostname

  • i or instance-id

  • s or seedfrom

A valid seedfrom value consists of a URI which must contain a trailing /.

HTTP and HTTPS#

The URI elements supported by NoCloud’s HTTP and HTTPS implementations include:

<scheme>://<host>/<path>/

Where scheme can be http or https and host can be an IP address or DNS name.

FTP and FTP over TLS#

The URI elements supported by NoCloud’s FTP and FTPS implementation include:

<scheme>://<userinfo>@<host>:<port>/<path>/

Where scheme can be ftp or ftps, userinfo will be username:password (defaults is anonymous and an empty password), host can be an IP address or DNS name, and port is which network port to use (default is 21).

Path Resource#

The path pointed to by the URI will contain the following files:

user-data (required) meta-data (required) vendor-data (optional)

The user-data file uses user data format. The meta-data file is a YAML-formatted file. The vendor data file adheres to user data formats at the same base URL.

DMI-specific kernel commandline#

Cloud-init performs variable expansion of the seedfrom URL for any DMI kernel variables present in /sys/class/dmi/id (kenv on FreeBSD). Your seedfrom URL can contain variable names of the format __dmi.varname__ to indicate to the cloud-init NoCloud datasource that dmi.varname should be expanded to the value of the DMI system attribute wanted.

Available DMI variables for expansion in seedfrom URL#

dmi.baseboard-asset-tag

dmi.baseboard-manufacturer

dmi.baseboard-version

dmi.bios-release-date

dmi.bios-vendor

dmi.bios-version

dmi.chassis-asset-tag

dmi.chassis-manufacturer

dmi.chassis-serial-number

dmi.chassis-version

dmi.system-manufacturer

dmi.system-product-name

dmi.system-serial-number

dmi.system-uuid

dmi.system-version

For example, you can pass this option to QEMU:

-smbios type=1,serial=ds=nocloud;s=http://10.10.0.1:8000/__dmi.chassis-serial-number__/

This will cause NoCloud to fetch the full metadata from a URL based on YOUR_SERIAL_NUMBER as seen in /sys/class/dmi/id/chassis_serial_number (kenv on FreeBSD) from http://10.10.0.1:8000/YOUR_SERIAL_NUMBER/meta-data after the network initialisation is complete.

Example: Creating a disk#

Given a disk Ubuntu cloud image in disk.img, you can create a sufficient disk by following the following example.

  1. Create the user-data and meta-data files that will be used to modify the image on first boot.

$ echo -e "instance-id: iid-local01\nlocal-hostname: cloudimg" > meta-data
$ echo -e "#cloud-config\npassword: passw0rd\nchpasswd: { expire: False }\nssh_pwauth: True\ncreate_hostname_file: true\n" > user-data
  1. At this stage you have three options:

    1. Create a disk to attach with some user data and metadata:

      $ genisoimage  -output seed.iso -volid cidata -joliet -rock user-data meta-data
      
    2. Alternatively, create a vfat filesystem with the same files:

      $ truncate --size 2M seed.iso
      $ mkfs.vfat -n cidata seed.iso
      
      • 2b) Option 1: mount and copy files:

        $ sudo mount -t vfat seed.iso /mnt
        $ sudo cp user-data meta-data /mnt
        $ sudo umount /mnt
        
      • 2b) Option 2: the mtools package provides mcopy, which can access vfat filesystems without mounting them:

        $ mcopy -oi seed.iso user-data meta-data ::
        
  2. Create a new qcow image to boot, backed by your original image:

$ qemu-img create -f qcow2 -b disk.img -F qcow2 boot-disk.img
  1. Boot the image and log in as “Ubuntu” with password “passw0rd”:

$ kvm -m 256 \
   -net nic -net user,hostfwd=tcp::2222-:22 \
   -drive file=boot-disk.img,if=virtio \
   -drive driver=raw,file=seed.iso,if=virtio

Note

Note that “passw0rd” was set as password through the user data above. There is no password set on these images.

Note

The instance-id provided (iid-local01 above) is what is used to determine if this is “first boot”. So, if you are making updates to user data you will also have to change the instance-id, or start the disk fresh.

Also, you can inject an /etc/network/interfaces file by providing the content for that file in the network-interfaces field of meta-data.

Example meta-data#

instance-id: iid-abcdefg
network-interfaces: |
  iface eth0 inet static
  address 192.168.1.10
  network 192.168.1.0
  netmask 255.255.255.0
  broadcast 192.168.1.255
  gateway 192.168.1.254
hostname: myhost

Network configuration can also be provided to cloud-init in either Networking config Version 1 or Networking config Version 2 by providing that YAML formatted data in a file named network-config. If found, this file will override a network-interfaces file.

See an example below. Note specifically that this file does not have a top level network key as it is already assumed to be network configuration based on the filename.

Example config#

version: 1
config:
   - type: physical
     name: interface0
     mac_address: "52:54:00:12:34:00"
     subnets:
        - type: static
          address: 192.168.1.10
          netmask: 255.255.255.0
          gateway: 192.168.1.254
version: 2
ethernets:
  interface0:
    match:
      macaddress: "52:54:00:12:34:00"
    set-name: interface0
    addresses:
      - 192.168.1.10/255.255.255.0
    gateway4: 192.168.1.254