Ubuntu server installation and image build hardware

Ubuntu Autoinstall Guide: From YAML to a Tested Server

Build an Ubuntu Autoinstall file with identity, SSH, storage, packages, and late commands, then test the installed server instead of stopping at schema validation.

September 3, 2026

← Back to Blog

Treat Autoinstall as one implementation of a server contract. Validate the YAML first, but accept the build only after the installed machine boots and passes access, service, network, storage, and restart checks.

Ubuntu Server's Subiquity installer reads a YAML autoinstall document. Canonical's current Autoinstall reference specifies a top-level autoinstall mapping and a required integer version, currently 1. The installer validates the configuration against a JSON schema before using it.

Start with a reviewable minimum

The file below is a useful review shape, not a paste-and-forget production answer. Replace the password hash and SSH key. Review the storage policy against the exact machine class. An automatic installer can erase the wrong disk with perfect syntax.

#cloud-config
autoinstall:
  version: 1
  locale: en_US.UTF-8
  keyboard:
    layout: us
  identity:
    hostname: edge-01
    username: ops
    password: "$6$REPLACE_WITH_A_REAL_SHA512_CRYPT_HASH"
  ssh:
    install-server: true
    allow-pw: false
    authorized-keys:
      - "ssh-ed25519 AAAA... operator@example"
  storage:
    layout:
      name: lvm
  packages:
    - curl
    - jq
    - prometheus-node-exporter
  late-commands:
    - curtin in-target --target=/target -- systemctl enable prometheus-node-exporter

Keep command lists explicit. Canonical documents that a command may be a string run through sh -c or an argument list run directly, and that a nonzero exit aborts the installation outside the error-command path. Use curtin in-target when a late command must operate inside the installed target rather than the live installer environment.

Ubuntu Autoinstall validation and acceptance flowYAML is schema checked, delivered to Subiquity, used to install the target disk, and then followed by first-boot acceptance tests.Machine contractSchema checkSubiquityTarget diskFirst bootboot failures refine the machine contractSSH keyservicenetworkstoragereboot
Parser success is an input gate. First-boot behavior is the release gate.

Delivery changes the document boundary

When the file is delivered through cloud-config, keep the top-level autoinstall key. Canonical recommends that shape for all delivery methods because it avoids a common formatting ambiguity. If some sections should remain interactive, list them under interactive-sections; a truly headless build should leave no hidden prompt waiting on a display that nobody can see.

Test the installed state, not the live installer

  1. Boot the installed disk without the installation media attached.
  2. Authenticate with the intended SSH key and reject password login.
  3. Check the expected service is enabled and listening on the intended interface.
  4. Confirm the filesystem and LVM layout match the reviewed storage policy.
  5. Restart once more and repeat the service and network checks.

OpenFactory can hold this machine contract as a recipe and attach VM checks to the build. It does not make an unsafe storage choice safe by changing formats. Keep destructive decisions explicit, then use the hosted boot loop to catch behavior that schema validation cannot see. The broader installation automation map shows where Preseed, Kickstart, and cloud-init move the same contract.

Frequently asked questions

Is Ubuntu Autoinstall the same as cloud-init?

No. Subiquity uses an autoinstall document to control installation. The document can be delivered as cloud-config, but ordinary cloud-init user data usually configures an image that is already installed.

Does schema validation prove an Autoinstall works?

No. Schema validation catches structural errors. It cannot prove that firmware, disk selection, mirrors, network setup, package installation, or the first reboot will work on the target machine.

Should passwords be stored in the YAML file?

Avoid plain-text passwords. The identity password field expects a crypt-compatible hash. Protect the file because a password hash and authorized keys are still security-sensitive deployment material.

Ready to ship this in production?

OpenFactory's free flow is for browsing. Persistent VMs, SSH access, snapshots, your own ISO, and fleet deployment live on a paid plan.