User-focused, reproducible Ubuntu seedbox provisioning with cloud-init NoCloud seeds.
- Static bundles of
meta-dataanduser-datafor Ubuntu autoinstall. - Ready-to-use sample host profiles under
cloud-init/v1/hosts/you can copy and customize. - A validator script to catch common mistakes before you boot.
- A VM, server, or bare-metal install that supports cloud-init NoCloud.
- Ubuntu Server autoinstall (20.04+)
- One delivery method for the seed:
- ISO/USB labeled
cidatacontaininguser-dataandmeta-data, or - HTTP(S) serving of these files (NoCloud-Net).
- ISO/USB labeled
- Pick a starting profile from
cloud-init/v1/hosts/(e.g.sample,minimal, oransible). - Copy it to a new directory name:
cloud-init/v1/hosts/<your-host>/
- Edit
meta-dataanduser-datato suit your environment. - Create a small ISO (or USB) labeled
cidatacontaining exactly these two files from your new host directory:user-datameta-data
- Attach the media and boot the target. Cloud-init will apply the configuration on first boot.
- Serve the version folder
cloud-init/v1/with any static web server. - Use the included landing page and hosts browser to verify paths.
- Landing page:
.../cloud-init/v1/index.html - Hosts list:
.../cloud-init/v1/hosts/_list.html
- Landing page:
- The installer will fetch these files for your chosen host:
.../hosts/<your-host>/user-data.../hosts/<your-host>/meta-data
Example from the repository root:
python -m http.server 8000 --directory cloud-init/
# Open the helper page in a browser to copy the computed URL:
# http://<server>:8000/index.html
# Or browse host seeds directly:
# http://<server>:8000/hosts/_list.htmlNote: the address needs to be accessible from the target server being installed.
When booting the Ubuntu installer (GRUB/syslinux), add the following to the kernel command line to enable unattended install via HTTP. The helper page shows this with your exact base URL and offers a one-click copy.
autoinstall ds="nocloud;s=http://ashley/cloud-init/v1/hosts/<hostname>/" ip=dhcp
Notes:
- Replace
<hostname>with your host directory name undercloud-init/v1/hosts/. - Keep the trailing
/after the host directory. - The URL must be reachable from the target machine.
- If the ds parameter isn't quoted, you must backslash/escape the semicolon (;) like this:
\;
- Create
cloud-init/v1/hosts/<your-host>/with copies ofmeta-dataanduser-datafrom a sample profile. - Edit
meta-data:- Set a unique
instance-id(often starting with yourlocal-hostname). - Set
local-hostname.
- Set a unique
- Edit
user-data:- Keep the first line
#cloud-config. - Adjust
autoinstallsections (e.g., storage, identity, packages, late-commands). - Re-run the validator until it passes.
- Keep the first line
cloud-init/v1/hosts/minimal/,sample/,ansible/→ example profilesmeta-datauser-data
index.html→ optional landing page if serving over HTTPhosts/_list.html→ optional host browser page when serving over HTTP
scripts/validate_autoinstall.py→ checks your host profilesubuntu_autoinstall_schema.json→ validation schemarequirements.txt→ Python deps for the validator
LICENSE
- Breaking changes will land in new version folders like
cloud-init/v2/.
- See
LICENSE.
- Install requirements once:
pip install -r scripts/requirements.txt- Run the validator:
python scripts/validate_autoinstall.py
# or specify a different hosts dir
python scripts/validate_autoinstall.py --hosts-dir cloud-init/v1/hostsThe validator checks:
- Presence and basic correctness of
meta-data(instance-id,local-hostname). user-dataYAML, top-level#cloud-config, andautoinstallstructure against the official JSON schema.
Schema reference:
- The JSON schema used by the validator is vendored at
scripts/ubuntu_autoinstall_schema.json. See Canonical Subiquity Autoinstall documentation for upstream details.
The one of these days, I'll have the time list:
- Full user-data with comments
- Scaffold profiles for desktop and k8s-node
- Overlays (comon, proxmox, aws)
- J2 templates and snippets
- Clean and release push scripts