Skip to content

Provision with Ignition

Ignition is a first-boot provisioning tool that configures Garden Linux systems declaratively before the system becomes operational. Garden Linux uses Ignition primarily for PXE network boot deployments and bare-metal installations.

What is Ignition?

Ignition is a low-level provisioning system that runs during the initramfs stage on first boot. It reads a declarative configuration (in JSON format) and performs system configuration tasks including:

  • Creating users and groups
  • Adding SSH authorized keys
  • Writing files to disk (configuration files, scripts, certificates)
  • Setting file permissions and ownership
  • Enabling and configuring systemd units
  • Formatting disks and creating filesystems

Ignition runs only once during the first boot (ignition.firstboot=1). After completing its tasks, it will not run again on subsequent boots.

When to Use Ignition

Use Ignition for:

  • PXE boot deployments — Network boot installations via iPXE
  • Bare-metal installations — Physical servers with the _ignite feature
  • Metal platform builds — Garden Linux images built with _pxe or metal features

For cloud platform deployments (AWS, Azure, GCP, OpenStack), use cloud-init instead, as these platforms integrate with cloud-init natively.

Prerequisites

  • Garden Linux build with the _ignite feature (automatically included with _pxe)
  • Butane (optional but recommended, for translating YAML to JSON)

Write an Ignition Configuration

Ignition configurations are written in JSON format. For improved readability, write configurations in YAML using the Butane translator, which converts YAML to the JSON format Ignition requires.

Basic Structure (YAML with Butane)

Create a basic Ignition configuration in YAML format:

yaml
variant: fcos
version: 1.3.0
storage:
  files: []
systemd:
  units: []
  • variant: fcos — Specifies Fedora CoreOS compatibility (Garden Linux uses the same Ignition specification)
  • version: 1.3.0 — Ignition configuration version

Create Users and SSH Keys

Add a user with SSH key authentication:

yaml
variant: fcos
version: 1.3.0
passwd:
  users:
    - name: gardenlinux
      groups:
        - wheel
      ssh_authorized_keys:
        - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIExamplePublicKeyHere user@host

The wheel group provides passwordless sudo access in Garden Linux.

Write Configuration Files

Write custom configuration files to disk:

yaml
variant: fcos
version: 1.3.0
storage:
  files:
    - path: /etc/hostname
      mode: 0644
      overwrite: true
      contents:
        inline: |
          my-server.example.com
    - path: /etc/systemd/network/10-eth0.network
      mode: 0644
      overwrite: true
      contents:
        inline: |
          [Match]
          Name=eth0
          
          [Network]
          Address=192.168.1.100/24
          Gateway=192.168.1.1
          DNS=9.9.9.9

Enable Systemd Units

Enable systemd services on first boot:

yaml
variant: fcos
version: 1.3.0
systemd:
  units:
    - name: ssh.service
      enabled: true
    - name: custom-app.service
      enabled: true
      contents: |
        [Unit]
        Description=Custom Application Service
        After=network-online.target
        Wants=network-online.target
        
        [Service]
        Type=simple
        ExecStart=/usr/local/bin/custom-app
        Restart=on-failure
        
        [Install]
        WantedBy=multi-user.target

Merge Multiple Configurations

Split complex configurations into multiple files using the merge directive:

yaml
variant: fcos
version: 1.3.0
ignition:
  config:
    merge:
      - source: http://example.com/base-config.json
      - source: http://example.com/network-config.json
storage:
  files:
    - path: /etc/hostname
      mode: 0644
      overwrite: true
      contents:
        inline: |
          my-server.example.com

Ignition fetches and merges the referenced configurations during first boot.

Translate YAML to JSON with Butane

Install Butane to translate YAML configurations to JSON:

bash
# Download Butane from GitHub releases
BUTANE_VERSION="v0.23.0"
curl -L -o butane \
  "https://github.com/coreos/butane/releases/download/${BUTANE_VERSION}/butane-x86_64-unknown-linux-gnu"

chmod +x butane

Translate the YAML configuration to JSON:

bash
./butane --pretty --strict ignition.yaml > ignition.json

The --strict flag reports warnings as errors, ensuring configuration correctness.

Deliver the Configuration

How you deliver the Ignition configuration depends on the deployment method:

Deployment MethodDelivery Mechanism
PXE BootSpecify ignition.config.url= in the kernel command line (see PXE Boot guide)
Bare Metal (Pre-install)Inject the configuration into the disk image before first boot
VM TestingUse firmware configuration (fw_cfg) or attach as a volume

PXE Boot Example

In your iPXE boot script, specify the Ignition configuration URL:

#!ipxe
set base-url http://192.168.1.10:8080
kernel ${base-url}/rootfs.vmlinuz initrd=rootfs.initrd \
  gl.ovl=/:tmpfs gl.url=${base-url}/root.squashfs gl.live=1 \
  ip=dhcp ignition.firstboot=1 \
  ignition.config.url=${base-url}/ignition.json \
  ignition.platform.id=metal
initrd ${base-url}/rootfs.initrd
boot

Advanced Configuration Examples

Partition and Format Disks

Define custom partition layouts and filesystems:

yaml
variant: fcos
version: 1.3.0
storage:
  files:
    - path: /opt/onmetal-install/partitions
      mode: 0755
      overwrite: true
      contents:
        inline: |
          label: gpt
          type=C12A7328-F81F-11D2-BA4B-00A0C93EC93B, name="EFI", size=510MiB
          type=0FC63DAF-8483-4772-8E79-3D69D8477DE4, name="ROOT"
    - path: /opt/onmetal-install/target
      mode: 0755
      overwrite: true
      contents:
        inline: |
          disk=/dev/sda

This configuration is used by the Garden Linux PXE installation script to partition the target disk.

Install Custom Packages on First Boot

Create a systemd unit that runs once to install additional packages:

yaml
variant: fcos
version: 1.3.0
systemd:
  units:
    - name: install-packages.service
      enabled: true
      contents: |
        [Unit]
        Description=Install Additional Packages
        After=network-online.target
        Wants=network-online.target
        ConditionFirstBoot=yes
        
        [Service]
        Type=oneshot
        RemainAfterExit=yes
        ExecStart=/usr/bin/mount -o remount,rw /usr
        ExecStart=/usr/bin/apt-get update
        ExecStart=/usr/bin/apt-get install -y htop vim curl
        ExecStart=/usr/bin/mount -o remount,ro /usr
        
        [Install]
        WantedBy=multi-user.target

Garden Linux mounts /usr read-only by default. Remount it read-write before installing packages, then remount read-only afterward.

Ignition Platforms

Ignition uses the ignition.platform.id= kernel parameter to identify the platform and determine where to fetch configuration:

Platform IDDescription
metalBare-metal or VM without cloud metadata
qemuQEMU/KVM virtualization
openstackOpenStack cloud platform

For Garden Linux PXE deployments, use ignition.platform.id=metal.

Troubleshooting

View Ignition Logs

If Ignition fails during first boot, check the journal for error messages:

bash
journalctl -u ignition-fetch.service
journalctl -u ignition-disks.service
journalctl -u ignition-files.service

Validate Configuration Syntax

Use Butane to validate your YAML configuration before translating to JSON:

bash
./butane --strict ignition.yaml > /dev/null

If the configuration is valid, Butane outputs nothing. Errors are reported to stderr.

Common Errors

  • Configuration not fetched — Verify the URL specified in ignition.config.url= is reachable from the target system
  • Files not written — Ensure file paths are absolute and parent directories exist
  • Units not enabled — Check systemd unit syntax using systemd-analyze verify

Reference