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
_ignitefeature - Metal platform builds — Garden Linux images built with
_pxeormetalfeatures
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
_ignitefeature (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:
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:
variant: fcos
version: 1.3.0
passwd:
users:
- name: gardenlinux
groups:
- wheel
ssh_authorized_keys:
- ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIExamplePublicKeyHere user@hostThe wheel group provides passwordless sudo access in Garden Linux.
Write Configuration Files
Write custom configuration files to disk:
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.9Enable Systemd Units
Enable systemd services on first boot:
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.targetMerge Multiple Configurations
Split complex configurations into multiple files using the merge directive:
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.comIgnition fetches and merges the referenced configurations during first boot.
Translate YAML to JSON with Butane
Install Butane to translate YAML configurations to JSON:
# 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 butaneTranslate the YAML configuration to JSON:
./butane --pretty --strict ignition.yaml > ignition.jsonThe --strict flag reports warnings as errors, ensuring configuration correctness.
Deliver the Configuration
How you deliver the Ignition configuration depends on the deployment method:
| Deployment Method | Delivery Mechanism |
|---|---|
| PXE Boot | Specify 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 Testing | Use 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
bootAdvanced Configuration Examples
Partition and Format Disks
Define custom partition layouts and filesystems:
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/sdaThis 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:
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.targetGarden 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 ID | Description |
|---|---|
metal | Bare-metal or VM without cloud metadata |
qemu | QEMU/KVM virtualization |
openstack | OpenStack 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:
journalctl -u ignition-fetch.service
journalctl -u ignition-disks.service
journalctl -u ignition-files.serviceValidate Configuration Syntax
Use Butane to validate your YAML configuration before translating to JSON:
./butane --strict ignition.yaml > /dev/nullIf 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
- Ignition Documentation (Fedora CoreOS)
- Ignition Specification
- Ignition Configuration Examples
- Butane Documentation
- Butane Configuration Specification