diff --git a/main.yml b/main.yml index 50a5bd9..573fe91 100644 --- a/main.yml +++ b/main.yml @@ -1,4 +1,14 @@ --- +# Bootstrap pipeline — role execution order: +# 1. global_defaults — normalize + validate system/hypervisor/disk input +# 2. system_check — pre-flight hardware/environment safety checks +# 3. virtualization — create VM on hypervisor (libvirt/proxmox/vmware/xen) +# 4. environment — detect live ISO, configure installer network, install tools +# 5. partitioning — partition disk, create FS, LUKS, LVM, mount everything +# 6. bootstrap — debootstrap/pacstrap/dnf install the target OS into /mnt +# 7. configuration — users, network, encryption, fstab, bootloader, services +# 8. cis — CIS hardening (optional, per system.features.cis.enabled) +# 9. cleanup — unmount, remove cloud-init artifacts, reboot/shutdown - name: Create and configure VMs hosts: "{{ bootstrap_target | default('all') }}" strategy: free # noqa: run-once[play] diff --git a/roles/global_defaults/tasks/_normalize_system.yml b/roles/global_defaults/tasks/_normalize_system.yml index cda5a71..e5dcd4c 100644 --- a/roles/global_defaults/tasks/_normalize_system.yml +++ b/roles/global_defaults/tasks/_normalize_system.yml @@ -12,15 +12,22 @@ }} ansible.builtin.set_fact: system_cfg: + # --- Identity & platform --- type: "{{ system_type }}" os: "{{ system_os_input if system_os_input | length > 0 else ('archlinux' if system_type == 'physical' else '') }}" version: "{{ system_raw.version | default('') | string }}" filesystem: "{{ system_raw.filesystem | default('') | string | lower }}" name: "{{ system_name }}" id: "{{ system_raw.id | default('') | string }}" + # --- VM sizing (ignored for physical) --- cpus: "{{ [system_raw.cpus | default(0) | int, 0] | max }}" memory: "{{ [system_raw.memory | default(0) | int, 0] | max }}" balloon: "{{ [system_raw.balloon | default(0) | int, 0] | max }}" + # --- Network --- + # Flat fields (bridge, ip, etc.) and interfaces[] are mutually exclusive. + # When interfaces[] is set, flat fields are populated from the first + # interface in the "Populate primary network fields" task below. + # When only flat fields are set, a synthetic interfaces[] entry is built. network: bridge: "{{ system_raw.network.bridge | default('') | string }}" vlan: "{{ system_raw.network.vlan | default('') | string }}" @@ -56,6 +63,7 @@ else [] ) }} + # --- Locale & environment --- timezone: "{{ system_raw.timezone | default('Europe/Vienna') | string }}" locale: "{{ system_raw.locale | default('en_US.UTF-8') | string }}" keymap: "{{ system_raw.keymap | default('us') | string }}" @@ -71,10 +79,12 @@ | reject('equalto', '') | list }} + # --- Storage & accounts --- disks: "{{ system_raw.disks | default([]) }}" users: "{{ system_raw.users | default([]) }}" root: password: "{{ system_raw.root.password | string }}" + # --- LUKS disk encryption --- luks: enabled: "{{ system_raw.luks.enabled | bool }}" passphrase: "{{ system_raw.luks.passphrase | string }}" @@ -94,6 +104,7 @@ pbkdf: "{{ system_raw.luks.pbkdf | string }}" urandom: "{{ system_raw.luks.urandom | bool }}" verify: "{{ system_raw.luks.verify | bool }}" + # --- Feature flags --- features: cis: enabled: "{{ system_raw.features.cis.enabled | bool }}" diff --git a/roles/global_defaults/tasks/main.yml b/roles/global_defaults/tasks/main.yml index ad4c09a..3cff635 100644 --- a/roles/global_defaults/tasks/main.yml +++ b/roles/global_defaults/tasks/main.yml @@ -1,4 +1,8 @@ --- +# Centralized normalization — all input dicts (system, hypervisor, disks) +# are normalized here into system_cfg, hypervisor_cfg, etc. +# Downstream roles consume these computed facts directly and do NOT need +# per-role _normalize.yml (except CIS, which has its own input dict). - name: Global defaults loaded ansible.builtin.debug: msg: Global defaults loaded. diff --git a/roles/global_defaults/tasks/system.yml b/roles/global_defaults/tasks/system.yml index 1aaaf4d..2eb5855 100644 --- a/roles/global_defaults/tasks/system.yml +++ b/roles/global_defaults/tasks/system.yml @@ -1,4 +1,10 @@ --- +# Two code paths: +# 1. Fresh run (system_cfg undefined): normalize from raw `system` input. +# 2. Pre-computed (system_cfg already set, e.g. from main project's deploy_iac): +# merge with bootstrap system_defaults to fill missing fields (luks, features, +# etc.) that bootstrap expects but the main project doesn't set, then derive +# convenience facts (hostname, os, os_version). - name: Normalize system and disk configuration when: system_cfg is not defined block: diff --git a/roles/virtualization/defaults/main.yml b/roles/virtualization/defaults/main.yml index fbd549a..f7c2919 100644 --- a/roles/virtualization/defaults/main.yml +++ b/roles/virtualization/defaults/main.yml @@ -1,4 +1,9 @@ --- +# Cloud-init support matrix: +# libvirt — cloud-init ISO attached as CDROM (user-data + network-config) +# proxmox — cloud-init via Proxmox API (cicustom, ciuser, cipassword, etc.) +# vmware — no cloud-init; configuration is applied post-install via chroot +# xen — no cloud-init; configuration is applied post-install via chroot virtualization_libvirt_image_dir: >- {{ system_cfg.path