Toolkit for declarative configuration of a Fedora CoreOS server.
This project will allow users to serve custom Ignition-compatible configurations that can be used to seed a Fedora CoreOS installation. To do this, it uses the configuration specified in secrets.yml
and transforms it into a format that is compatible with the Butane 1.5.0 specification.
All configuration settings and secrets are defined in the secrets.yml
file. For more details, see specification section below.
Jinja2 templates are included in the templates
folder.
Template | Description |
---|---|
etc/samba/smbusers.export.j2 | Creates file containing the samba users to create on system startup. |
etc/systemd/system/backup.target.j2 | Creates systemd target unit (backup.target ) that contains a timer for each container that has a backup configuration specified. |
etc/systemd/system/healthcheck-container.target.j2 | Creates systemd target unit (healthcheck-container.target ) that contains a timer for each container that has a monitoring URL. |
etc/systemd/system/sync.target.j2 | Creates a systemd target unit (sync.target ) that contains a timer for each synchronization job that has been specified. |
etc/environment.j2 | Creates the /etc/environment file containing the variables specified for the host. |
etc/hosts.j2 | Creates the /etc/hosts file containing the provided ip & host mappings. |
config.bu.j2 | Creates the config.bu file containing the Butane 1.5.0 compatible configuration. |
container-backup.conf.j2 | Creates the drop-ins for container services that contain the necessary environment variables for creating backups. |
container-core.conf.j2 | Creates the 00--core.conf drop-in containing implicit environment variables (ex. CONTAINER_PATH) derived from container configuration. |
container-healthcheck.conf.j2 | Creates the drop-in containing the monitor URL for container healthchecks. |
container-override.conf.j2 | Creates the specified drop-in files containing explicitly defined variables and volumes for containers. |
firewalld.xml.j2 | Creates the firewalld configuration files in the /etc/firewalld/zones folder. |
firewalld-wireguard.xml.j2 | Creates a firewalld service for wireguard connections. |
monitor.path.j2 | Creates a systemd Path unit for monitoring filesystem paths for changes. |
monitor.service.j2 | Creates a systemd Service unit to be invoked by the Path unit. |
network.nmconnection.j2 | Creates the network configuration files in the /etc/NetworkManager/system-connections folder. |
path.mount.j2 | Creates systemd mount units in the /etc/systemd/system folder. |
rclone.conf.j2 | Creates the /etc/rclone/rclone.conf configuration file. |
smb.conf.j2 | Creates the /etc/samba/smb.conf configuration file. |
sync.conf.j2 | Creates the systemd drop-in containing variable definitions to support a synchronization job. |
The justfile
contains recipes for making it easier to build & deploy the project.
Recipe | Description |
---|---|
build [secretfile] | Uses butane to transpile configuration into an ignition file. |
clean [secretfile] | Removes all rendered templates, Ignition files and untracked files. |
configure [secretfile] | Renders Jinja2 templates to produce files and Butane-compatible configuration. |
download-iso | Downloads the latest stable Fedora CoreOS ISO. |
install-deps | Installs python package dependencies. |
serve [secretfile] | Spins up a web server to host the generated Ignition file. |
This specification extends the Fedora CoreOS Butane Configuration Specification to add additional functionality. It produces a Butane configuration that can be transpiled to create an Ignition file for Fedora CoreOS installations.
-
hostname (string)
Hostname for the computer. Value is combined with
domain
and written to/etc/hostname
. -
domain (string)
Domain for the computer. Value is combined with
hostname
and written to/etc/hostname
. -
timezone (string)
String representing a time zone (ex.
America/New_York
) -
containers (object[])
List of container objects. The values provided will be used to configure containers.
-
name (string)
Name of the container. The value provided will be used for the name of the container's environment file stored in
/etc/containers/config/
. -
path (string)
Path to the container's volumes,
CONTAINER_PATH
. This variable is referenced by the container quadlets for bind-mounting volumes. -
dataset (string)
The ZFS dataset containing container volumes. This dataset will have a snapshot taken prior to each backup.
-
monitor_url (string)
The URL for the healthchecks.io healthcheck responsible for monitoring container health.
-
backup (object)
Backup job for container files.
-
path (string)
Path to store backup files.
-
monitor_url (string)
The URL for the healthchecks.io healthcheck responsible for monitoring backup health.
-
remotes (string[])
The list of Rclone remotes to utilize when synchronizing backup files. These are defined in
/etc/rclone.conf
. The remotes listed here should match those specified in therclone
section below. -
keep_daily (integer)
Number of daily backups to keep.
-
keep_weekly (integer)
Number of weekly backups to keep.
-
keep_monthly (integer)
Number of monthly backups to keep.
-
keep_yearly (integer)
Number of yearly backups to keep.
-
-
overrides (object[])
Overrides for podman.unit drop-in files.
π NOTE Some container options do not work (ex. AddHost
). When a container option doesn't work the service is not loaded by systemd. Unsure of what other options do not work, butEnvironment
andVolume
appear to work.-
file ((string))
Name for drop-in file.
-
options ((object[]))
List of options for drop-in file.
-
key (string)
Container option for drop-in file.
-
value (string)
Value for Container option
-
section (string)
Section of unit file for option
-
-
Example:
containers: - name: mealie path: /var/pool/volumes/mealie dataset: pool/volumes/mealie backup: path: /my/borg/repo/mealie remotes: - backblaze keep_daily: 7 keep_weekly: 4 keep_monthly: 2 keep_yearly: 0 overrides: - file: 10-mealie-variables.conf options: - key: Environment value: "PGID=1000" - key: Environment value: "PUID=1000" - key: Environment value: "TZ=America/New_York" - key: Environment value: "WEB_PORT=8080" section: Service
-
-
directories (string[])
List of additional directories to create. The paths specified should be absolute.
Example:
directories: - /var/pool
-
disks (string[])
List of disk devices to use in a mirrored pool for root. (NOTE: This doesn't appear to function properly.)
Example:
disks: - /dev/disk/by-id/unique-name-disk-1 - /dev/disk/by-id/unique-name-disk-2
-
environment (string[])
List of environment variables. Variables should be specified in
KEY=VALUE
pair format so they can be sourced by systemd unit files. The variables listed here will be written to/etc/environment
.The variables
BACKUP_KEY
,SHARED_VOLUMES_PATH
,UPDATES_MONITOR_URL
, &ZFS_MONITOR_URL
are utilized by systemd unit files. They must exist for dependent services to execute.The variable
BACKUP_KEY
represents the passphrase used for encrypting files during the backup process. TheSHARED_VOLUMES_PATH
variable represents the path to the location of files that are shared across containers. TheUPDATES_MONITOR_URL
represents the healthchecks.io URL that will be triggered when important security updates are available. TheZFS_MONITOR_URL
represents the healthchecks.io URL that will be triggered when any ZFS pool is unhealthy.Example:
environment: - "BACKUP_KEY=my-borg-passphrase"
-
firewall (object[])
List of firewall zone configurations. The values provided will be written to zone configuration files in
/etc/firewalld/zones/
.-
zone (string)
Unique name for firewall zone. This name will be used to name the XML file written to
/etc/firewalld/zones/
. -
services (string[])
List of services to enable for firewall zone. The provided services must exist.
Example:
firewall: - zone: Public services: - ssh - mdns
-
-
hosts (object[])
IP address to host mappings for
/etc/hosts
file.-
ip (string)
IP address for host.
-
host (string)
Name for host
Example:
hosts: - ip: 192.168.1.2 host: mypc
-
-
keys (object[])
SSH host keys for restoration.
-
path (string)
Path to SSH host key file.
-
content (string)
Content for SSH host key (NOTE: Use literal (|) block style to preserve line breaks.)
-
owner (string)
Owner for SSH host key. This is typically
root
. -
group (string)
Group for SSH host key. This is typically
root
. -
mode (string)
Mode for SSH host key. This is typically
0600
for private keys and0644
for public keys.
Example:
keys: - path: /etc/ssh/ssh_host_ecdsa_key content: | -----BEGIN OPENSSH PRIVATE KEY----- This is my fake private key -----END OPENSSH PRIVATE KEY----- owner: root group: root mode: '0600'
-
-
links (object[])
List of symlinks to create.
-
path (string)
Path for link
-
target (string)
Path for link to target. This path can be relative to the link path.
Example:
# This link will automatically be included and will utilize the value provided to timezone above. It's listed here for demonstration purposes only. links: - path: /etc/localtime target: /usr/share/zoneinfo/America/New_York
-
-
monitors (object[])
List of paths to monitor for filesystem changes. Changes will kick off the specified systemd service.
-
name (string)
Name for the systemd Path unit that will be created to monitor the filesystem path.
-
description (string)
Description of the filesystem monitor for the systemd Path unit
-
path (string)
Path to be monitored for filesystem changes.
-
service (object)
The systemd service to be invoked when there is a filesystem change for the monitored path.
-
description (string)
Description of the service that will be invoked.
-
options (object[])
List of key-value pairs for systemd service files.
-
key (string)
Key for systemd service.
-
value (string)
Value for systemd service.
-
-
requires (string[])
List of services required for systemd service.
-
Example
monitors: - name: music-updated description: Path for monitoring staged music path: /var/home/core/Music service: description: Service for processing new audio files options: - key: ExecCondition value: systemctl is-active --quiet beets.service - key: ExecStart value: podman exec beets /bin/bash -c "beet import /downloads" requires: - beets.service
-
-
mounts (object[])
List of devices to mount. Mount files will be created and stored in
/etc/systemd/system/
for each path specified.-
path (string)
Path to source path/device.
-
target (string)
Path to target location.
-
options (string[])
List of options to apply when mounting.
-
requires (string[])
List of services required for the mount.
-
before (string[])
List of services dependent on the mount.
-
after (string[])
List of services required to start before mounting.
-
description (string)
Description of the mount point.
Example:
mounts: - path: /var/my/folder target: /var/mounts/binds/locationA options: - bind requires: - zfs-mount.service before: - plex.service after: - zfs-mount.service description: My bind mount
-
-
network (object[])
List of networks and their configurations. The configurations specified below will be written to
.nmconnection
files in the/etc/NetworkManager/system-connections/
folder.-
interface (string)
Name for interface to configure.
-
type (string)
Type of the interface to configure (ex.
ethernet
) -
settings (object[])
Group of settings for protocol. This is representative of a section in the
.nmconnection
file.-
protocol (string)
Protocol name. This will be used as the name for the section header (ex.
ipv4
). -
options (object[])
List of key-value pairs for protocol settings. These will be assembled into
KEY=VALUE
format for.nmconnection
file.-
key (string)
Property for protocol (ex.
method
) -
value (string)
Value for property (ex.
auto
)
-
-
Example:
network: - interface: eth0 type: ethernet settings: - protocol: ipv4 options: - key: method value: auto - protocol: ipv6 options: - key: method value: disabled
-
-
rclone (object[])
List of remotes to target when synchronizing backups. To specify which remotes to use when backing up containers, see the container specification above.
-
remote (string)
Unique name for remote. These values will be used for section headers in the Rclone configuration and will also be used when specifying the remotes to use when backing up containers.
-
type (string)
Type for remote (ex. b2). For a full list of supported remote types, review the Rclone Documentation.
-
account (string)
Account identifier for remote.
-
key (string)
Key or passphrase for remote.
Example:
rclone: - remote: backblaze type: b2 account: my-account-id key: my-account-key
-
-
samba (object[])
List of options that represent the Samba configuration.
-
configuration (object[])
-
options (object[])
List of key-value pairs for configuration option.
-
key (string)
Samba property (ex.
read only
). -
value (string)
Value for Samba property (ex.
no
).
-
-
-
users (string[])
Exports of samba user data using
sudo pdbedit -L -w
.
Example:
samba: configuration: - name: global options: - key: netbios name value: myserver - key: workgroup value: WORKGROUP - key: server string value: Samba %v server - key: security value: user - key: passdb backend value: tdbsam - key: include value: /etc/samba/usershares.conf comment: Install samba-usershares package for support - name: shared_docs options: - key: comment value: Folder for Shared Documents - key: path value: /var/my/shared/docs - key: read only value: no - key: browseable value: yes
-
-
sync (object[])
List of synchronization jobs. These jobs will synchronize two locations using
rsync
and the options provided below.-
name (string)
Unique name for synchronization pair. This value will be used for the template units and environment files.
-
source (string)
Valid source for synchronization. This can be a path or a device.
-
target (string)
Valid target for synchronization. This can be a path or a device.
-
options (string[])
List of synchronization options. See rsync(1) for more information about the options available for
rsync
. -
cooldown (integer)
Number of seconds to between synchronization operations. The value provided here will be used to prevent execution of the service again until the cooldown period has been exceeded.
Example:
sync: name: music-usb source: /path/to/music target: /path/to/usb/device options: - '-vrht' - '--modify-window=1' - '--exclude=Michael[[:space:]]Jackson' - '--delete' - '--delete-excluded'
-
-
users (object[])
List of user accounts.
-
name (string)
Unique name for user
-
password (string)
Hashed password for user account (See mkpasswd(1)).
-
pubkeys (string[])
List of public keys to write to ~/.ssh/authorized_keys
-
- Update the
config.bu.j2
template to include any changes to the butane configuration. - Define secrets in the
secrets.yml
file. Use thesecrets.yml.example
file as an example. - To configure Samba within the
secrets.yml
file, use thesmb.conf.example
file as an example to use for building the key value pairs. - Execute
just download-iso
to download the latest Fedora CoreOS ISO file. Write the ISO to a USB drive using Etcher (or similar tool) - Execute
just serve
to configure, build and serve the ignition file. - Boot into Fedora CoreOS live distribution.
- Execute
sudo coreos-installer install --insecure-ignition --ignition-url http://<web-server-ip>/.generated/config.ign <disk-device>
. Example:sudo coreos-installer install --insecure-ignition --ignition-url http://192.168.1.100/.generated/config.ign /dev/nvme0n1
. - Execute
poweroff
, unplug the USB drive, and power on the machine again. Follow the instructions for automatos-server to rebase to new image.
π NOTE |
---|
For Windows development, execute the command winget import -i apps.json from an administrative Powershell window to install required dependencies. You will also need to use an administrative powershell window to run the configure recipe since it creates symlinks. |