Compare commits
25 Commits
8056890460
...
74ae98db35
| Author | SHA1 | Date | |
|---|---|---|---|
| 74ae98db35 | |||
| fc23f84cc3 | |||
| 3c7d9e16da | |||
| e4b9f1c579 | |||
| 920969d60e | |||
| 9d723630cb | |||
| 0c8242589c | |||
| 2885ba9ffa | |||
| 81d63029a4 | |||
| 2fa0fba4c4 | |||
| 055b6de68b | |||
| 4e85740e0a | |||
| 0ee2806c62 | |||
| 1027afc6ea | |||
| 74cb09ffee | |||
| 9f5096d69d | |||
| 6da46a03ed | |||
| e7c898d653 | |||
| 0388dca0a4 | |||
| 1d545fbbc8 | |||
| 53bb4589b6 | |||
| 73f0b81b5a | |||
| 2d46df8f5a | |||
| 45d3fef4e2 | |||
| a6b051d9e4 |
553
README.md
553
README.md
@@ -1,223 +1,372 @@
|
|||||||
# Ansible-Bootstrap
|
# Ansible Bootstrap Playbook
|
||||||
|
|
||||||
An Ansible playbook for automating system bootstrap processes in an Infrastructure-as-Code manner.
|
Automate Linux system bootstrap across multiple distributions and hypervisors in an Infrastructure-as-Code workflow.
|
||||||
|
|
||||||
# Info
|
## Supported Distributions
|
||||||
|
|
||||||
Most of the roles are adaptable for use with systems beyond ArchLinux, requiring only that the target system can install a necessary package manager, such as `dnf` for RHEL-based systems. Additionally, a replacement for the `arch-chroot` command may be required for these systems.
|
| Distribution | Versions |
|
||||||
|
|---|---|
|
||||||
|
| AlmaLinux | 8.x, 9.x, 10.x |
|
||||||
|
| Alpine Linux | latest |
|
||||||
|
| Arch Linux | latest |
|
||||||
|
| Debian | 10, 11, 12, 13, unstable |
|
||||||
|
| Fedora | 40, 41, 42, 43 |
|
||||||
|
| openSUSE Tumbleweed | latest |
|
||||||
|
| RHEL | 8.x, 9.x, 10.x |
|
||||||
|
| Rocky Linux | 8.x, 9.x, 10.x |
|
||||||
|
| Ubuntu | latest |
|
||||||
|
| Ubuntu LTS | latest |
|
||||||
|
| Void Linux | latest |
|
||||||
|
|
||||||
**NOTE**:
|
## Supported Hypervisors
|
||||||
|
|
||||||
- For RHEL 8, RHEL 9, and RHEL 10, repository access requires the `rhel_iso` variable. This variable specifies a local ISO or proxy repository.
|
| Hypervisor | Value |
|
||||||
- RHEL systems do not support `btrfs`. Use `ext4` or `xfs` as alternatives.
|
|---|---|
|
||||||
- For RHEL 8, `xfs` may cause installation issues; `ext4` is recommended.
|
| libvirt | `libvirt` |
|
||||||
- `custom_iso: true` skips ArchISO validation and pacman setup, your installer ISO must provide the tools required by the selected roles.
|
| Proxmox | `proxmox` |
|
||||||
|
| VMware | `vmware` |
|
||||||
|
| Xen | `xen` |
|
||||||
|
| Bare metal | `none` |
|
||||||
|
|
||||||
# Supported Distributions
|
## Compatibility Notes
|
||||||
|
|
||||||
This playbook supports multiple Linux distributions with specific versions tailored to each.
|
- `rhel_iso` is required for `system.os: rhel`.
|
||||||
Below is a list of supported distributions:
|
- RHEL installs should use `system.filesystem: ext4` or `system.filesystem: xfs` (not `btrfs`).
|
||||||
|
- For RHEL 8 specifically, prefer `ext4` over `xfs` if you hit installer/filesystem edge cases.
|
||||||
|
- `custom_iso: true` skips ArchISO validation and pacman preparation; your installer image must already provide required tooling.
|
||||||
|
- On non-Arch installers, set `system.features.chroot.tool` (`arch-chroot`, `chroot`, or `systemd-nspawn`) explicitly as needed.
|
||||||
|
|
||||||
| `os` | Distribution |
|
## Configuration Model
|
||||||
| ---------- | ---------------------------------- |
|
|
||||||
| archlinux | ArchLinux (Latest rolling release) |
|
|
||||||
| almalinux | AlmaLinux 9.x |
|
|
||||||
| debian11 | Debian 11 (Bullseye) |
|
|
||||||
| debian12 | Debian 12 (Bookworm) |
|
|
||||||
| debian13 | Debian 13 (Trixie) |
|
|
||||||
| fedora | Fedora 43 |
|
|
||||||
| rhel8 | Red Hat Enterprise Linux 8 |
|
|
||||||
| rhel9 | Red Hat Enterprise Linux 9 |
|
|
||||||
| rhel10 | Red Hat Enterprise Linux 10 |
|
|
||||||
| rocky | Rocky Linux 9.x |
|
|
||||||
| ubuntu | Ubuntu 25.04 (Plucky Puffin) |
|
|
||||||
| ubuntu-lts | Ubuntu 24.04 LTS (Noble Numbat) |
|
|
||||||
|
|
||||||
# Documentation
|
The project uses only dict-based variables:
|
||||||
|
|
||||||
## Table of Contents
|
- `system` for host/runtime/install configuration
|
||||||
|
- `hypervisor` for virtualization backend configuration
|
||||||
|
|
||||||
1. [Overview](#1-overview)
|
These dictionaries are normal Ansible variables and belong in host/group vars.
|
||||||
2. [Global Variables](#2-global-variables)
|
You can define them in inventory host entries, `group_vars/*`, or `host_vars/*`.
|
||||||
3. [Inventory Variables](#3-inventory-variables)
|
Dictionary variables are merged across scopes (`group_vars` -> `host_vars`) by project config.
|
||||||
4. [How to Use the Playbook](#4-how-to-use-the-playbook)
|
Set shared values like `system.filesystem` once in group vars, then override only host-specific keys per host.
|
||||||
- 4.1 [Prerequisites](#41-prerequisites)
|
|
||||||
- 4.2 [Running the Playbook](#42-running-the-playbook)
|
|
||||||
- 4.3 [Example Usage](#43-example-usage)
|
|
||||||
|
|
||||||
## 1. Overview
|
### Variable Placement
|
||||||
|
|
||||||
The playbook uses the ArchLinux ISO as a foundational tool to provides an efficient and systematic method for the automatic deployment of a variety of Linux distributions on designated target systems. It ensures a standardized setup across different platforms, equipping each system with the essential configurations and software necessary for its designated role.
|
| Location | Scope | Typical use |
|
||||||
|
|---|---|---|
|
||||||
|
| `group_vars/all.yml` | All hosts | Shared defaults like `hypervisor`, `system.filesystem`, `boot_iso` |
|
||||||
|
| `group_vars/<group>.yml` | Group | Environment or role-specific defaults |
|
||||||
|
| `host_vars/<host>.yml` | Single host | Host-specific overrides |
|
||||||
|
| Inventory host vars | Single host | Inline definitions for quick setup |
|
||||||
|
|
||||||
## 2. Global Variables
|
### Example Host Definition
|
||||||
|
|
||||||
Global variables apply across your Ansible project and can be supplied via inventory or `-e @vars_example.yml`. These variables define common settings such as hypervisor connection details and the boot ISO path. They can be overridden by inventory variables for specific hosts or VMs if needed.
|
```yaml
|
||||||
|
all:
|
||||||
|
vars:
|
||||||
|
system:
|
||||||
|
filesystem: btrfs
|
||||||
|
boot_iso: "local:iso/archlinux-x86_64.iso"
|
||||||
|
hypervisor:
|
||||||
|
type: proxmox
|
||||||
|
url: pve01.example.com
|
||||||
|
username: root@pam
|
||||||
|
password: CHANGE_ME
|
||||||
|
host: pve01
|
||||||
|
storage: local-lvm
|
||||||
|
|
||||||
### 2.1 Core Provisioning
|
children:
|
||||||
|
bootstrap:
|
||||||
| Variable | Description | Example Value |
|
hosts:
|
||||||
| ----------------------- | ---------------------------------------------------------- | ----------------------------------------- |
|
app01.example.com:
|
||||||
| `install_type` | Type of installation. | `virtual`, `physical` |
|
ansible_host: 10.0.0.10
|
||||||
| `hypervisor` | Type of hypervisor (required for virtual installs). | `libvirt`, `proxmox`, `vmware`, `none` |
|
system:
|
||||||
| `install_drive` | Drive where the system will be installed. | `/dev/sda` |
|
type: virtual
|
||||||
| `boot_iso` | Path to the boot ISO image. | `local-btrfs:iso/archlinux-x86_64.iso` |
|
os: debian
|
||||||
| `rhel_iso` | Path to the RHEL ISO file, required for RHEL 8/9/10. | `local-btrfs:iso/rhel-9.4-x86_64-dvd.iso` |
|
version: "12"
|
||||||
| `custom_iso` (optional) | Skip ArchISO checks and pacman setup on installer media. | `true`, `false (default)` |
|
name: app01.example.com
|
||||||
| `cis` (optional) | Adjusts the installation to be CIS level 3 conformant. | `true`, `false (default)` |
|
id: 101
|
||||||
| `selinux` (optional) | Toggle SELinux where supported. | `true (default)`, `false` |
|
cpus: 2
|
||||||
| `firewalld_enabled` (optional) | Toggle firewalld package/service enablement. | `true (default)`, `false` |
|
memory: 4096
|
||||||
| `ssh_enabled` (optional) | Toggle SSH server package/service enablement. | `true (default)`, `false` |
|
balloon: 0
|
||||||
|
network: vmbr0
|
||||||
### 2.2 Hypervisor Access (virtual installs)
|
ip: 10.0.0.10
|
||||||
|
prefix: 24
|
||||||
| Variable | Description | Example Value |
|
gateway: 10.0.0.1
|
||||||
| ----------------------- | ---------------------------------------------------------- | -------------------- |
|
dns:
|
||||||
| `hypervisor_url` | URL/IP address for the hypervisor interface. | `192.168.0.2` |
|
servers: [1.1.1.1, 1.0.0.1]
|
||||||
| `hypervisor_username` | Username for hypervisor authentication. | `root@pam` |
|
search: [example.com]
|
||||||
| `hypervisor_password` | Password for hypervisor authentication. | `123456` |
|
disks:
|
||||||
| `hypervisor_datacenter` | Name of the hypervisor datacenter. | `default-datacenter` |
|
- size: 40
|
||||||
| `hypervisor_cluster` | Name of the hypervisor cluster. | `default-cluster` |
|
- size: 120
|
||||||
| `hypervisor_node` | Hypervisor node name. | `node01` |
|
mount:
|
||||||
| `hypervisor_storage` | Storage identifier for VM disks. | `local-btrfs` |
|
path: /data
|
||||||
| `vm_path` (optional) | Libvirt image dir or VMware folder path. | `/var/lib/libvirt/images` |
|
fstype: xfs
|
||||||
| `vmware_ssh` | If Ansible should use SSH after base VMware setup. | `true`, `false (default)` |
|
user:
|
||||||
| `vlan_name` (optional) | VLAN for the VM's network interface. | `vlan100` |
|
name: ops
|
||||||
| `note` (optional) | VMware VM annotation. | `Provisioned by Ansible` |
|
password: CHANGE_ME
|
||||||
|
key: "ssh-ed25519 AAAA..."
|
||||||
### 2.3 VMware Tools connection (VMware installs)
|
root:
|
||||||
|
password: CHANGE_ME
|
||||||
These are required when `hypervisor: vmware` uses the `vmware_tools` connection.
|
luks:
|
||||||
|
enabled: true
|
||||||
| Variable | Description | Example Value |
|
passphrase: CHANGE_ME
|
||||||
| ------------------------------- | ------------------------------------------ | -------------------------------------- |
|
auto: true
|
||||||
| `ansible_vmware_tools_user` | Guest OS user for guest operations. | `root` |
|
method: tpm2
|
||||||
| `ansible_vmware_tools_password` | Guest OS password for guest operations. | `""` |
|
tpm2:
|
||||||
| `ansible_vmware_guest_path` | VM inventory path (datacenter + folder). | `/dc01/vm/Folder/vm01.example.com` |
|
pcrs: "7"
|
||||||
| `ansible_vmware_host` | vCenter/ESXi hostname. | `vcenter01.example.com` |
|
features:
|
||||||
| `ansible_vmware_user` | vCenter/ESXi username. | `administrator@vsphere.local` |
|
firewall:
|
||||||
| `ansible_vmware_password` | vCenter/ESXi password. | `********` |
|
enabled: true
|
||||||
| `ansible_vmware_validate_certs` | Validate vCenter/ESXi TLS certs. | `false` |
|
backend: firewalld
|
||||||
|
toolkit: nftables
|
||||||
### 2.4 Disk Encryption (optional)
|
|
||||||
|
|
||||||
| Variable | Description | Example Value |
|
|
||||||
| -------------------------- | ----------------------------------------------- | ------------------ |
|
|
||||||
| `luks_enabled` | Enable LUKS encryption for the root volume. | `true`, `false` |
|
|
||||||
| `luks_passphrase` | Passphrase used for initial LUKS format/unlock. | `1234` |
|
|
||||||
| `luks_mapper_name` | Decrypted mapper name. | `SYSTEM_DECRYPTED` |
|
|
||||||
| `luks_auto_decrypt` | Enable automatic unlock on boot. | `true`, `false` |
|
|
||||||
| `luks_auto_decrypt_method` | Auto-unlock method. | `tpm2`, `keyfile`, `manual` |
|
|
||||||
| `luks_tpm2_device` | TPM2 device for enrollment. | `auto` |
|
|
||||||
| `luks_tpm2_pcrs` | TPM2 PCR list (systemd-cryptenroll). | `7` |
|
|
||||||
| `luks_keyfile_size` | Keyfile size in bytes for initramfs. | `64` |
|
|
||||||
| `luks_options` | LUKS options passed to crypttab/kernel. | `discard,tries=3` |
|
|
||||||
| `luks_type` | LUKS format type. | `luks2` |
|
|
||||||
| `luks_cipher` | LUKS cipher. | `aes-xts-plain64` |
|
|
||||||
| `luks_hash` | LUKS hash. | `sha512` |
|
|
||||||
| `luks_iter_time` | LUKS iter time in milliseconds. | `4000` |
|
|
||||||
| `luks_key_size` | LUKS key size in bits. | `512` |
|
|
||||||
| `luks_pbkdf` | LUKS PBKDF algorithm. | `argon2id` |
|
|
||||||
| `luks_use_urandom` | Reserved; module uses cryptsetup defaults. | `true` |
|
|
||||||
| `luks_verify_passphrase` | Reserved; module uses cryptsetup defaults. | `true` |
|
|
||||||
|
|
||||||
### 2.5 Partitioning Overrides (advanced)
|
|
||||||
|
|
||||||
Use these only when you need to override the default layout logic.
|
|
||||||
|
|
||||||
| Variable | Description | Example Value |
|
|
||||||
| ---------------------------- | -------------------------------------------------------- | ------------- |
|
|
||||||
| `partitioning_efi_size_mib` | ESP size in MiB. | `512` |
|
|
||||||
| `partitioning_boot_size_mib` | `/boot` size in MiB when a separate boot is used. | `1024` |
|
|
||||||
| `partitioning_separate_boot` | Force a separate `/boot` partition. | `true` |
|
|
||||||
| `partitioning_boot_fs_fstype` | Filesystem for `/boot` when separate. | `ext4` |
|
|
||||||
| `partitioning_use_full_disk` | Use remaining LVM space for the root volume. | `true` |
|
|
||||||
|
|
||||||
To protect sensitive information, such as passwords, API keys, and other confidential variables (e.g., `hypervisor_password`), **it is recommended to use Ansible Vault**.
|
|
||||||
|
|
||||||
## 3. Inventory Variables
|
|
||||||
|
|
||||||
Inventory variables are defined for individual hosts or VMs in the inventory file, allowing customization of settings such as the operating system, filesystem, and compliance with CIS benchmarks. These variables can be set globally and overridden for specific hosts or VMs.
|
|
||||||
|
|
||||||
### 3.1 System Identity and OS
|
|
||||||
|
|
||||||
| Variable | Description | Example Value |
|
|
||||||
| ------------ | -------------------------------------- | ---------------------- |
|
|
||||||
| `ansible_host` | Ansible connection address for the host. | `192.168.0.10` |
|
|
||||||
| `os` | Operating system to be installed. | `ubuntu-lts` |
|
|
||||||
| `filesystem` | Filesystem type for the root volume. | `btrfs`, `ext4`, `xfs` |
|
|
||||||
| `hostname` | The hostname assigned to the system. | `vm01` |
|
|
||||||
|
|
||||||
### 3.2 Credentials and Access
|
|
||||||
|
|
||||||
These are prompted by default via `vars_prompt` in `main.yml`, but can be supplied via inventory/vars/`-e` for non-interactive runs.
|
|
||||||
|
|
||||||
| Variable | Description | Example Value |
|
|
||||||
| ----------------- | ---------------------------------- | ----------------- |
|
|
||||||
| `root_password` | Root password (vault recommended). | `SecurePass123` |
|
|
||||||
| `user_name` | Username for a user account. | `adminuser` |
|
|
||||||
| `user_password` | Password for the user account. | `UserPass123` |
|
|
||||||
| `user_public_key` | SSH Key for the user account. | `ssh-ed25519 AAAA` |
|
|
||||||
|
|
||||||
### 3.3 Networking
|
|
||||||
|
|
||||||
| Variable | Description | Example Value |
|
|
||||||
| --------------- | -------------------------------------------------------------- | ----------------- |
|
|
||||||
| `vm_ip` | IP address assigned to the system (omit to use DHCP). | `192.168.0.10` |
|
|
||||||
| `vm_nms` | Netmask bits for static addressing. | `24` |
|
|
||||||
| `vm_gw` | Default gateway IP address (static only). | `192.168.0.1` |
|
|
||||||
| `vm_dns` | DNS server IP address(es). | `1.0.0.1,1.1.1.1` |
|
|
||||||
| `vm_dns_search` | DNS search zone(s) for the network configuration. | `example.com` |
|
|
||||||
| `vm_nif` | Network interface/bridge for the VM's network connection. | `vmbr0` |
|
|
||||||
|
|
||||||
### 3.4 VM Sizing (virtual installs)
|
|
||||||
|
|
||||||
| Variable | Description | Example Value |
|
|
||||||
| ----------- | --------------------------------- | ------------- |
|
|
||||||
| `vm_id` | Unique identifier for the VM. | `101` |
|
|
||||||
| `vm_size` | Disk size allocated in GB (min 20). | `20` |
|
|
||||||
| `vm_memory` | Amount of memory in MB. | `2048` |
|
|
||||||
| `vm_cpus` | Number of CPU cores (virtual installs). | `4` |
|
|
||||||
| `vm_ballo` | Ballooning memory size (optional).| `2048` |
|
|
||||||
|
|
||||||
### 3.5 Post-install Packages
|
|
||||||
|
|
||||||
| Variable | Description | Example Value |
|
|
||||||
| ------------------------ | --------------------------------------------------------------------- | ------------------ |
|
|
||||||
| `extra_packages` (optional) | Additional packages installed after the first boot into the installed OS. | `["git", "jq"]` |
|
|
||||||
|
|
||||||
## 4. How to Use the Playbook
|
|
||||||
|
|
||||||
### 4.1 Prerequisites
|
|
||||||
|
|
||||||
Before running the playbook, ensure you have Ansible installed and configured correctly, and your inventory file is set up with the target systems defined.
|
|
||||||
|
|
||||||
### 4.2 Running the Playbook
|
|
||||||
|
|
||||||
Execute the playbook using the `ansible-playbook` command, ensuring that all necessary variables are defined, typically by specifying a vars file (such as `vars_example.yml`) containing the required configurations.
|
|
||||||
|
|
||||||
### 4.3 Example Usage
|
|
||||||
|
|
||||||
An effective way to use the playbook involves defining all necessary configurations within a vars file (for example, `vars_example.yml`). This file should include all relevant global variables tailored to your specific deployment requirements. Additionally, you should prepare an inventory file (`inventory.yml`) that lists all the hosts along with any specific inventory variables they might need. Then, you can run the playbook as follows:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
ansible-playbook -i inventory.yml -e @vars_example.yml main.yml
|
|
||||||
```
|
```
|
||||||
|
|
||||||
This command prompts Ansible to execute the `main.yml` playbook, applying configurations defined in both the vars file and the inventory file.
|
## Core Variables
|
||||||
|
|
||||||
Use `inventory_example.yml`, `inventory_libvirt_example.yml`, `vars_example.yml`, and the bare-metal examples as starting points for new inventories.
|
| Variable | Type | Description |
|
||||||
|
|---|---|---|
|
||||||
|
| `boot_iso` | string | Required when `system.type=virtual` |
|
||||||
|
| `rhel_iso` | string | Required when `system.os=rhel` |
|
||||||
|
| `custom_iso` | bool | Skip Arch ISO-specific preparation checks |
|
||||||
|
|
||||||
## Notes
|
## `system` Dictionary
|
||||||
|
|
||||||
- `vm_size`/`vm_memory`/`vm_cpus` are required for virtual installs only, physical installs use the full disk.
|
Top-level host install/runtime settings.
|
||||||
- `vm_dns` and `vm_dns_search` accept comma-separated strings or YAML lists.
|
Use these keys under `system`.
|
||||||
- `hypervisor` determines which backend-specific roles run.
|
|
||||||
- Guest tools are installed based on `hypervisor`: `qemu-guest-agent` for `libvirt`/`proxmox`, `open-vm-tools` for `vmware`, otherwise none.
|
| Key | Type | Default | Description |
|
||||||
- Molecule is scaffolded with a delegated driver and a no-op converge for lint-only validation.
|
|---|---|---|---|
|
||||||
- With LUKS enabled on Debian/Ubuntu and RHEL-based systems, provisioning uses an ESP (512 MiB), a separate `/boot`
|
| `type` | string | `virtual` | `virtual` or `physical` |
|
||||||
(1 GiB, same as `filesystem` unless `btrfs` uses ext4 on Debian/Ubuntu or xfs on RHEL-based), and the encrypted root;
|
| `os` | string | empty (`archlinux` if omitted on physical) | Target distribution |
|
||||||
adjust sizes via
|
| `version` | string | empty | Version selector for distro families |
|
||||||
`partitioning_efi_size_mib` and `partitioning_boot_size_mib` if needed.
|
| `filesystem` | string | empty | `btrfs`, `ext4`, or `xfs` |
|
||||||
- With `luks_auto_decrypt_method: tpm2` on virtual installs, the virtualization role enables a TPM2 device (libvirt/proxmox/vmware).
|
| `name` | string | inventory hostname | Final hostname |
|
||||||
- For VMware, `vmware_ssh: true` enables SSH on the guest and switches the connection to SSH for the remaining tasks.
|
| `id` | int/string | empty | VMID for Proxmox |
|
||||||
- For physical installs, set `ansible_user`/`ansible_password` for the installer environment when it differs from the prompted user credentials.
|
| `cpus` | int | `0` | vCPU count |
|
||||||
|
| `memory` | int | `0` | Memory in MiB |
|
||||||
|
| `balloon` | int | `0` | Balloon memory in MiB |
|
||||||
|
| `network` | string | empty | Hypervisor network/bridge |
|
||||||
|
| `vlan` | string/int | empty | VLAN tag |
|
||||||
|
| `ip` | string | empty | Static IP (optional) |
|
||||||
|
| `prefix` | int | empty | Prefix for static IP |
|
||||||
|
| `gateway` | string | empty | Static gateway |
|
||||||
|
| `path` | string | empty | Hypervisor folder/path (libvirt/vmware) |
|
||||||
|
| `packages` | list/string | empty | Post-reboot packages |
|
||||||
|
| `dns` | dict | `{servers: [], search: []}` | DNS nested dictionary |
|
||||||
|
| `disks` | list | `[]` | Disk layout list |
|
||||||
|
| `user` | dict | `{name:'', password:'', key:''}` | User account dictionary |
|
||||||
|
| `root` | dict | `{password:''}` | Root account dictionary |
|
||||||
|
| `luks` | dict | see below | Encryption dictionary |
|
||||||
|
| `features` | dict | see below | Feature flags dictionary |
|
||||||
|
|
||||||
|
### `system.dns`
|
||||||
|
|
||||||
|
DNS options used by network configuration tasks.
|
||||||
|
Use these keys under `system.dns`.
|
||||||
|
|
||||||
|
| Key | Type | Default | Description |
|
||||||
|
|---|---|---|---|
|
||||||
|
| `servers` | list/string | `[]` | DNS resolvers; comma-separated string is normalized |
|
||||||
|
| `search` | list/string | `[]` | Search domains; comma-separated string is normalized |
|
||||||
|
|
||||||
|
### `system.user`
|
||||||
|
|
||||||
|
Target user account settings.
|
||||||
|
Use these keys under `system.user`.
|
||||||
|
|
||||||
|
| Key | Type | Default | Description |
|
||||||
|
|---|---|---|---|
|
||||||
|
| `name` | string | empty | Username created on target |
|
||||||
|
| `password` | string | empty | User password (also used for sudo/become) |
|
||||||
|
| `key` | string | empty | SSH public key for `authorized_keys` |
|
||||||
|
|
||||||
|
### `system.root`
|
||||||
|
|
||||||
|
Use these keys under `system.root`.
|
||||||
|
|
||||||
|
| Key | Type | Default | Description |
|
||||||
|
|---|---|---|---|
|
||||||
|
| `password` | string | empty | Root password |
|
||||||
|
|
||||||
|
### `system.luks`
|
||||||
|
|
||||||
|
LUKS container, unlock, and initramfs-related settings.
|
||||||
|
Use these keys under `system.luks`.
|
||||||
|
|
||||||
|
| Key | Type | Default | Allowed | Description |
|
||||||
|
|---|---|---|---|---|
|
||||||
|
| `enabled` | bool | `false` | `true`/`false` | Enable encrypted root workflow |
|
||||||
|
| `passphrase` | string | empty | any string | Passphrase used for format/open/enroll |
|
||||||
|
| `mapper` | string | `SYSTEM_DECRYPTED` | mapper name | Mapper name under `/dev/mapper` |
|
||||||
|
| `auto` | bool | `true` | `true`/`false` | Auto-unlock behavior toggle |
|
||||||
|
| `method` | string | `tpm2` | `tpm2`,`keyfile` | Auto-unlock backend when `auto=true` |
|
||||||
|
| `keysize` | int | `64` | positive int | Keyfile size (bytes) for keyfile mode |
|
||||||
|
| `options` | string | `discard,tries=3` | crypttab opts | Additional crypttab/kernel options |
|
||||||
|
| `type` | string | `luks2` | cryptsetup type | LUKS format type |
|
||||||
|
| `cipher` | string | `aes-xts-plain64` | cipher name | Cryptsetup cipher |
|
||||||
|
| `hash` | string | `sha512` | hash name | Cryptsetup hash |
|
||||||
|
| `iter` | int | `4000` | positive int | PBKDF iteration time (ms) |
|
||||||
|
| `bits` | int | `512` | positive int | Key size (bits) |
|
||||||
|
| `pbkdf` | string | `argon2id` | pbkdf name | PBKDF algorithm |
|
||||||
|
| `urandom` | bool | `true` | `true`/`false` | Use urandom during key generation |
|
||||||
|
| `verify` | bool | `true` | `true`/`false` | Verify passphrase during format |
|
||||||
|
|
||||||
|
### `system.luks.tpm2`
|
||||||
|
|
||||||
|
TPM2-specific policy settings used when `system.luks.method=tpm2`.
|
||||||
|
Use these keys under `system.luks.tpm2`.
|
||||||
|
|
||||||
|
| Key | Type | Default | Allowed | Description |
|
||||||
|
|---|---|---|---|---|
|
||||||
|
| `device` | string | `auto` | `auto` or device path | TPM2 device selector |
|
||||||
|
| `pcrs` | string/list | empty | PCR expression | PCR binding policy (for example `"7"` or `"0+7"`) |
|
||||||
|
|
||||||
|
### `system.features`
|
||||||
|
|
||||||
|
Feature toggles for optional system configuration.
|
||||||
|
Use these keys under `system.features`.
|
||||||
|
|
||||||
|
| Key | Type | Default | Allowed | Description |
|
||||||
|
|---|---|---|---|---|
|
||||||
|
| `cis.enabled` | bool | `false` | `true`/`false` | Enable CIS hardening role |
|
||||||
|
| `selinux.enabled` | bool | `true` | `true`/`false` | SELinux management |
|
||||||
|
| `firewall.enabled` | bool | `true` | `true`/`false` | Enable firewall role actions |
|
||||||
|
| `firewall.backend` | string | `firewalld` | `firewalld`,`ufw` | Firewall service backend |
|
||||||
|
| `firewall.toolkit` | string | `nftables` | `nftables`,`iptables` | Packet filtering toolkit selection |
|
||||||
|
| `ssh.enabled` | bool | `true` | `true`/`false` | SSH service/package management |
|
||||||
|
| `zstd.enabled` | bool | `true` | `true`/`false` | zstd related tuning |
|
||||||
|
| `swap.enabled` | bool | `true` | `true`/`false` | Swap setup toggle |
|
||||||
|
| `banner.motd` | bool | `true` | `true`/`false` | MOTD banner management |
|
||||||
|
| `banner.sudo` | bool | `true` | `true`/`false` | Sudo banner management |
|
||||||
|
| `chroot.tool` | string | `arch-chroot` | `arch-chroot`,`chroot`,`systemd-nspawn` | Chroot wrapper command |
|
||||||
|
|
||||||
|
## Multi-Disk Schema
|
||||||
|
|
||||||
|
`system.disks[0]` is always the OS disk. Additional entries can define data disks.
|
||||||
|
|
||||||
|
| Key | Type | Description |
|
||||||
|
|---|---|---|
|
||||||
|
| `size` | number | Disk size in GB (required for virtual) |
|
||||||
|
| `device` | string | Explicit disk device (required for physical data disks) |
|
||||||
|
| `mount.path` | string | Mount target (for additional disks) |
|
||||||
|
| `mount.fstype` | string | `btrfs`, `ext4`, or `xfs` |
|
||||||
|
| `mount.label` | string | Optional filesystem label |
|
||||||
|
| `mount.opts` | string | Mount options (`defaults` by default) |
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
system:
|
||||||
|
disks:
|
||||||
|
- size: 80
|
||||||
|
- size: 200
|
||||||
|
mount:
|
||||||
|
path: /data
|
||||||
|
fstype: xfs
|
||||||
|
label: DATA
|
||||||
|
opts: defaults,noatime
|
||||||
|
- size: 300
|
||||||
|
mount:
|
||||||
|
path: /backup
|
||||||
|
fstype: ext4
|
||||||
|
```
|
||||||
|
|
||||||
|
For physical installs, include device paths:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
system:
|
||||||
|
type: physical
|
||||||
|
disks:
|
||||||
|
- device: /dev/sda
|
||||||
|
size: 120
|
||||||
|
- device: /dev/sdb
|
||||||
|
size: 500
|
||||||
|
mount:
|
||||||
|
path: /data
|
||||||
|
fstype: ext4
|
||||||
|
```
|
||||||
|
|
||||||
|
## Advanced Partitioning Overrides
|
||||||
|
|
||||||
|
Use these only when you need to override default layout behavior.
|
||||||
|
|
||||||
|
| Variable | Description | Default |
|
||||||
|
|---|---|---|
|
||||||
|
| `partitioning_efi_size_mib` | EFI system partition size in MiB | `512` |
|
||||||
|
| `partitioning_boot_size_mib` | Separate `/boot` size in MiB (when used) | `1024` |
|
||||||
|
| `partitioning_separate_boot` | Force separate `/boot` partition logic | auto-derived |
|
||||||
|
| `partitioning_boot_fs_fstype` | Filesystem for `/boot` when separate | auto-derived |
|
||||||
|
| `partitioning_use_full_disk` | Consume remaining VG space for root LV | `true` |
|
||||||
|
|
||||||
|
## `hypervisor` Dictionary
|
||||||
|
|
||||||
|
Use these keys under `hypervisor`.
|
||||||
|
|
||||||
|
| Key | Type | Description |
|
||||||
|
|---|---|---|
|
||||||
|
| `type` | string | `libvirt`, `proxmox`, `vmware`, `xen`, `none` |
|
||||||
|
| `url` | string | Proxmox/VMware API host |
|
||||||
|
| `username` | string | API username |
|
||||||
|
| `password` | string | API password |
|
||||||
|
| `host` | string | Proxmox node name |
|
||||||
|
| `storage` | string | Proxmox/VMware storage |
|
||||||
|
| `datacenter` | string | VMware datacenter |
|
||||||
|
| `cluster` | string | VMware cluster |
|
||||||
|
| `certs` | bool | TLS cert validation for VMware |
|
||||||
|
| `ssh` | bool | VMware installer SSH bootstrap helper |
|
||||||
|
|
||||||
|
## VMware Guest Operations Variables
|
||||||
|
|
||||||
|
When `hypervisor.type: vmware` and connection uses `vmware_tools`, ensure these variables are set in inventory/group/host vars as needed by your vCenter/ESXi environment.
|
||||||
|
|
||||||
|
| Variable | Description |
|
||||||
|
|---|---|
|
||||||
|
| `ansible_vmware_tools_user` | Guest OS username for guest operations |
|
||||||
|
| `ansible_vmware_tools_password` | Guest OS password for guest operations |
|
||||||
|
| `ansible_vmware_guest_path` | VM inventory path (`/datacenter/vm/folder/name`) |
|
||||||
|
| `ansible_vmware_host` | vCenter/ESXi host |
|
||||||
|
| `ansible_vmware_user` | vCenter/ESXi API username |
|
||||||
|
| `ansible_vmware_password` | vCenter/ESXi API password |
|
||||||
|
| `ansible_vmware_validate_certs` | Enable/disable TLS certificate validation |
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
- Ansible installed on the control machine.
|
||||||
|
- Inventory and variables prepared for your target hosts.
|
||||||
|
- Disposable/non-production targets (the playbook enforces production-safety checks).
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ansible-playbook -i inventory_example.yml main.yml
|
||||||
|
ansible-playbook -i inventory_libvirt_example.yml main.yml
|
||||||
|
ansible-playbook -i inventory.yml main.yml -e @vars_example.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
## Security
|
||||||
|
|
||||||
|
Store sensitive data (passwords, API tokens, private keys) with Ansible Vault instead of plaintext inventory files.
|
||||||
|
|
||||||
|
## Operational Notes
|
||||||
|
|
||||||
|
- For virtual installs, `system.cpus`, `system.memory`, and `system.disks[0].size` are required and validated.
|
||||||
|
- For physical installs, sizing is derived from the detected install drive; set installer access (`ansible_user`/`ansible_password`) when needed.
|
||||||
|
- `system.dns.servers` and `system.dns.search` accept either YAML lists or comma-separated strings.
|
||||||
|
- `hypervisor.type` selects backend-specific provisioning/cleanup behavior.
|
||||||
|
- Guest tools are selected automatically by hypervisor: `qemu-guest-agent` (`libvirt`/`proxmox`) and `open-vm-tools` (`vmware`).
|
||||||
|
- With `system.luks.method: tpm2` on virtual installs, the virtualization role enables a TPM2 device where supported.
|
||||||
|
- With LUKS on non-Arch targets, provisioning may use a separate `/boot`; tune with `partitioning_efi_size_mib` and `partitioning_boot_size_mib`.
|
||||||
|
- For VMware, `hypervisor.ssh: true` enables SSH on the guest and switches the connection to SSH for remaining tasks.
|
||||||
|
- Molecule scenario is lint-focused (`delegated` driver with non-destructive placeholder converge).
|
||||||
|
|
||||||
|
## Safety
|
||||||
|
|
||||||
|
This playbook intentionally aborts if it detects a non-live/production target.
|
||||||
|
It also refuses to touch pre-existing VMs and only cleans up VMs created in the current run.
|
||||||
|
|
||||||
|
## Validation
|
||||||
|
|
||||||
|
Always run lint after changes:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ansible-lint
|
||||||
|
```
|
||||||
|
|||||||
2
ansible.cfg
Normal file
2
ansible.cfg
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
[defaults]
|
||||||
|
hash_behaviour = merge
|
||||||
@@ -1,9 +1,20 @@
|
|||||||
---
|
---
|
||||||
all:
|
all:
|
||||||
|
vars:
|
||||||
|
hypervisor:
|
||||||
|
type: "none"
|
||||||
|
system:
|
||||||
|
filesystem: "ext4"
|
||||||
hosts:
|
hosts:
|
||||||
baremetal01.example.com:
|
baremetal01.example.com:
|
||||||
ansible_host: 10.0.0.162
|
ansible_host: 10.0.0.162
|
||||||
ansible_user: root
|
ansible_user: root
|
||||||
ansible_password: "1234"
|
ansible_password: "1234"
|
||||||
ansible_become_password: "1234"
|
ansible_become_password: "1234"
|
||||||
hostname: "baremetal01.example.com"
|
system:
|
||||||
|
type: "physical"
|
||||||
|
os: "archlinux"
|
||||||
|
name: "baremetal01.example.com"
|
||||||
|
disks:
|
||||||
|
- device: "/dev/sda"
|
||||||
|
size: 120
|
||||||
|
|||||||
@@ -1,50 +1,127 @@
|
|||||||
---
|
---
|
||||||
all:
|
all:
|
||||||
vars:
|
vars:
|
||||||
install_type: "virtual"
|
hypervisor:
|
||||||
hypervisor: "proxmox"
|
type: "proxmox"
|
||||||
install_drive: "/dev/sda"
|
url: "pve01.example.com"
|
||||||
|
username: "root@pam"
|
||||||
|
password: "CHANGE_ME"
|
||||||
|
host: "pve01"
|
||||||
|
storage: "local-lvm"
|
||||||
boot_iso: "local:iso/archlinux-x86_64.iso"
|
boot_iso: "local:iso/archlinux-x86_64.iso"
|
||||||
vm_nif: "vmbr0"
|
|
||||||
children:
|
children:
|
||||||
proxmox:
|
proxmox:
|
||||||
hosts:
|
hosts:
|
||||||
app01.example.com:
|
app01.example.com:
|
||||||
ansible_host: 10.0.0.10
|
ansible_host: 10.0.0.10
|
||||||
hostname: "app01.example.com"
|
system:
|
||||||
os: "archlinux"
|
|
||||||
filesystem: "btrfs"
|
filesystem: "btrfs"
|
||||||
vm_id: 100
|
type: "virtual"
|
||||||
vm_cpus: 2
|
os: "archlinux"
|
||||||
vm_memory: 4096
|
name: "app01.example.com"
|
||||||
vm_size: 40
|
id: 100
|
||||||
vm_ip: 10.0.0.10
|
cpus: 2
|
||||||
vm_nms: 24
|
memory: 4096
|
||||||
vm_gw: 10.0.0.1
|
balloon: 0
|
||||||
vm_dns:
|
network: "vmbr0"
|
||||||
|
ip: 10.0.0.10
|
||||||
|
prefix: 24
|
||||||
|
gateway: 10.0.0.1
|
||||||
|
dns:
|
||||||
|
servers:
|
||||||
- 1.1.1.1
|
- 1.1.1.1
|
||||||
- 1.0.0.1
|
- 1.0.0.1
|
||||||
extra_packages:
|
search:
|
||||||
|
- example.com
|
||||||
|
disks:
|
||||||
|
- size: 40
|
||||||
|
- size: 80
|
||||||
|
mount:
|
||||||
|
path: /data
|
||||||
|
fstype: xfs
|
||||||
|
label: DATA
|
||||||
|
opts: defaults
|
||||||
|
user:
|
||||||
|
name: "ops"
|
||||||
|
password: "CHANGE_ME"
|
||||||
|
key: "ssh-ed25519 AAAA..."
|
||||||
|
root:
|
||||||
|
password: "CHANGE_ME"
|
||||||
|
packages:
|
||||||
- jq
|
- jq
|
||||||
- tmux
|
- tmux
|
||||||
|
features:
|
||||||
|
cis:
|
||||||
|
enabled: false
|
||||||
|
selinux:
|
||||||
|
enabled: true
|
||||||
|
firewall:
|
||||||
|
enabled: true
|
||||||
|
backend: "firewalld"
|
||||||
|
toolkit: "nftables"
|
||||||
|
ssh:
|
||||||
|
enabled: true
|
||||||
|
zstd:
|
||||||
|
enabled: true
|
||||||
|
swap:
|
||||||
|
enabled: true
|
||||||
|
banner:
|
||||||
|
motd: true
|
||||||
|
sudo: true
|
||||||
|
chroot:
|
||||||
|
tool: "arch-chroot"
|
||||||
db01.example.com:
|
db01.example.com:
|
||||||
ansible_host: 10.0.0.11
|
ansible_host: 10.0.0.11
|
||||||
hostname: "db01.example.com"
|
|
||||||
os: "rhel9"
|
|
||||||
filesystem: "xfs"
|
|
||||||
vm_id: 101
|
|
||||||
vm_cpus: 4
|
|
||||||
vm_memory: 8192
|
|
||||||
vm_size: 80
|
|
||||||
vm_ip: 10.0.0.11
|
|
||||||
vm_nms: 24
|
|
||||||
vm_gw: 10.0.0.1
|
|
||||||
vm_dns: "1.1.1.1,1.0.0.1"
|
|
||||||
rhel_iso: "local:iso/rhel-9.4-x86_64-dvd.iso"
|
rhel_iso: "local:iso/rhel-9.4-x86_64-dvd.iso"
|
||||||
luks_enabled: true
|
system:
|
||||||
luks_passphrase: "CHANGE_ME"
|
filesystem: "xfs"
|
||||||
luks_auto_decrypt_method: "keyfile"
|
type: "virtual"
|
||||||
luks_keyfile_size: 128
|
os: "rhel"
|
||||||
cis: true
|
version: "9"
|
||||||
selinux: false
|
name: "db01.example.com"
|
||||||
firewalld_enabled: false
|
id: 101
|
||||||
|
cpus: 4
|
||||||
|
memory: 8192
|
||||||
|
network: "vmbr0"
|
||||||
|
ip: 10.0.0.11
|
||||||
|
prefix: 24
|
||||||
|
gateway: 10.0.0.1
|
||||||
|
dns:
|
||||||
|
servers: "1.1.1.1,1.0.0.1"
|
||||||
|
disks:
|
||||||
|
- size: 80
|
||||||
|
- size: 200
|
||||||
|
mount:
|
||||||
|
path: /srv/data
|
||||||
|
fstype: ext4
|
||||||
|
user:
|
||||||
|
name: "dbadmin"
|
||||||
|
password: "CHANGE_ME"
|
||||||
|
key: "ssh-ed25519 AAAA..."
|
||||||
|
root:
|
||||||
|
password: "CHANGE_ME"
|
||||||
|
luks:
|
||||||
|
enabled: true
|
||||||
|
passphrase: "CHANGE_ME"
|
||||||
|
method: "keyfile"
|
||||||
|
keysize: 128
|
||||||
|
features:
|
||||||
|
cis:
|
||||||
|
enabled: true
|
||||||
|
selinux:
|
||||||
|
enabled: false
|
||||||
|
firewall:
|
||||||
|
enabled: false
|
||||||
|
backend: "firewalld"
|
||||||
|
toolkit: "nftables"
|
||||||
|
ssh:
|
||||||
|
enabled: true
|
||||||
|
zstd:
|
||||||
|
enabled: true
|
||||||
|
swap:
|
||||||
|
enabled: true
|
||||||
|
banner:
|
||||||
|
motd: true
|
||||||
|
sudo: true
|
||||||
|
chroot:
|
||||||
|
tool: "arch-chroot"
|
||||||
|
|||||||
@@ -1,56 +1,126 @@
|
|||||||
---
|
---
|
||||||
all:
|
all:
|
||||||
vars:
|
vars:
|
||||||
install_type: "virtual"
|
hypervisor:
|
||||||
hypervisor: "libvirt"
|
type: "libvirt"
|
||||||
install_drive: "/dev/vda"
|
url: "localhost"
|
||||||
|
username: ""
|
||||||
|
password: ""
|
||||||
|
host: ""
|
||||||
|
storage: "default"
|
||||||
boot_iso: "/var/lib/libvirt/images/archlinux-x86_64.iso"
|
boot_iso: "/var/lib/libvirt/images/archlinux-x86_64.iso"
|
||||||
children:
|
children:
|
||||||
libvirt:
|
libvirt:
|
||||||
hosts:
|
hosts:
|
||||||
web01.example.com:
|
web01.local:
|
||||||
ansible_host: 192.168.122.10
|
ansible_host: 192.168.122.20
|
||||||
hostname: "web01.example.com"
|
system:
|
||||||
os: "debian12"
|
|
||||||
filesystem: "ext4"
|
filesystem: "ext4"
|
||||||
vm_cpus: 2
|
type: "virtual"
|
||||||
vm_memory: 2048
|
os: "debian"
|
||||||
vm_size: 30
|
version: "12"
|
||||||
vm_ip: 192.168.122.10
|
name: "web01.local"
|
||||||
vm_nms: 24
|
cpus: 2
|
||||||
vm_gw: 192.168.122.1
|
memory: 2048
|
||||||
vm_dns: 1.1.1.1
|
network: "default"
|
||||||
extra_packages:
|
ip: 192.168.122.20
|
||||||
|
prefix: 24
|
||||||
|
gateway: 192.168.122.1
|
||||||
|
dns:
|
||||||
|
servers:
|
||||||
|
- 1.1.1.1
|
||||||
|
search:
|
||||||
|
- lab.local
|
||||||
|
path: "/var/lib/libvirt/images"
|
||||||
|
disks:
|
||||||
|
- size: 30
|
||||||
|
- size: 80
|
||||||
|
mount:
|
||||||
|
path: /var/www
|
||||||
|
fstype: xfs
|
||||||
|
user:
|
||||||
|
name: "web"
|
||||||
|
password: "CHANGE_ME"
|
||||||
|
key: "ssh-ed25519 AAAA..."
|
||||||
|
root:
|
||||||
|
password: "CHANGE_ME"
|
||||||
|
packages:
|
||||||
- nginx
|
- nginx
|
||||||
- fail2ban
|
- curl
|
||||||
vault01.example.com:
|
features:
|
||||||
ansible_host: 192.168.122.11
|
firewall:
|
||||||
hostname: "vault01.example.com"
|
enabled: true
|
||||||
os: "ubuntu-lts"
|
backend: "ufw"
|
||||||
filesystem: "btrfs"
|
toolkit: "nftables"
|
||||||
vm_cpus: 2
|
db01.local:
|
||||||
vm_memory: 4096
|
ansible_host: 192.168.122.21
|
||||||
vm_size: 40
|
|
||||||
vm_ip: 192.168.122.11
|
|
||||||
vm_nms: 24
|
|
||||||
vm_gw: 192.168.122.1
|
|
||||||
vm_dns_search: "example.com"
|
|
||||||
luks_enabled: true
|
|
||||||
luks_passphrase: "CHANGE_ME"
|
|
||||||
luks_auto_decrypt_method: "keyfile"
|
|
||||||
firewalld_enabled: false
|
|
||||||
rhel9.example.com:
|
|
||||||
ansible_host: 192.168.122.12
|
|
||||||
hostname: "rhel9.example.com"
|
|
||||||
os: "rhel9"
|
|
||||||
filesystem: "xfs"
|
|
||||||
vm_cpus: 4
|
|
||||||
vm_memory: 8192
|
|
||||||
vm_size: 80
|
|
||||||
vm_ip: 192.168.122.12
|
|
||||||
vm_nms: 24
|
|
||||||
vm_gw: 192.168.122.1
|
|
||||||
vm_dns: "1.1.1.1,1.0.0.1"
|
|
||||||
vm_path: "/srv/libvirt/images"
|
|
||||||
rhel_iso: "/var/lib/libvirt/images/rhel-9.4-x86_64-dvd.iso"
|
rhel_iso: "/var/lib/libvirt/images/rhel-9.4-x86_64-dvd.iso"
|
||||||
vlan_name: "100"
|
system:
|
||||||
|
filesystem: "xfs"
|
||||||
|
type: "virtual"
|
||||||
|
os: "rhel"
|
||||||
|
version: "9"
|
||||||
|
name: "db01.local"
|
||||||
|
cpus: 4
|
||||||
|
memory: 4096
|
||||||
|
network: "default"
|
||||||
|
ip: 192.168.122.21
|
||||||
|
prefix: 24
|
||||||
|
gateway: 192.168.122.1
|
||||||
|
dns:
|
||||||
|
servers:
|
||||||
|
- 9.9.9.9
|
||||||
|
search:
|
||||||
|
- example.com
|
||||||
|
disks:
|
||||||
|
- size: 60
|
||||||
|
- size: 120
|
||||||
|
mount:
|
||||||
|
path: /data
|
||||||
|
fstype: ext4
|
||||||
|
user:
|
||||||
|
name: "db"
|
||||||
|
password: "CHANGE_ME"
|
||||||
|
key: "ssh-ed25519 AAAA..."
|
||||||
|
root:
|
||||||
|
password: "CHANGE_ME"
|
||||||
|
luks:
|
||||||
|
enabled: true
|
||||||
|
passphrase: "CHANGE_ME"
|
||||||
|
method: "keyfile"
|
||||||
|
features:
|
||||||
|
firewall:
|
||||||
|
enabled: false
|
||||||
|
backend: "firewalld"
|
||||||
|
toolkit: "nftables"
|
||||||
|
compute01.local:
|
||||||
|
ansible_host: 192.168.122.22
|
||||||
|
system:
|
||||||
|
filesystem: "btrfs"
|
||||||
|
type: "virtual"
|
||||||
|
os: "fedora"
|
||||||
|
version: "41"
|
||||||
|
name: "compute01.local"
|
||||||
|
cpus: 8
|
||||||
|
memory: 8192
|
||||||
|
network: "default"
|
||||||
|
ip: 192.168.122.22
|
||||||
|
prefix: 24
|
||||||
|
gateway: 192.168.122.1
|
||||||
|
dns:
|
||||||
|
servers: "1.1.1.1,1.0.0.1"
|
||||||
|
disks:
|
||||||
|
- size: 80
|
||||||
|
- size: 200
|
||||||
|
mount:
|
||||||
|
path: /data
|
||||||
|
fstype: btrfs
|
||||||
|
user:
|
||||||
|
name: "compute"
|
||||||
|
password: "CHANGE_ME"
|
||||||
|
key: "ssh-ed25519 AAAA..."
|
||||||
|
root:
|
||||||
|
password: "CHANGE_ME"
|
||||||
|
features:
|
||||||
|
cis:
|
||||||
|
enabled: true
|
||||||
|
|||||||
80
main.yml
80
main.yml
@@ -25,20 +25,61 @@
|
|||||||
What is your root password?
|
What is your root password?
|
||||||
confirm: true
|
confirm: true
|
||||||
pre_tasks:
|
pre_tasks:
|
||||||
|
- name: Apply prompted authentication values to system input
|
||||||
|
vars:
|
||||||
|
system_input: "{{ system | default({}) }}"
|
||||||
|
system_user_input: "{{ (system_input.user | default({})) if (system_input.user is mapping) else {} }}"
|
||||||
|
system_root_input: "{{ (system_input.root | default({})) if (system_input.root is mapping) else {} }}"
|
||||||
|
prompt_user_name: "{{ user_name | default(system_user_name | default(''), true) | string }}"
|
||||||
|
prompt_user_key: "{{ user_public_key | default(user_key | default(system_user_key | default(''), true), true) | string }}"
|
||||||
|
prompt_user_password: "{{ user_password | default(system_user_password | default(''), true) | string }}"
|
||||||
|
prompt_root_password: "{{ root_password | default(system_root_password | default(''), true) | string }}"
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
system: >-
|
||||||
|
{{
|
||||||
|
system_input
|
||||||
|
| combine(
|
||||||
|
{
|
||||||
|
'user': {
|
||||||
|
'name': (
|
||||||
|
(system_user_input.name | default('') | string | length) > 0
|
||||||
|
) | ternary(system_user_input.name | string, prompt_user_name),
|
||||||
|
'key': (
|
||||||
|
(system_user_input.key | default('') | string | length) > 0
|
||||||
|
) | ternary(system_user_input.key | string, prompt_user_key),
|
||||||
|
'password': (
|
||||||
|
(system_user_input.password | default('') | string | length) > 0
|
||||||
|
) | ternary(system_user_input.password | string, prompt_user_password)
|
||||||
|
},
|
||||||
|
'root': {
|
||||||
|
'password': (
|
||||||
|
(system_root_input.password | default('') | string | length) > 0
|
||||||
|
) | ternary(system_root_input.password | string, prompt_root_password)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
recursive=True
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
- name: Load global defaults
|
- name: Load global defaults
|
||||||
ansible.builtin.import_role:
|
ansible.builtin.import_role:
|
||||||
name: global_defaults
|
name: global_defaults
|
||||||
|
|
||||||
|
- name: Perform safety checks
|
||||||
|
ansible.builtin.import_role:
|
||||||
|
name: system_check
|
||||||
|
|
||||||
roles:
|
roles:
|
||||||
- role: virtualization
|
- role: virtualization
|
||||||
when: install_type == "virtual"
|
when: system_cfg.type == "virtual"
|
||||||
become: false
|
become: false
|
||||||
vars:
|
vars:
|
||||||
ansible_connection: local
|
ansible_connection: local
|
||||||
|
|
||||||
- role: environment
|
- role: environment
|
||||||
vars:
|
vars:
|
||||||
ansible_connection: "{{ 'vmware_tools' if hypervisor == 'vmware' else 'ssh' }}"
|
ansible_connection: "{{ 'vmware_tools' if hypervisor_type == 'vmware' else 'ssh' }}"
|
||||||
|
|
||||||
- role: partitioning
|
- role: partitioning
|
||||||
vars:
|
vars:
|
||||||
@@ -50,10 +91,10 @@
|
|||||||
- role: configuration
|
- role: configuration
|
||||||
|
|
||||||
- role: cis
|
- role: cis
|
||||||
when: cis_enabled
|
when: system_cfg.features.cis.enabled | bool
|
||||||
|
|
||||||
- role: cleanup
|
- role: cleanup
|
||||||
when: install_type in ["virtual", "physical"]
|
when: system_cfg.type in ["virtual", "physical"]
|
||||||
become: false
|
become: false
|
||||||
|
|
||||||
post_tasks:
|
post_tasks:
|
||||||
@@ -62,9 +103,9 @@
|
|||||||
post_reboot_can_connect: >-
|
post_reboot_can_connect: >-
|
||||||
{{
|
{{
|
||||||
(ansible_connection | default('ssh')) != 'ssh'
|
(ansible_connection | default('ssh')) != 'ssh'
|
||||||
or (vm_ip is defined and (vm_ip | string | length) > 0)
|
or ((system_cfg.ip | default('') | string | length) > 0)
|
||||||
or (
|
or (
|
||||||
install_type == 'physical'
|
system_cfg.type == 'physical'
|
||||||
and (ansible_host | default('') | string | length) > 0
|
and (ansible_host | default('') | string | length) > 0
|
||||||
)
|
)
|
||||||
}}
|
}}
|
||||||
@@ -74,29 +115,16 @@
|
|||||||
when:
|
when:
|
||||||
- post_reboot_can_connect | bool
|
- post_reboot_can_connect | bool
|
||||||
ansible.builtin.set_fact:
|
ansible.builtin.set_fact:
|
||||||
ansible_user: "{{ user_name }}"
|
ansible_user: "{{ system_cfg.user.name }}"
|
||||||
ansible_password: "{{ user_password }}"
|
ansible_password: "{{ system_cfg.user.password }}"
|
||||||
ansible_become_password: "{{ user_password }}"
|
ansible_become_password: "{{ system_cfg.user.password }}"
|
||||||
ansible_ssh_extra_args: "-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no"
|
ansible_ssh_extra_args: "-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no"
|
||||||
|
|
||||||
- name: Install post-reboot extra packages
|
- name: Install post-reboot packages
|
||||||
vars:
|
|
||||||
post_install_extra_packages: >-
|
|
||||||
{{
|
|
||||||
(
|
|
||||||
extra_packages
|
|
||||||
if (extra_packages is iterable and extra_packages is not string)
|
|
||||||
else (extra_packages | string).split(',')
|
|
||||||
)
|
|
||||||
| map('trim')
|
|
||||||
| reject('equalto', '')
|
|
||||||
| list
|
|
||||||
}}
|
|
||||||
when:
|
when:
|
||||||
- post_reboot_can_connect | bool
|
- post_reboot_can_connect | bool
|
||||||
- extra_packages is defined
|
- system_cfg.packages is defined
|
||||||
- extra_packages | length > 0
|
- system_cfg.packages | length > 0
|
||||||
- post_install_extra_packages | length > 0
|
|
||||||
ansible.builtin.package:
|
ansible.builtin.package:
|
||||||
name: "{{ post_install_extra_packages }}"
|
name: "{{ system_cfg.packages }}"
|
||||||
state: present
|
state: present
|
||||||
|
|||||||
@@ -1,20 +1,35 @@
|
|||||||
---
|
---
|
||||||
- name: Bootstrap AlmaLinux 9
|
- name: Bootstrap AlmaLinux
|
||||||
vars:
|
vars:
|
||||||
bootstrap_alma_extra: >-
|
bootstrap_almalinux_extra: >-
|
||||||
{{
|
{{
|
||||||
lookup('vars', bootstrap_var_key)
|
lookup('vars', bootstrap_var_key)
|
||||||
| reject('equalto', '')
|
| reject('equalto', '')
|
||||||
| join(' ')
|
| join(' ')
|
||||||
}}
|
}}
|
||||||
ansible.builtin.command: "{{ item }}"
|
block:
|
||||||
loop:
|
- name: Install AlmaLinux base system
|
||||||
- >-
|
ansible.builtin.command: >-
|
||||||
dnf --releasever=9 --best --repo=alma-baseos --installroot=/mnt
|
dnf --releasever={{ os_version }} --best --repo=baseos --repo=appstream
|
||||||
--setopt=install_weak_deps=False groupinstall -y base core
|
--installroot=/mnt --setopt=install_weak_deps=False
|
||||||
- ln -sf /run/NetworkManager/resolv.conf /mnt/etc/resolv.conf
|
groupinstall -y core
|
||||||
- >-
|
register: bootstrap_almalinux_base_result
|
||||||
{{ chroot_command }} /mnt dnf --releasever=9 --setopt=install_weak_deps=False
|
changed_when: bootstrap_almalinux_base_result.rc == 0
|
||||||
install -y {{ bootstrap_alma_extra }}
|
|
||||||
register: bootstrap_result
|
- name: Ensure chroot has resolv.conf
|
||||||
changed_when: bootstrap_result.rc == 0
|
ansible.builtin.file:
|
||||||
|
src: /run/NetworkManager/resolv.conf
|
||||||
|
dest: /mnt/etc/resolv.conf
|
||||||
|
state: link
|
||||||
|
|
||||||
|
- name: Install extra packages
|
||||||
|
ansible.builtin.command: >-
|
||||||
|
{{ chroot_command }} dnf --releasever={{ os_version }} --setopt=install_weak_deps=False
|
||||||
|
install -y {{ bootstrap_almalinux_extra }}
|
||||||
|
register: bootstrap_almalinux_extra_result
|
||||||
|
changed_when: bootstrap_almalinux_extra_result.rc == 0
|
||||||
|
|
||||||
|
- name: Reinstall kernel core
|
||||||
|
ansible.builtin.command: "{{ chroot_command }} dnf reinstall -y kernel-core"
|
||||||
|
register: bootstrap_almalinux_kernel_result
|
||||||
|
changed_when: bootstrap_almalinux_kernel_result.rc == 0
|
||||||
|
|||||||
33
roles/bootstrap/tasks/alpine.yml
Normal file
33
roles/bootstrap/tasks/alpine.yml
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
---
|
||||||
|
- name: Bootstrap Alpine Linux
|
||||||
|
vars:
|
||||||
|
bootstrap_alpine_packages: >-
|
||||||
|
{{
|
||||||
|
lookup('vars', 'bootstrap_alpine') | reject('equalto', '') | join(' ')
|
||||||
|
}}
|
||||||
|
block:
|
||||||
|
- name: Ensure chroot has resolv.conf
|
||||||
|
ansible.builtin.file:
|
||||||
|
src: /run/NetworkManager/resolv.conf
|
||||||
|
dest: /mnt/etc/resolv.conf
|
||||||
|
state: link
|
||||||
|
force: true
|
||||||
|
|
||||||
|
- name: Install Alpine Linux packages
|
||||||
|
ansible.builtin.command: >
|
||||||
|
apk --root /mnt --no-cache add alpine-base
|
||||||
|
register: bootstrap_alpine_bootstrap_result
|
||||||
|
changed_when: bootstrap_alpine_bootstrap_result.rc == 0
|
||||||
|
|
||||||
|
- name: Install extra packages
|
||||||
|
when: bootstrap_alpine_packages | length > 0
|
||||||
|
ansible.builtin.command: >
|
||||||
|
apk --root /mnt add {{ bootstrap_alpine_packages }}
|
||||||
|
register: bootstrap_alpine_extra_result
|
||||||
|
changed_when: bootstrap_alpine_extra_result.rc == 0
|
||||||
|
|
||||||
|
- name: Install bootloader
|
||||||
|
ansible.builtin.command: >
|
||||||
|
apk --root /mnt add grub grub-efi efibootmgr
|
||||||
|
register: bootstrap_alpine_bootloader_result
|
||||||
|
changed_when: bootstrap_alpine_bootloader_result.rc == 0
|
||||||
@@ -3,27 +3,65 @@
|
|||||||
vars:
|
vars:
|
||||||
bootstrap_debian_release: >-
|
bootstrap_debian_release: >-
|
||||||
{{
|
{{
|
||||||
'bullseye' if bootstrap_os_key == 'debian11'
|
'buster' if (os_version | string) == '10'
|
||||||
else 'bookworm' if bootstrap_os_key == 'debian12'
|
else 'bullseye' if (os_version | string) == '11'
|
||||||
|
else 'bookworm' if (os_version | string) == '12'
|
||||||
|
else 'trixie' if (os_version | string) == '13'
|
||||||
|
else 'sid' if (os_version | string) == 'unstable'
|
||||||
else 'trixie'
|
else 'trixie'
|
||||||
}}
|
}}
|
||||||
bootstrap_debian_base_list: "{{ lookup('vars', bootstrap_var_key).base | default([]) }}"
|
bootstrap_debian_package_config: >-
|
||||||
bootstrap_debian_extra_list: "{{ lookup('vars', bootstrap_var_key).extra | default([]) }}"
|
|
||||||
bootstrap_debian_base: "{{ bootstrap_debian_base_list | reject('equalto', '') | join(',') }}"
|
|
||||||
bootstrap_debian_extra: >-
|
|
||||||
{{
|
{{
|
||||||
(
|
lookup('vars', bootstrap_var_key)
|
||||||
bootstrap_debian_extra_list
|
}}
|
||||||
)
|
bootstrap_debian_base_packages: >-
|
||||||
|
{{
|
||||||
|
bootstrap_debian_package_config.base
|
||||||
|
| default([])
|
||||||
| reject('equalto', '')
|
| reject('equalto', '')
|
||||||
|
| list
|
||||||
|
}}
|
||||||
|
bootstrap_debian_extra_packages: >-
|
||||||
|
{{
|
||||||
|
bootstrap_debian_package_config.extra
|
||||||
|
| default([])
|
||||||
|
| reject('equalto', '')
|
||||||
|
| list
|
||||||
|
}}
|
||||||
|
bootstrap_debian_base_csv: "{{ bootstrap_debian_base_packages | join(',') }}"
|
||||||
|
bootstrap_debian_extra_args: >-
|
||||||
|
{{
|
||||||
|
bootstrap_debian_extra_packages
|
||||||
| join(' ')
|
| join(' ')
|
||||||
}}
|
}}
|
||||||
ansible.builtin.command: "{{ item }}"
|
block:
|
||||||
loop:
|
- name: Validate Debian package configuration
|
||||||
- >-
|
ansible.builtin.assert:
|
||||||
debootstrap --include={{ bootstrap_debian_base }}
|
that:
|
||||||
|
- bootstrap_debian_package_config is mapping
|
||||||
|
- bootstrap_debian_package_config.base is defined
|
||||||
|
- bootstrap_debian_package_config.base is sequence
|
||||||
|
- bootstrap_debian_package_config.base is not string
|
||||||
|
- bootstrap_debian_package_config.extra is defined
|
||||||
|
- bootstrap_debian_package_config.extra is sequence
|
||||||
|
- bootstrap_debian_package_config.extra is not string
|
||||||
|
fail_msg: "bootstrap package definition for {{ bootstrap_var_key }} must be a mapping with base/extra lists."
|
||||||
|
quiet: true
|
||||||
|
|
||||||
|
- name: Install Debian base system
|
||||||
|
ansible.builtin.command: >-
|
||||||
|
debootstrap --include={{ bootstrap_debian_base_csv }}
|
||||||
{{ bootstrap_debian_release }} /mnt http://deb.debian.org/debian/
|
{{ bootstrap_debian_release }} /mnt http://deb.debian.org/debian/
|
||||||
- "{{ chroot_command }} /mnt apt install -y {{ bootstrap_debian_extra }}"
|
register: bootstrap_debian_base_result
|
||||||
- "{{ chroot_command }} /mnt apt remove -y libcups2 libavahi-common3 libavahi-common-data"
|
changed_when: bootstrap_debian_base_result.rc == 0
|
||||||
register: bootstrap_result
|
|
||||||
changed_when: bootstrap_result.rc == 0
|
- name: Install extra packages
|
||||||
|
when: bootstrap_debian_extra_packages | length > 0
|
||||||
|
ansible.builtin.command: "{{ chroot_command }} apt install -y {{ bootstrap_debian_extra_args }}"
|
||||||
|
register: bootstrap_debian_extra_result
|
||||||
|
changed_when: bootstrap_debian_extra_result.rc == 0
|
||||||
|
|
||||||
|
- name: Remove unnecessary packages
|
||||||
|
ansible.builtin.command: "{{ chroot_command }} apt remove -y libcups2 libavahi-common3 libavahi-common-data"
|
||||||
|
register: bootstrap_debian_remove_result
|
||||||
|
changed_when: bootstrap_debian_remove_result.rc == 0
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
- name: Bootstrap Fedora 43
|
- name: Bootstrap Fedora
|
||||||
vars:
|
vars:
|
||||||
bootstrap_fedora_extra: >-
|
bootstrap_fedora_extra: >-
|
||||||
{{
|
{{
|
||||||
@@ -7,16 +7,29 @@
|
|||||||
| reject('equalto', '')
|
| reject('equalto', '')
|
||||||
| join(' ')
|
| join(' ')
|
||||||
}}
|
}}
|
||||||
ansible.builtin.command: "{{ item }}"
|
block:
|
||||||
loop:
|
- name: Install Fedora base system
|
||||||
- >-
|
ansible.builtin.command: >-
|
||||||
dnf --releasever=43 --best --repo=fedora --repo=fedora-updates
|
dnf --releasever={{ os_version }} --best --repo=fedora --repo=fedora-updates
|
||||||
--installroot=/mnt --setopt=install_weak_deps=False
|
--installroot=/mnt --setopt=install_weak_deps=False
|
||||||
groupinstall -y critical-path-base core
|
groupinstall -y critical-path-base core
|
||||||
- ln -sf /run/NetworkManager/resolv.conf /mnt/etc/resolv.conf
|
register: bootstrap_fedora_base_result
|
||||||
- >-
|
changed_when: bootstrap_fedora_base_result.rc == 0
|
||||||
{{ chroot_command }} /mnt dnf --releasever=43 --setopt=install_weak_deps=False
|
|
||||||
|
- name: Ensure chroot has resolv.conf
|
||||||
|
ansible.builtin.file:
|
||||||
|
src: /run/NetworkManager/resolv.conf
|
||||||
|
dest: /mnt/etc/resolv.conf
|
||||||
|
state: link
|
||||||
|
|
||||||
|
- name: Install extra packages
|
||||||
|
ansible.builtin.command: >-
|
||||||
|
{{ chroot_command }} dnf --releasever={{ os_version }} --setopt=install_weak_deps=False
|
||||||
install -y {{ bootstrap_fedora_extra }}
|
install -y {{ bootstrap_fedora_extra }}
|
||||||
- "{{ chroot_command }} /mnt dnf reinstall -y kernel-core"
|
register: bootstrap_fedora_extra_result
|
||||||
register: bootstrap_result
|
changed_when: bootstrap_fedora_extra_result.rc == 0
|
||||||
changed_when: bootstrap_result.rc == 0
|
|
||||||
|
- name: Reinstall kernel core
|
||||||
|
ansible.builtin.command: "{{ chroot_command }} dnf reinstall -y kernel-core"
|
||||||
|
register: bootstrap_fedora_kernel_result
|
||||||
|
changed_when: bootstrap_fedora_kernel_result.rc == 0
|
||||||
|
|||||||
@@ -1,27 +1,35 @@
|
|||||||
---
|
---
|
||||||
- name: Run OS-specific bootstrap process
|
- name: Run OS-specific bootstrap process
|
||||||
vars:
|
vars:
|
||||||
bootstrap_os_key: "{{ os | lower }}"
|
bootstrap_os_key: "{{ (os_resolved | default(os)) | lower }}"
|
||||||
bootstrap_var_key: "{{ 'bootstrap_' + (os | lower | replace('-', '_')) }}"
|
bootstrap_var_key: "{{ 'bootstrap_' + ((os_resolved | default(os)) | lower | replace('-', '_')) }}"
|
||||||
block:
|
block:
|
||||||
- name: Include AlmaLinux bootstrap tasks
|
- name: Include AlmaLinux bootstrap tasks
|
||||||
when: bootstrap_os_key == 'almalinux'
|
when: bootstrap_os_key in ['almalinux', 'almalinux8', 'almalinux9', 'almalinux10']
|
||||||
ansible.builtin.include_tasks: almalinux.yml
|
ansible.builtin.include_tasks: almalinux.yml
|
||||||
|
|
||||||
|
- name: Include Alpine bootstrap tasks
|
||||||
|
when: bootstrap_os_key == 'alpine'
|
||||||
|
ansible.builtin.include_tasks: alpine.yml
|
||||||
|
|
||||||
- name: Include ArchLinux bootstrap tasks
|
- name: Include ArchLinux bootstrap tasks
|
||||||
when: bootstrap_os_key == 'archlinux'
|
when: bootstrap_os_key == 'archlinux'
|
||||||
ansible.builtin.include_tasks: archlinux.yml
|
ansible.builtin.include_tasks: archlinux.yml
|
||||||
|
|
||||||
- name: Include Debian bootstrap tasks
|
- name: Include Debian bootstrap tasks
|
||||||
when: bootstrap_os_key in ['debian11', 'debian12', 'debian13']
|
when: bootstrap_os_key in ['debian10', 'debian11', 'debian12', 'debian13', 'debianunstable']
|
||||||
ansible.builtin.include_tasks: debian.yml
|
ansible.builtin.include_tasks: debian.yml
|
||||||
|
|
||||||
- name: Include Fedora bootstrap tasks
|
- name: Include Fedora bootstrap tasks
|
||||||
when: bootstrap_os_key == 'fedora'
|
when: bootstrap_os_key in ['fedora', 'fedora40', 'fedora41', 'fedora42', 'fedora43']
|
||||||
ansible.builtin.include_tasks: fedora.yml
|
ansible.builtin.include_tasks: fedora.yml
|
||||||
|
|
||||||
|
- name: Include openSUSE bootstrap tasks
|
||||||
|
when: bootstrap_os_key == 'opensuse'
|
||||||
|
ansible.builtin.include_tasks: opensuse.yml
|
||||||
|
|
||||||
- name: Include Rocky bootstrap tasks
|
- name: Include Rocky bootstrap tasks
|
||||||
when: bootstrap_os_key == 'rocky'
|
when: bootstrap_os_key in ['rocky', 'rocky8', 'rocky9', 'rocky10']
|
||||||
ansible.builtin.include_tasks: rocky.yml
|
ansible.builtin.include_tasks: rocky.yml
|
||||||
|
|
||||||
- name: Include RHEL bootstrap tasks
|
- name: Include RHEL bootstrap tasks
|
||||||
@@ -31,3 +39,7 @@
|
|||||||
- name: Include Ubuntu bootstrap tasks
|
- name: Include Ubuntu bootstrap tasks
|
||||||
when: bootstrap_os_key in ['ubuntu', 'ubuntu-lts']
|
when: bootstrap_os_key in ['ubuntu', 'ubuntu-lts']
|
||||||
ansible.builtin.include_tasks: ubuntu.yml
|
ansible.builtin.include_tasks: ubuntu.yml
|
||||||
|
|
||||||
|
- name: Include Void bootstrap tasks
|
||||||
|
when: bootstrap_os_key == 'void'
|
||||||
|
ansible.builtin.include_tasks: void.yml
|
||||||
|
|||||||
33
roles/bootstrap/tasks/opensuse.yml
Normal file
33
roles/bootstrap/tasks/opensuse.yml
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
---
|
||||||
|
- name: Bootstrap openSUSE
|
||||||
|
vars:
|
||||||
|
bootstrap_opensuse_packages: >-
|
||||||
|
{{
|
||||||
|
lookup('vars', 'bootstrap_opensuse') | reject('equalto', '') | join(' ')
|
||||||
|
}}
|
||||||
|
block:
|
||||||
|
- name: Ensure chroot has resolv.conf
|
||||||
|
ansible.builtin.file:
|
||||||
|
src: /run/NetworkManager/resolv.conf
|
||||||
|
dest: /mnt/etc/resolv.conf
|
||||||
|
state: link
|
||||||
|
force: true
|
||||||
|
|
||||||
|
- name: Install openSUSE base packages
|
||||||
|
ansible.builtin.command: >
|
||||||
|
zypper --root /mnt --non-interactive install -t pattern patterns-base-base
|
||||||
|
register: bootstrap_opensuse_base_result
|
||||||
|
changed_when: bootstrap_opensuse_base_result.rc == 0
|
||||||
|
|
||||||
|
- name: Install openSUSE extra packages
|
||||||
|
when: bootstrap_opensuse_packages | length > 0
|
||||||
|
ansible.builtin.command: >
|
||||||
|
zypper --root /mnt --non-interactive install {{ bootstrap_opensuse_packages }}
|
||||||
|
register: bootstrap_opensuse_extra_result
|
||||||
|
changed_when: bootstrap_opensuse_extra_result.rc == 0
|
||||||
|
|
||||||
|
- name: Install bootloader
|
||||||
|
ansible.builtin.command: >
|
||||||
|
zypper --root /mnt --non-interactive install grub2 grub2-efi efibootmgr
|
||||||
|
register: bootstrap_opensuse_bootloader_result
|
||||||
|
changed_when: bootstrap_opensuse_bootloader_result.rc == 0
|
||||||
@@ -17,7 +17,6 @@
|
|||||||
src: /run/NetworkManager/resolv.conf
|
src: /run/NetworkManager/resolv.conf
|
||||||
dest: /mnt/etc/resolv.conf
|
dest: /mnt/etc/resolv.conf
|
||||||
state: link
|
state: link
|
||||||
force: true
|
|
||||||
|
|
||||||
- name: Ensure chroot RHEL DVD directory exists
|
- name: Ensure chroot RHEL DVD directory exists
|
||||||
ansible.builtin.file:
|
ansible.builtin.file:
|
||||||
@@ -34,7 +33,7 @@
|
|||||||
state: mounted
|
state: mounted
|
||||||
|
|
||||||
- name: Rebuild RPM database inside chroot
|
- name: Rebuild RPM database inside chroot
|
||||||
ansible.builtin.command: "{{ chroot_command }} /mnt rpm --rebuilddb"
|
ansible.builtin.command: "{{ chroot_command }} rpm --rebuilddb"
|
||||||
register: bootstrap_rpm_rebuild_result
|
register: bootstrap_rpm_rebuild_result
|
||||||
changed_when: bootstrap_rpm_rebuild_result.rc == 0
|
changed_when: bootstrap_rpm_rebuild_result.rc == 0
|
||||||
|
|
||||||
@@ -55,7 +54,7 @@
|
|||||||
| join(' ')
|
| join(' ')
|
||||||
}}
|
}}
|
||||||
ansible.builtin.command: >-
|
ansible.builtin.command: >-
|
||||||
{{ chroot_command }} /mnt dnf --releasever={{ bootstrap_rhel_release }}
|
{{ chroot_command }} dnf --releasever={{ bootstrap_rhel_release }}
|
||||||
--setopt=install_weak_deps=False install -y {{ bootstrap_rhel_extra }}
|
--setopt=install_weak_deps=False install -y {{ bootstrap_rhel_extra }}
|
||||||
register: bootstrap_result
|
register: bootstrap_result
|
||||||
changed_when: bootstrap_result.rc == 0
|
changed_when: bootstrap_result.rc == 0
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
- name: Bootstrap RockyLinux 9
|
- name: Bootstrap Rocky Linux
|
||||||
vars:
|
vars:
|
||||||
bootstrap_rocky_extra: >-
|
bootstrap_rocky_extra: >-
|
||||||
{{
|
{{
|
||||||
@@ -7,15 +7,29 @@
|
|||||||
| reject('equalto', '')
|
| reject('equalto', '')
|
||||||
| join(' ')
|
| join(' ')
|
||||||
}}
|
}}
|
||||||
ansible.builtin.command: "{{ item }}"
|
block:
|
||||||
loop:
|
- name: Install Rocky Linux base system
|
||||||
- >-
|
ansible.builtin.command: >-
|
||||||
dnf --releasever=9 --best --repo=rocky-baseos --installroot=/mnt
|
dnf --releasever={{ os_version }} --best --repo=baseos --repo=appstream
|
||||||
--setopt=install_weak_deps=False --setopt=optional_metadata_types=filelists
|
--installroot=/mnt --setopt=install_weak_deps=False
|
||||||
groupinstall -y base core
|
groupinstall -y core
|
||||||
- ln -sf /run/NetworkManager/resolv.conf /mnt/etc/resolv.conf
|
register: bootstrap_rocky_base_result
|
||||||
- >-
|
changed_when: bootstrap_rocky_base_result.rc == 0
|
||||||
{{ chroot_command }} /mnt dnf --releasever=9 --setopt=install_weak_deps=False
|
|
||||||
|
- name: Ensure chroot has resolv.conf
|
||||||
|
ansible.builtin.file:
|
||||||
|
src: /run/NetworkManager/resolv.conf
|
||||||
|
dest: /mnt/etc/resolv.conf
|
||||||
|
state: link
|
||||||
|
|
||||||
|
- name: Install extra packages
|
||||||
|
ansible.builtin.command: >-
|
||||||
|
{{ chroot_command }} dnf --releasever={{ os_version }} --setopt=install_weak_deps=False
|
||||||
install -y {{ bootstrap_rocky_extra }}
|
install -y {{ bootstrap_rocky_extra }}
|
||||||
register: bootstrap_result
|
register: bootstrap_rocky_extra_result
|
||||||
changed_when: bootstrap_result.rc == 0
|
changed_when: bootstrap_rocky_extra_result.rc == 0
|
||||||
|
|
||||||
|
- name: Reinstall kernel core
|
||||||
|
ansible.builtin.command: "{{ chroot_command }} dnf reinstall -y kernel-core"
|
||||||
|
register: bootstrap_rocky_kernel_result
|
||||||
|
changed_when: bootstrap_rocky_kernel_result.rc == 0
|
||||||
|
|||||||
@@ -3,25 +3,66 @@
|
|||||||
vars:
|
vars:
|
||||||
bootstrap_ubuntu_release: >-
|
bootstrap_ubuntu_release: >-
|
||||||
{{ 'plucky' if bootstrap_os_key == 'ubuntu' else 'noble' }}
|
{{ 'plucky' if bootstrap_os_key == 'ubuntu' else 'noble' }}
|
||||||
bootstrap_ubuntu_base_list: "{{ lookup('vars', bootstrap_var_key).base | default([]) }}"
|
bootstrap_ubuntu_package_config: >-
|
||||||
bootstrap_ubuntu_extra_list: "{{ lookup('vars', bootstrap_var_key).extra | default([]) }}"
|
|
||||||
bootstrap_ubuntu_base: "{{ bootstrap_ubuntu_base_list | reject('equalto', '') | join(',') }}"
|
|
||||||
bootstrap_ubuntu_extra: >-
|
|
||||||
{{
|
{{
|
||||||
(
|
lookup('vars', bootstrap_var_key)
|
||||||
bootstrap_ubuntu_extra_list
|
|
||||||
)
|
|
||||||
| reject('equalto', '')
|
|
||||||
| join(' ')
|
|
||||||
}}
|
}}
|
||||||
ansible.builtin.command: "{{ item }}"
|
bootstrap_ubuntu_base_packages: >-
|
||||||
loop:
|
{{
|
||||||
- >-
|
bootstrap_ubuntu_package_config.base
|
||||||
debootstrap --include={{ bootstrap_ubuntu_base }}
|
| default([])
|
||||||
{{ bootstrap_ubuntu_release }} /mnt http://archive.ubuntu.com/ubuntu/
|
| reject('equalto', '')
|
||||||
- ln -sf /run/NetworkManager/resolv.conf /mnt/etc/resolv.conf
|
| list
|
||||||
- "{{ chroot_command }} /mnt sed -i '1s|$| universe|' /etc/apt/sources.list"
|
}}
|
||||||
- "{{ chroot_command }} /mnt apt update"
|
bootstrap_ubuntu_extra_packages: >-
|
||||||
- "{{ chroot_command }} /mnt apt install -y {{ bootstrap_ubuntu_extra }}"
|
{{
|
||||||
register: bootstrap_result
|
bootstrap_ubuntu_package_config.extra
|
||||||
changed_when: bootstrap_result.rc == 0
|
| default([])
|
||||||
|
| reject('equalto', '')
|
||||||
|
| list
|
||||||
|
}}
|
||||||
|
bootstrap_ubuntu_base_csv: "{{ bootstrap_ubuntu_base_packages | join(',') }}"
|
||||||
|
bootstrap_ubuntu_extra: "{{ bootstrap_ubuntu_extra_packages | join(' ') }}"
|
||||||
|
block:
|
||||||
|
- name: Validate Ubuntu package configuration
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- bootstrap_ubuntu_package_config is mapping
|
||||||
|
- bootstrap_ubuntu_package_config.base is defined
|
||||||
|
- bootstrap_ubuntu_package_config.base is sequence
|
||||||
|
- bootstrap_ubuntu_package_config.base is not string
|
||||||
|
- bootstrap_ubuntu_package_config.extra is defined
|
||||||
|
- bootstrap_ubuntu_package_config.extra is sequence
|
||||||
|
- bootstrap_ubuntu_package_config.extra is not string
|
||||||
|
fail_msg: "bootstrap package definition for {{ bootstrap_var_key }} must be a mapping with base/extra lists."
|
||||||
|
quiet: true
|
||||||
|
|
||||||
|
- name: Install Ubuntu base system
|
||||||
|
ansible.builtin.command: >-
|
||||||
|
debootstrap --include={{ bootstrap_ubuntu_base_csv }}
|
||||||
|
{{ bootstrap_ubuntu_release }} /mnt
|
||||||
|
http://archive.ubuntu.com/ubuntu/
|
||||||
|
register: bootstrap_ubuntu_base_result
|
||||||
|
changed_when: bootstrap_ubuntu_base_result.rc == 0
|
||||||
|
|
||||||
|
- name: Ensure chroot has resolv.conf
|
||||||
|
ansible.builtin.file:
|
||||||
|
src: /run/NetworkManager/resolv.conf
|
||||||
|
dest: /mnt/etc/resolv.conf
|
||||||
|
state: link
|
||||||
|
|
||||||
|
- name: Enable universe repository
|
||||||
|
ansible.builtin.command: "{{ chroot_command }} sed -i '1s|$| universe|' /etc/apt/sources.list"
|
||||||
|
register: bootstrap_ubuntu_repo_result
|
||||||
|
changed_when: bootstrap_ubuntu_repo_result.rc == 0
|
||||||
|
|
||||||
|
- name: Update package lists
|
||||||
|
ansible.builtin.command: "{{ chroot_command }} apt update"
|
||||||
|
register: bootstrap_ubuntu_update_result
|
||||||
|
changed_when: bootstrap_ubuntu_update_result.rc == 0
|
||||||
|
|
||||||
|
- name: Install extra packages
|
||||||
|
when: bootstrap_ubuntu_extra_packages | length > 0
|
||||||
|
ansible.builtin.command: "{{ chroot_command }} apt install -y {{ bootstrap_ubuntu_extra }}"
|
||||||
|
register: bootstrap_ubuntu_extra_result
|
||||||
|
changed_when: bootstrap_ubuntu_extra_result.rc == 0
|
||||||
|
|||||||
33
roles/bootstrap/tasks/void.yml
Normal file
33
roles/bootstrap/tasks/void.yml
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
---
|
||||||
|
- name: Bootstrap Void Linux
|
||||||
|
vars:
|
||||||
|
bootstrap_void_packages: >-
|
||||||
|
{{
|
||||||
|
lookup('vars', 'bootstrap_void') | reject('equalto', '') | join(' ')
|
||||||
|
}}
|
||||||
|
block:
|
||||||
|
- name: Ensure chroot has resolv.conf
|
||||||
|
ansible.builtin.file:
|
||||||
|
src: /run/NetworkManager/resolv.conf
|
||||||
|
dest: /mnt/etc/resolv.conf
|
||||||
|
state: link
|
||||||
|
force: true
|
||||||
|
|
||||||
|
- name: Install Void Linux base packages
|
||||||
|
ansible.builtin.command: >
|
||||||
|
xbps-install -Sy -r /mnt -R https://repo-default.voidlinux.org/current void-repo-nonfree base-system
|
||||||
|
register: bootstrap_void_base_result
|
||||||
|
changed_when: bootstrap_void_base_result.rc == 0
|
||||||
|
|
||||||
|
- name: Install extra packages
|
||||||
|
when: bootstrap_void_packages | length > 0
|
||||||
|
ansible.builtin.command: >
|
||||||
|
xbps-install -Su -r /mnt {{ bootstrap_void_packages }}
|
||||||
|
register: bootstrap_void_extra_result
|
||||||
|
changed_when: bootstrap_void_extra_result.rc == 0
|
||||||
|
|
||||||
|
- name: Install bootloader
|
||||||
|
ansible.builtin.command: >
|
||||||
|
xbps-install -Sy -r /mnt grub-x86_64-efi efibootmgr
|
||||||
|
register: bootstrap_void_bootloader_result
|
||||||
|
changed_when: bootstrap_void_bootloader_result.rc == 0
|
||||||
@@ -1,229 +1,56 @@
|
|||||||
---
|
---
|
||||||
bootstrap_almalinux:
|
bootstrap_rhel_base:
|
||||||
- bind-utils
|
- bind-utils
|
||||||
- dbus-daemon
|
|
||||||
- dhcp-client
|
- dhcp-client
|
||||||
- efibootmgr
|
- efibootmgr
|
||||||
- "{{ 'firewalld' if firewalld_enabled | bool else '' }}"
|
- "{{ 'firewalld' if system_cfg.features.firewall.backend == 'firewalld' and system_cfg.features.firewall.enabled | bool else '' }}"
|
||||||
|
- "{{ 'ufw' if system_cfg.features.firewall.backend == 'ufw' and system_cfg.features.firewall.enabled | bool else '' }}"
|
||||||
|
- "{{ 'iptables' if system_cfg.features.firewall.toolkit == 'iptables' else '' }}"
|
||||||
|
- "{{ 'nftables' if system_cfg.features.firewall.toolkit == 'nftables' else '' }}"
|
||||||
- glibc-langpack-de
|
- glibc-langpack-de
|
||||||
- glibc-langpack-en
|
- glibc-langpack-en
|
||||||
- grub2
|
|
||||||
- grub2-efi
|
|
||||||
- lrzsz
|
- lrzsz
|
||||||
- lvm2
|
- lvm2
|
||||||
- nc
|
|
||||||
- nfs-utils
|
|
||||||
- nfsv4-client-utils
|
|
||||||
- mtr
|
- mtr
|
||||||
- ppp
|
- ncurses-term
|
||||||
|
- nfs-utils
|
||||||
|
- policycoreutils-python-utils
|
||||||
- shim
|
- shim
|
||||||
- tmux
|
- tmux
|
||||||
- "{{ 'cryptsetup' if luks_enabled else '' }}"
|
- "{{ 'cryptsetup' if system_cfg.luks.enabled else '' }}"
|
||||||
- "{{ 'tpm2-tools' if luks_enabled else '' }}"
|
- "{{ 'tpm2-tools' if system_cfg.luks.enabled else '' }}"
|
||||||
- "{{ 'qemu-guest-agent' if hypervisor | lower in ['libvirt', 'proxmox'] else '' }}"
|
- "{{ 'qemu-guest-agent' if hypervisor_type in ['libvirt', 'proxmox'] else '' }}"
|
||||||
- "{{ 'open-vm-tools' if hypervisor | lower == 'vmware' else '' }}"
|
- "{{ 'open-vm-tools' if hypervisor_type == 'vmware' else '' }}"
|
||||||
- vim
|
- vim
|
||||||
- wget
|
|
||||||
- zram-generator
|
|
||||||
- zstd
|
- zstd
|
||||||
|
|
||||||
bootstrap_archlinux:
|
bootstrap_rhel_versioned:
|
||||||
- base
|
- grub2
|
||||||
- btrfs-progs
|
- "{{ 'grub2-efi-x64' if os_version_major | default('') == '8' else 'grub2-efi' }}"
|
||||||
- cronie
|
- "{{ 'grub2-tools-extra' if os_version_major | default('') in ['8', '9'] else '' }}"
|
||||||
- dhcpcd
|
- "{{ 'python39' if os_version_major | default('') == '8' else 'python' }}"
|
||||||
- efibootmgr
|
- "{{ 'kernel' if os_version_major | default('') == '10' else '' }}"
|
||||||
- fastfetch
|
- "{{ 'zram-generator' if os_version_major | default('') in ['9', '10'] else '' }}"
|
||||||
- "{{ 'firewalld' if firewalld_enabled | bool else '' }}"
|
|
||||||
- fish
|
|
||||||
- fzf
|
|
||||||
- grub
|
|
||||||
- htop
|
|
||||||
- libpwquality
|
|
||||||
- linux
|
|
||||||
- logrotate
|
|
||||||
- lrzsz
|
|
||||||
- lsof
|
|
||||||
- lvm2
|
|
||||||
- ncdu
|
|
||||||
- networkmanager
|
|
||||||
- nfs-utils
|
|
||||||
- "{{ 'openssh' if ssh_enabled | bool else '' }}"
|
|
||||||
- ppp
|
|
||||||
- prometheus-node-exporter
|
|
||||||
- python-psycopg2
|
|
||||||
- reflector
|
|
||||||
- rsync
|
|
||||||
- sudo
|
|
||||||
- tldr
|
|
||||||
- tmux
|
|
||||||
- "{{ 'cryptsetup' if luks_enabled else '' }}"
|
|
||||||
- "{{ 'tpm2-tools' if luks_enabled else '' }}"
|
|
||||||
- "{{ 'qemu-guest-agent' if hypervisor | lower in ['libvirt', 'proxmox'] else '' }}"
|
|
||||||
- "{{ 'open-vm-tools' if hypervisor | lower == 'vmware' else '' }}"
|
|
||||||
- vim
|
|
||||||
- wireguard-tools
|
|
||||||
- zram-generator
|
|
||||||
|
|
||||||
bootstrap_debian11:
|
bootstrap_rhel_common: "{{ bootstrap_rhel_base + bootstrap_rhel_versioned }}"
|
||||||
base:
|
|
||||||
- apparmor-utils
|
|
||||||
- btrfs-progs
|
|
||||||
- chrony
|
|
||||||
- cron
|
|
||||||
- gnupg
|
|
||||||
- grub-efi
|
|
||||||
- grub-efi-amd64-signed
|
|
||||||
- grub2-common
|
|
||||||
- "{{ 'cryptsetup' if luks_enabled else '' }}"
|
|
||||||
- "{{ 'cryptsetup-initramfs' if luks_enabled else '' }}"
|
|
||||||
- linux-image-amd64
|
|
||||||
- locales
|
|
||||||
- logrotate
|
|
||||||
- lvm2
|
|
||||||
- net-tools
|
|
||||||
- "{{ 'openssh-server' if ssh_enabled | bool else '' }}"
|
|
||||||
- python3
|
|
||||||
- sudo
|
|
||||||
- xfsprogs
|
|
||||||
|
|
||||||
extra:
|
bootstrap_rhel8: "{{ bootstrap_rhel_common }}"
|
||||||
- bat
|
bootstrap_rhel9: "{{ bootstrap_rhel_common }}"
|
||||||
- curl
|
bootstrap_rhel10: "{{ bootstrap_rhel_common }}"
|
||||||
- entr
|
|
||||||
- "{{ 'firewalld' if firewalld_enabled | bool else '' }}"
|
|
||||||
- fish
|
|
||||||
- fzf
|
|
||||||
- htop
|
|
||||||
- jq
|
|
||||||
- libpam-pwquality
|
|
||||||
- lrzsz
|
|
||||||
- mtr
|
|
||||||
- ncdu
|
|
||||||
- neofetch
|
|
||||||
- network-manager
|
|
||||||
- python-is-python3
|
|
||||||
- ripgrep
|
|
||||||
- rsync
|
|
||||||
- screen
|
|
||||||
- software-properties-common
|
|
||||||
- syslog-ng
|
|
||||||
- tcpd
|
|
||||||
- tldr
|
|
||||||
- "{{ 'tpm2-tools' if luks_enabled else '' }}"
|
|
||||||
- "{{ 'qemu-guest-agent' if hypervisor | lower in ['libvirt', 'proxmox'] else '' }}"
|
|
||||||
- "{{ 'open-vm-tools' if hypervisor | lower == 'vmware' else '' }}"
|
|
||||||
- vim
|
|
||||||
- wget
|
|
||||||
- zstd
|
|
||||||
|
|
||||||
bootstrap_debian12:
|
bootstrap_almalinux:
|
||||||
base:
|
"{{ bootstrap_rhel_base + ['grub2', 'grub2-efi', 'dbus-daemon', 'lrzsz', 'nfsv4-client-utils', 'nc', 'ppp', 'zram-generator'] }}"
|
||||||
- btrfs-progs
|
|
||||||
- cron
|
|
||||||
- gnupg
|
|
||||||
- grub-efi
|
|
||||||
- grub-efi-amd64-signed
|
|
||||||
- grub2-common
|
|
||||||
- "{{ 'cryptsetup' if luks_enabled else '' }}"
|
|
||||||
- "{{ 'cryptsetup-initramfs' if luks_enabled else '' }}"
|
|
||||||
- linux-image-amd64
|
|
||||||
- locales
|
|
||||||
- logrotate
|
|
||||||
- lvm2
|
|
||||||
- xfsprogs
|
|
||||||
|
|
||||||
extra:
|
bootstrap_rocky:
|
||||||
- apparmor-utils
|
"{{ bootstrap_rhel_base + ['grub2', 'grub2-efi', 'nfsv4-client-utils', 'nc', 'ppp', 'telnet', 'util-linux-core', 'wget', 'zram-generator'] }}"
|
||||||
- bat
|
|
||||||
- chrony
|
|
||||||
- curl
|
|
||||||
- duf
|
|
||||||
- entr
|
|
||||||
- "{{ 'firewalld' if firewalld_enabled | bool else '' }}"
|
|
||||||
- fish
|
|
||||||
- fzf
|
|
||||||
- htop
|
|
||||||
- jq
|
|
||||||
- libpam-pwquality
|
|
||||||
- logrotate
|
|
||||||
- lrzsz
|
|
||||||
- mtr
|
|
||||||
- ncdu
|
|
||||||
- neofetch
|
|
||||||
- net-tools
|
|
||||||
- network-manager
|
|
||||||
- "{{ 'openssh-server' if ssh_enabled | bool else '' }}"
|
|
||||||
- python-is-python3
|
|
||||||
- python3
|
|
||||||
- ripgrep
|
|
||||||
- rsync
|
|
||||||
- screen
|
|
||||||
- software-properties-common
|
|
||||||
- sudo
|
|
||||||
- syslog-ng
|
|
||||||
- systemd-zram-generator
|
|
||||||
- tcpd
|
|
||||||
- tldr
|
|
||||||
- "{{ 'tpm2-tools' if luks_enabled else '' }}"
|
|
||||||
- "{{ 'qemu-guest-agent' if hypervisor | lower in ['libvirt', 'proxmox'] else '' }}"
|
|
||||||
- "{{ 'open-vm-tools' if hypervisor | lower == 'vmware' else '' }}"
|
|
||||||
- vim
|
|
||||||
- wget
|
|
||||||
- zstd
|
|
||||||
|
|
||||||
bootstrap_debian13:
|
bootstrap_almalinux8: "{{ bootstrap_almalinux }}"
|
||||||
base:
|
bootstrap_almalinux9: "{{ bootstrap_almalinux }}"
|
||||||
- btrfs-progs
|
bootstrap_almalinux10: "{{ bootstrap_almalinux }}"
|
||||||
- cron
|
|
||||||
- gnupg
|
|
||||||
- grub-efi
|
|
||||||
- grub-efi-amd64-signed
|
|
||||||
- grub2-common
|
|
||||||
- "{{ 'cryptsetup' if luks_enabled else '' }}"
|
|
||||||
- "{{ 'cryptsetup-initramfs' if luks_enabled else '' }}"
|
|
||||||
- linux-image-amd64
|
|
||||||
- locales
|
|
||||||
- logrotate
|
|
||||||
- lvm2
|
|
||||||
- xfsprogs
|
|
||||||
|
|
||||||
extra:
|
bootstrap_rocky8: "{{ bootstrap_rocky }}"
|
||||||
- apparmor-utils
|
bootstrap_rocky9: "{{ bootstrap_rocky }}"
|
||||||
- bat
|
bootstrap_rocky10: "{{ bootstrap_rocky }}"
|
||||||
- chrony
|
|
||||||
- curl
|
|
||||||
- duf
|
|
||||||
- entr
|
|
||||||
- fastfetch
|
|
||||||
- "{{ 'firewalld' if firewalld_enabled | bool else '' }}"
|
|
||||||
- fish
|
|
||||||
- fzf
|
|
||||||
- htop
|
|
||||||
- jq
|
|
||||||
- libpam-pwquality
|
|
||||||
- logrotate
|
|
||||||
- lrzsz
|
|
||||||
- mtr
|
|
||||||
- ncdu
|
|
||||||
- net-tools
|
|
||||||
- network-manager
|
|
||||||
- "{{ 'openssh-server' if ssh_enabled | bool else '' }}"
|
|
||||||
- python-is-python3
|
|
||||||
- python3
|
|
||||||
- ripgrep
|
|
||||||
- rsync
|
|
||||||
- screen
|
|
||||||
- sudo
|
|
||||||
- syslog-ng
|
|
||||||
- systemd-zram-generator
|
|
||||||
- tcpd
|
|
||||||
- "{{ 'tpm2-tools' if luks_enabled else '' }}"
|
|
||||||
- "{{ 'qemu-guest-agent' if hypervisor | lower in ['libvirt', 'proxmox'] else '' }}"
|
|
||||||
- "{{ 'open-vm-tools' if hypervisor | lower == 'vmware' else '' }}"
|
|
||||||
- vim
|
|
||||||
- wget
|
|
||||||
- zstd
|
|
||||||
|
|
||||||
bootstrap_fedora:
|
bootstrap_fedora:
|
||||||
- bat
|
- bat
|
||||||
@@ -234,7 +61,10 @@ bootstrap_fedora:
|
|||||||
- duf
|
- duf
|
||||||
- efibootmgr
|
- efibootmgr
|
||||||
- entr
|
- entr
|
||||||
- "{{ 'firewalld' if firewalld_enabled | bool else '' }}"
|
- "{{ 'firewalld' if system_cfg.features.firewall.backend == 'firewalld' and system_cfg.features.firewall.enabled | bool else '' }}"
|
||||||
|
- "{{ 'ufw' if system_cfg.features.firewall.backend == 'ufw' and system_cfg.features.firewall.enabled | bool else '' }}"
|
||||||
|
- "{{ 'iptables' if system_cfg.features.firewall.toolkit == 'iptables' else '' }}"
|
||||||
|
- "{{ 'nftables' if system_cfg.features.firewall.toolkit == 'nftables' else '' }}"
|
||||||
- fish
|
- fish
|
||||||
- fzf
|
- fzf
|
||||||
- glibc-langpack-de
|
- glibc-langpack-de
|
||||||
@@ -254,247 +84,184 @@ bootstrap_fedora:
|
|||||||
- ripgrep
|
- ripgrep
|
||||||
- shim
|
- shim
|
||||||
- tmux
|
- tmux
|
||||||
- "{{ 'cryptsetup' if luks_enabled else '' }}"
|
- "{{ 'cryptsetup' if system_cfg.luks.enabled else '' }}"
|
||||||
- "{{ 'tpm2-tools' if luks_enabled else '' }}"
|
- "{{ 'tpm2-tools' if system_cfg.luks.enabled else '' }}"
|
||||||
- "{{ 'qemu-guest-agent' if hypervisor | lower in ['libvirt', 'proxmox'] else '' }}"
|
- "{{ 'qemu-guest-agent' if hypervisor_type in ['libvirt', 'proxmox'] else '' }}"
|
||||||
- "{{ 'open-vm-tools' if hypervisor | lower == 'vmware' else '' }}"
|
- "{{ 'open-vm-tools' if hypervisor_type == 'vmware' else '' }}"
|
||||||
- vim-default-editor
|
- vim-default-editor
|
||||||
- wget
|
- wget
|
||||||
- zoxide
|
- zoxide
|
||||||
- zram-generator
|
- zram-generator
|
||||||
- zstd
|
- zstd
|
||||||
|
|
||||||
bootstrap_rhel8:
|
bootstrap_fedora40: "{{ bootstrap_fedora }}"
|
||||||
- bind-utils
|
bootstrap_fedora41: "{{ bootstrap_fedora }}"
|
||||||
- dhcp-client
|
bootstrap_fedora42: "{{ bootstrap_fedora }}"
|
||||||
- efibootmgr
|
bootstrap_fedora43: "{{ bootstrap_fedora }}"
|
||||||
- "{{ 'firewalld' if firewalld_enabled | bool else '' }}"
|
|
||||||
- glibc-langpack-de
|
|
||||||
- glibc-langpack-en
|
|
||||||
- grub2
|
|
||||||
- grub2-efi-x64
|
|
||||||
- grub2-tools-extra
|
|
||||||
- lrzsz
|
|
||||||
- lvm2
|
|
||||||
- mtr
|
|
||||||
- ncurses-term
|
|
||||||
- nfs-utils
|
|
||||||
- policycoreutils-python-utils
|
|
||||||
- python39
|
|
||||||
- shim
|
|
||||||
- tmux
|
|
||||||
- "{{ 'cryptsetup' if luks_enabled else '' }}"
|
|
||||||
- "{{ 'tpm2-tools' if luks_enabled else '' }}"
|
|
||||||
- "{{ 'qemu-guest-agent' if hypervisor | lower in ['libvirt', 'proxmox'] else '' }}"
|
|
||||||
- "{{ 'open-vm-tools' if hypervisor | lower == 'vmware' else '' }}"
|
|
||||||
- vim
|
|
||||||
- zstd
|
|
||||||
|
|
||||||
bootstrap_rhel9:
|
bootstrap_debian_base_common:
|
||||||
- bind-utils
|
- btrfs-progs
|
||||||
- dhcp-client
|
- cron
|
||||||
- efibootmgr
|
- gnupg
|
||||||
- "{{ 'firewalld' if firewalld_enabled | bool else '' }}"
|
- grub-efi
|
||||||
- glibc-langpack-de
|
- grub-efi-amd64-signed
|
||||||
- glibc-langpack-en
|
- grub2-common
|
||||||
- grub2
|
- "{{ 'cryptsetup' if system_cfg.luks.enabled else '' }}"
|
||||||
- grub2-efi
|
- "{{ 'cryptsetup-initramfs' if system_cfg.luks.enabled else '' }}"
|
||||||
- grub2-tools-extra
|
- locales
|
||||||
- lrzsz
|
- logrotate
|
||||||
- lvm2
|
- lvm2
|
||||||
- mtr
|
- "{{ 'iptables' if system_cfg.features.firewall.toolkit == 'iptables' else '' }}"
|
||||||
- ncurses-term
|
- "{{ 'nftables' if system_cfg.features.firewall.toolkit == 'nftables' else '' }}"
|
||||||
- nfs-utils
|
- "{{ 'openssh-server' if system_cfg.features.ssh.enabled | bool else '' }}"
|
||||||
- policycoreutils-python-utils
|
- python3
|
||||||
- python
|
- xfsprogs
|
||||||
- shim
|
|
||||||
- tmux
|
|
||||||
- "{{ 'cryptsetup' if luks_enabled else '' }}"
|
|
||||||
- "{{ 'tpm2-tools' if luks_enabled else '' }}"
|
|
||||||
- "{{ 'qemu-guest-agent' if hypervisor | lower in ['libvirt', 'proxmox'] else '' }}"
|
|
||||||
- "{{ 'open-vm-tools' if hypervisor | lower == 'vmware' else '' }}"
|
|
||||||
- vim
|
|
||||||
- zram-generator
|
|
||||||
- zstd
|
|
||||||
|
|
||||||
bootstrap_rhel10:
|
bootstrap_debian_extra_common:
|
||||||
- bind-utils
|
- apparmor-utils
|
||||||
- efibootmgr
|
- bat
|
||||||
- "{{ 'firewalld' if firewalld_enabled | bool else '' }}"
|
- chrony
|
||||||
- glibc-langpack-de
|
- curl
|
||||||
- glibc-langpack-en
|
- entr
|
||||||
- grub2
|
- "{{ 'firewalld' if system_cfg.features.firewall.backend == 'firewalld' and system_cfg.features.firewall.enabled | bool else '' }}"
|
||||||
- grub2-efi
|
- "{{ 'ufw' if system_cfg.features.firewall.backend == 'ufw' and system_cfg.features.firewall.enabled | bool else '' }}"
|
||||||
- kernel
|
- fish
|
||||||
|
- fzf
|
||||||
|
- htop
|
||||||
|
- jq
|
||||||
|
- libpam-pwquality
|
||||||
- lrzsz
|
- lrzsz
|
||||||
- lvm2
|
|
||||||
- mtr
|
- mtr
|
||||||
- ncurses-term
|
- ncdu
|
||||||
- nfs-utils
|
- net-tools
|
||||||
- policycoreutils-python-utils
|
- network-manager
|
||||||
- python
|
- python-is-python3
|
||||||
- shim
|
- ripgrep
|
||||||
- tmux
|
- rsync
|
||||||
- "{{ 'cryptsetup' if luks_enabled else '' }}"
|
- screen
|
||||||
- "{{ 'tpm2-tools' if luks_enabled else '' }}"
|
- sudo
|
||||||
- "{{ 'qemu-guest-agent' if hypervisor | lower in ['libvirt', 'proxmox'] else '' }}"
|
- syslog-ng
|
||||||
- "{{ 'open-vm-tools' if hypervisor | lower == 'vmware' else '' }}"
|
- tcpd
|
||||||
- vim
|
- "{{ 'tpm2-tools' if system_cfg.luks.enabled else '' }}"
|
||||||
- zram-generator
|
- "{{ 'qemu-guest-agent' if hypervisor_type in ['libvirt', 'proxmox'] else '' }}"
|
||||||
- zstd
|
- "{{ 'open-vm-tools' if hypervisor_type == 'vmware' else '' }}"
|
||||||
|
|
||||||
bootstrap_rocky:
|
|
||||||
- bind-utils
|
|
||||||
- dbus-daemon
|
|
||||||
- dhcp-client
|
|
||||||
- efibootmgr
|
|
||||||
- "{{ 'firewalld' if firewalld_enabled | bool else '' }}"
|
|
||||||
- glibc-langpack-de
|
|
||||||
- glibc-langpack-en
|
|
||||||
- grub2
|
|
||||||
- grub2-efi
|
|
||||||
- lrzsz
|
|
||||||
- lvm2
|
|
||||||
- mtr
|
|
||||||
- nc
|
|
||||||
- nfs-utils
|
|
||||||
- nfsv4-client-utils
|
|
||||||
- ppp
|
|
||||||
- shim
|
|
||||||
- telnet
|
|
||||||
- tmux
|
|
||||||
- "{{ 'cryptsetup' if luks_enabled else '' }}"
|
|
||||||
- "{{ 'tpm2-tools' if luks_enabled else '' }}"
|
|
||||||
- "{{ 'qemu-guest-agent' if hypervisor | lower in ['libvirt', 'proxmox'] else '' }}"
|
|
||||||
- "{{ 'open-vm-tools' if hypervisor | lower == 'vmware' else '' }}"
|
|
||||||
- util-linux-core
|
|
||||||
- vim
|
- vim
|
||||||
- wget
|
- wget
|
||||||
- zram-generator
|
|
||||||
- zstd
|
- zstd
|
||||||
|
|
||||||
|
bootstrap_debian_extra_versioned:
|
||||||
|
- linux-image-amd64
|
||||||
|
- "{{ 'duf' if (os_version | string) not in ['10', '11'] else '' }}"
|
||||||
|
- "{{ 'fastfetch' if (os_version | string) in ['12', '13', 'unstable'] else '' }}"
|
||||||
|
- "{{ 'neofetch' if (os_version | string) == '12' else '' }}"
|
||||||
|
- "{{ 'software-properties-common' if (os_version | string) not in ['13', 'unstable'] else '' }}"
|
||||||
|
- "{{ 'systemd-zram-generator' if (os_version | string) not in ['10', '11'] else '' }}"
|
||||||
|
- "{{ 'tldr' if (os_version | string) not in ['13', 'unstable'] else '' }}"
|
||||||
|
|
||||||
|
bootstrap_debian:
|
||||||
|
base: "{{ bootstrap_debian_base_common }}"
|
||||||
|
extra: "{{ bootstrap_debian_extra_common + bootstrap_debian_extra_versioned }}"
|
||||||
|
|
||||||
|
bootstrap_debian10: "{{ bootstrap_debian }}"
|
||||||
|
bootstrap_debian11: "{{ bootstrap_debian }}"
|
||||||
|
bootstrap_debian12: "{{ bootstrap_debian }}"
|
||||||
|
bootstrap_debian13: "{{ bootstrap_debian }}"
|
||||||
|
bootstrap_debianunstable: "{{ bootstrap_debian }}"
|
||||||
|
|
||||||
bootstrap_ubuntu:
|
bootstrap_ubuntu:
|
||||||
base:
|
base:
|
||||||
- btrfs-progs
|
|
||||||
- cron
|
|
||||||
- gnupg
|
|
||||||
- grub-efi
|
|
||||||
- grub-efi-amd64-signed
|
|
||||||
- grub2-common
|
|
||||||
- "{{ 'cryptsetup' if luks_enabled else '' }}"
|
|
||||||
- "{{ 'cryptsetup-initramfs' if luks_enabled else '' }}"
|
|
||||||
- linux-image-generic
|
- linux-image-generic
|
||||||
- locales
|
extra: >-
|
||||||
- lvm2
|
{{
|
||||||
- xfsprogs
|
bootstrap_debian_base_common
|
||||||
|
+ bootstrap_debian_extra_common
|
||||||
extra:
|
+ ['bash-completion', 'dnsutils', 'duf', 'eza', 'fdupes', 'fio', 'ncurses-term', 'software-properties-common', 'systemd-zram-generator', 'tldr', 'traceroute', 'util-linux-extra', 'yq', 'zoxide']
|
||||||
- apparmor-utils
|
}}
|
||||||
- bash-completion
|
|
||||||
- bat
|
|
||||||
- chrony
|
|
||||||
- curl
|
|
||||||
- dnsutils
|
|
||||||
- duf
|
|
||||||
- entr
|
|
||||||
- eza
|
|
||||||
- fdupes
|
|
||||||
- fio
|
|
||||||
- "{{ 'firewalld' if firewalld_enabled | bool else '' }}"
|
|
||||||
- fish
|
|
||||||
- htop
|
|
||||||
- jq
|
|
||||||
- libpam-pwquality
|
|
||||||
- logrotate
|
|
||||||
- lrzsz
|
|
||||||
- mtr
|
|
||||||
- ncdu
|
|
||||||
- ncurses-term
|
|
||||||
- net-tools
|
|
||||||
- network-manager
|
|
||||||
- "{{ 'openssh-server' if ssh_enabled | bool else '' }}"
|
|
||||||
- python-is-python3
|
|
||||||
- python3
|
|
||||||
- ripgrep
|
|
||||||
- rsync
|
|
||||||
- screen
|
|
||||||
- software-properties-common
|
|
||||||
- sudo
|
|
||||||
- syslog-ng
|
|
||||||
- systemd-zram-generator
|
|
||||||
- tcpd
|
|
||||||
- tldr
|
|
||||||
- tmux
|
|
||||||
- "{{ 'tpm2-tools' if luks_enabled else '' }}"
|
|
||||||
- "{{ 'qemu-guest-agent' if hypervisor | lower in ['libvirt', 'proxmox'] else '' }}"
|
|
||||||
- "{{ 'open-vm-tools' if hypervisor | lower == 'vmware' else '' }}"
|
|
||||||
- traceroute
|
|
||||||
- util-linux-extra
|
|
||||||
- vim
|
|
||||||
- wget
|
|
||||||
- yq
|
|
||||||
- zoxide
|
|
||||||
- zstd
|
|
||||||
|
|
||||||
bootstrap_ubuntu_lts:
|
bootstrap_ubuntu_lts:
|
||||||
base:
|
base:
|
||||||
- btrfs-progs
|
|
||||||
- cron
|
|
||||||
- gnupg
|
|
||||||
- grub-efi
|
|
||||||
- grub-efi-amd64-signed
|
|
||||||
- grub2-common
|
|
||||||
- "{{ 'cryptsetup' if luks_enabled else '' }}"
|
|
||||||
- "{{ 'cryptsetup-initramfs' if luks_enabled else '' }}"
|
|
||||||
- linux-image-generic
|
- linux-image-generic
|
||||||
- locales
|
extra: >-
|
||||||
- lvm2
|
{{
|
||||||
- xfsprogs
|
bootstrap_debian_base_common
|
||||||
|
+ bootstrap_debian_extra_common
|
||||||
|
+ ['bash-completion', 'dnsutils', 'duf', 'eza', 'fdupes', 'fio', 'ncurses-term', 'software-properties-common', 'systemd-zram-generator', 'tldr', 'traceroute', 'util-linux-extra', 'yq', 'zoxide']
|
||||||
|
}}
|
||||||
|
|
||||||
extra:
|
bootstrap_archlinux:
|
||||||
- apparmor-utils
|
- base
|
||||||
- bash-completion
|
- btrfs-progs
|
||||||
- bat
|
- cronie
|
||||||
- chrony
|
- dhcpcd
|
||||||
- curl
|
- efibootmgr
|
||||||
- dnsutils
|
- fastfetch
|
||||||
- duf
|
- "{{ 'firewalld' if system_cfg.features.firewall.backend == 'firewalld' and system_cfg.features.firewall.enabled | bool else '' }}"
|
||||||
- entr
|
- "{{ 'ufw' if system_cfg.features.firewall.backend == 'ufw' and system_cfg.features.firewall.enabled | bool else '' }}"
|
||||||
- eza
|
- "{{ 'iptables' if system_cfg.features.firewall.toolkit == 'iptables' else '' }}"
|
||||||
- fdupes
|
- "{{ 'iptables-nft' if system_cfg.features.firewall.toolkit == 'nftables' else '' }}"
|
||||||
- fio
|
|
||||||
- "{{ 'firewalld' if firewalld_enabled | bool else '' }}"
|
|
||||||
- fish
|
- fish
|
||||||
|
- fzf
|
||||||
|
- grub
|
||||||
- htop
|
- htop
|
||||||
- jq
|
- libpwquality
|
||||||
- libpam-pwquality
|
- linux
|
||||||
- logrotate
|
- logrotate
|
||||||
- lrzsz
|
- lrzsz
|
||||||
- mtr
|
- lsof
|
||||||
|
- lvm2
|
||||||
- ncdu
|
- ncdu
|
||||||
- ncurses-term
|
- networkmanager
|
||||||
- net-tools
|
- nfs-utils
|
||||||
- network-manager
|
- "{{ 'openssh' if system_cfg.features.ssh.enabled | bool else '' }}"
|
||||||
- "{{ 'openssh-server' if ssh_enabled | bool else '' }}"
|
- ppp
|
||||||
- python-is-python3
|
- prometheus-node-exporter
|
||||||
- python3
|
- python-psycopg2
|
||||||
- ripgrep
|
- reflector
|
||||||
- rsync
|
- rsync
|
||||||
- screen
|
|
||||||
- software-properties-common
|
|
||||||
- sudo
|
- sudo
|
||||||
- syslog-ng
|
|
||||||
- systemd-zram-generator
|
|
||||||
- tcpd
|
|
||||||
- tldr
|
- tldr
|
||||||
- tmux
|
- tmux
|
||||||
- "{{ 'tpm2-tools' if luks_enabled else '' }}"
|
- "{{ 'cryptsetup' if system_cfg.luks.enabled else '' }}"
|
||||||
- "{{ 'qemu-guest-agent' if hypervisor | lower in ['libvirt', 'proxmox'] else '' }}"
|
- "{{ 'tpm2-tools' if system_cfg.luks.enabled else '' }}"
|
||||||
- "{{ 'open-vm-tools' if hypervisor | lower == 'vmware' else '' }}"
|
- "{{ 'qemu-guest-agent' if hypervisor_type in ['libvirt', 'proxmox'] else '' }}"
|
||||||
- traceroute
|
- "{{ 'open-vm-tools' if hypervisor_type == 'vmware' else '' }}"
|
||||||
- util-linux-extra
|
|
||||||
- vim
|
- vim
|
||||||
- wget
|
- wireguard-tools
|
||||||
- yq
|
- zram-generator
|
||||||
- zoxide
|
|
||||||
- zstd
|
bootstrap_alpine:
|
||||||
|
- alpine-base
|
||||||
|
- vim
|
||||||
|
- "{{ 'openssh' if system_cfg.features.ssh.enabled | bool else '' }}"
|
||||||
|
- "{{ 'qemu-guest-agent' if hypervisor_type in ['libvirt', 'proxmox'] else '' }}"
|
||||||
|
- "{{ 'open-vm-tools' if hypervisor_type == 'vmware' else '' }}"
|
||||||
|
- "{{ 'firewalld' if system_cfg.features.firewall.backend == 'firewalld' and system_cfg.features.firewall.enabled | bool else '' }}"
|
||||||
|
- "{{ 'ufw' if system_cfg.features.firewall.backend == 'ufw' and system_cfg.features.firewall.enabled | bool else '' }}"
|
||||||
|
- "{{ 'iptables' if system_cfg.features.firewall.toolkit == 'iptables' else '' }}"
|
||||||
|
- "{{ 'nftables' if system_cfg.features.firewall.toolkit == 'nftables' else '' }}"
|
||||||
|
- "{{ 'cryptsetup' if system_cfg.luks.enabled else '' }}"
|
||||||
|
- "{{ 'tpm2-tools' if system_cfg.luks.enabled else '' }}"
|
||||||
|
|
||||||
|
bootstrap_opensuse:
|
||||||
|
- vim
|
||||||
|
- "{{ 'openssh' if system_cfg.features.ssh.enabled | bool else '' }}"
|
||||||
|
- "{{ 'qemu-guest-agent' if hypervisor_type in ['libvirt', 'proxmox'] else '' }}"
|
||||||
|
- "{{ 'open-vm-tools' if hypervisor_type == 'vmware' else '' }}"
|
||||||
|
- "{{ 'firewalld' if system_cfg.features.firewall.backend == 'firewalld' and system_cfg.features.firewall.enabled | bool else '' }}"
|
||||||
|
- "{{ 'ufw' if system_cfg.features.firewall.backend == 'ufw' and system_cfg.features.firewall.enabled | bool else '' }}"
|
||||||
|
- "{{ 'iptables' if system_cfg.features.firewall.toolkit == 'iptables' else '' }}"
|
||||||
|
- "{{ 'nftables' if system_cfg.features.firewall.toolkit == 'nftables' else '' }}"
|
||||||
|
- "{{ 'cryptsetup' if system_cfg.luks.enabled else '' }}"
|
||||||
|
- "{{ 'tpm2-tools' if system_cfg.luks.enabled else '' }}"
|
||||||
|
|
||||||
|
bootstrap_void:
|
||||||
|
- vim
|
||||||
|
- "{{ 'openssh' if system_cfg.features.ssh.enabled | bool else '' }}"
|
||||||
|
- "{{ 'qemu-guest-agent' if hypervisor_type in ['libvirt', 'proxmox'] else '' }}"
|
||||||
|
- "{{ 'open-vm-tools' if hypervisor_type == 'vmware' else '' }}"
|
||||||
|
- "{{ 'firewalld' if system_cfg.features.firewall.backend == 'firewalld' and system_cfg.features.firewall.enabled | bool else '' }}"
|
||||||
|
- "{{ 'ufw' if system_cfg.features.firewall.backend == 'ufw' and system_cfg.features.firewall.enabled | bool else '' }}"
|
||||||
|
- "{{ 'iptables' if system_cfg.features.firewall.toolkit == 'iptables' else '' }}"
|
||||||
|
- "{{ 'nftables' if system_cfg.features.firewall.toolkit == 'nftables' else '' }}"
|
||||||
|
- "{{ 'cryptsetup' if system_cfg.luks.enabled else '' }}"
|
||||||
|
- "{{ 'tpm2-tools' if system_cfg.luks.enabled else '' }}"
|
||||||
|
|||||||
@@ -10,12 +10,12 @@ cis_permission_targets: >-
|
|||||||
{ "path": "/mnt/etc/cron.d", "mode": "0700" },
|
{ "path": "/mnt/etc/cron.d", "mode": "0700" },
|
||||||
{ "path": "/mnt/etc/crontab", "mode": "0600" },
|
{ "path": "/mnt/etc/crontab", "mode": "0600" },
|
||||||
{ "path": "/mnt/etc/logrotate.conf", "mode": "0644" },
|
{ "path": "/mnt/etc/logrotate.conf", "mode": "0644" },
|
||||||
{ "path": "/mnt/usr/sbin/pppd", "mode": "0754" } if os not in ["rhel8", "rhel9", "rhel10"] else None,
|
{ "path": "/mnt/usr/sbin/pppd", "mode": "0754" } if os != "rhel" else None,
|
||||||
{
|
{
|
||||||
"path": "/mnt/usr/bin/"
|
"path": "/mnt/usr/bin/"
|
||||||
+ ("fusermount3" if os in ["archlinux", "debian12", "fedora", "rhel9", "rhel10", "rocky"] else "fusermount"),
|
+ ("fusermount3" if os in ["archlinux", "fedora", "rocky"] or os == "rhel" or (os == "debian" and (os_version | string) == "12") else "fusermount"),
|
||||||
"mode": "755"
|
"mode": "755"
|
||||||
},
|
},
|
||||||
{ "path": "/mnt/usr/bin/" + ("write.ul" if os == "debian11" else "write"), "mode": "755" }
|
{ "path": "/mnt/usr/bin/" + ("write.ul" if os == "debian" and (os_version | string) == "11" else "write"), "mode": "755" }
|
||||||
] | reject("none")
|
] | reject("none")
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
---
|
---
|
||||||
- name: Configure System Cryptography Policy
|
- name: Configure System Cryptography Policy
|
||||||
when: os in ["almalinux", "rhel9", "rhel10", "rocky"]
|
when: os == "rhel" or os in ["almalinux", "rocky"]
|
||||||
ansible.builtin.command: "{{ chroot_command }} /mnt /usr/bin/update-crypto-policies --set DEFAULT:NO-SHA1"
|
ansible.builtin.command: "{{ chroot_command }} /usr/bin/update-crypto-policies --set DEFAULT:NO-SHA1"
|
||||||
register: cis_crypto_policy_result
|
register: cis_crypto_policy_result
|
||||||
changed_when: "'Setting system-wide crypto-policies to' in cis_crypto_policy_result.stdout"
|
changed_when: "'Setting system-wide crypto-policies to' in cis_crypto_policy_result.stdout"
|
||||||
|
|
||||||
- name: Mask Systemd Services
|
- name: Mask Systemd Services
|
||||||
ansible.builtin.command: >
|
ansible.builtin.command: >
|
||||||
{{ chroot_command }} /mnt systemctl mask nftables bluetooth rpcbind
|
{{ chroot_command }} systemctl mask {{ 'nftables' if system_cfg.features.firewall.toolkit == 'iptables' else 'iptables' }} bluetooth rpcbind
|
||||||
register: cis_mask_services_result
|
register: cis_mask_services_result
|
||||||
changed_when: cis_mask_services_result.rc == 0
|
changed_when: cis_mask_services_result.rc == 0
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
install rds /bin/false
|
install rds /bin/false
|
||||||
install tipc /bin/false
|
install tipc /bin/false
|
||||||
|
|
||||||
- name: Remove legacy USB rules file
|
- name: Remove old USB rules file
|
||||||
ansible.builtin.file:
|
ansible.builtin.file:
|
||||||
path: /mnt/etc/udev/rules.d/10-cis_usb_devices.sh
|
path: /mnt/etc/udev/rules.d/10-cis_usb_devices.sh
|
||||||
state: absent
|
state: absent
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
- path: >-
|
- path: >-
|
||||||
/mnt/etc/{{
|
/mnt/etc/{{
|
||||||
"pam.d/common-auth"
|
"pam.d/common-auth"
|
||||||
if os in ["debian11", "debian12", "ubuntu", "ubuntu-lts"]
|
if is_debian | bool
|
||||||
else "authselect/system-auth"
|
else "authselect/system-auth"
|
||||||
if os == "fedora"
|
if os == "fedora"
|
||||||
else "pam.d/system-auth"
|
else "pam.d/system-auth"
|
||||||
@@ -28,7 +28,7 @@
|
|||||||
- path: >-
|
- path: >-
|
||||||
/mnt/etc/{{
|
/mnt/etc/{{
|
||||||
"pam.d/common-account"
|
"pam.d/common-account"
|
||||||
if os in ["debian11", "debian12", "ubuntu", "ubuntu-lts"]
|
if is_debian | bool
|
||||||
else "authselect/system-auth"
|
else "authselect/system-auth"
|
||||||
if os == "fedora"
|
if os == "fedora"
|
||||||
else "pam.d/system-auth"
|
else "pam.d/system-auth"
|
||||||
@@ -37,7 +37,7 @@
|
|||||||
- path: >-
|
- path: >-
|
||||||
/mnt/etc/pam.d/{{
|
/mnt/etc/pam.d/{{
|
||||||
"common-password"
|
"common-password"
|
||||||
if os in ["debian11", "debian12", "ubuntu", "ubuntu-lts"]
|
if is_debian | bool
|
||||||
else "passwd"
|
else "passwd"
|
||||||
}}
|
}}
|
||||||
content: >-
|
content: >-
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
---
|
---
|
||||||
cleanup_libvirt_image_dir: >-
|
cleanup_libvirt_image_dir: >-
|
||||||
{{ vm_path if vm_path is defined and vm_path | length > 0 else '/var/lib/libvirt/images' }}
|
{{
|
||||||
|
system_cfg.path
|
||||||
|
if system_cfg is defined and (system_cfg.path | string | length) > 0
|
||||||
|
else '/var/lib/libvirt/images'
|
||||||
|
}}
|
||||||
cleanup_libvirt_cloudinit_path: >-
|
cleanup_libvirt_cloudinit_path: >-
|
||||||
{{ [cleanup_libvirt_image_dir, hostname ~ '-cloudinit.iso'] | ansible.builtin.path_join }}
|
{{ [cleanup_libvirt_image_dir, hostname ~ '-cloudinit.iso'] | ansible.builtin.path_join }}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
- name: Remove Archiso and cloud-init disks
|
- name: Remove Archiso and cloud-init disks
|
||||||
when: hypervisor == "libvirt"
|
when: hypervisor_type == "libvirt"
|
||||||
delegate_to: localhost
|
delegate_to: localhost
|
||||||
become: false
|
become: false
|
||||||
block:
|
block:
|
||||||
@@ -102,3 +102,5 @@
|
|||||||
delegate_to: "{{ inventory_hostname }}"
|
delegate_to: "{{ inventory_hostname }}"
|
||||||
ansible.builtin.wait_for_connection:
|
ansible.builtin.wait_for_connection:
|
||||||
timeout: 300
|
timeout: 300
|
||||||
|
failed_when: false
|
||||||
|
changed_when: false
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
---
|
---
|
||||||
- name: Cleanup physical install
|
- name: Cleanup physical install
|
||||||
when: install_type == "physical"
|
when: system_cfg.type == "physical"
|
||||||
ansible.builtin.include_tasks: physical.yml
|
ansible.builtin.include_tasks: physical.yml
|
||||||
|
|
||||||
- name: Cleanup virtual install
|
- name: Cleanup virtual install
|
||||||
when: install_type == "virtual"
|
when: system_cfg.type == "virtual"
|
||||||
ansible.builtin.include_tasks: virtual.yml
|
ansible.builtin.include_tasks: virtual.yml
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
---
|
---
|
||||||
- name: Setup Cleanup
|
- name: Setup Cleanup
|
||||||
when: hypervisor == "proxmox"
|
when: hypervisor_type == "proxmox"
|
||||||
delegate_to: localhost
|
delegate_to: localhost
|
||||||
become: false
|
become: false
|
||||||
block:
|
block:
|
||||||
- name: Cleanup Setup Disks
|
- name: Cleanup Setup Disks
|
||||||
community.proxmox.proxmox_disk:
|
community.proxmox.proxmox_disk:
|
||||||
api_host: "{{ hypervisor_url }}"
|
api_host: "{{ hypervisor_cfg.url }}"
|
||||||
api_user: "{{ hypervisor_username }}"
|
api_user: "{{ hypervisor_cfg.username }}"
|
||||||
api_password: "{{ hypervisor_password }}"
|
api_password: "{{ hypervisor_cfg.password }}"
|
||||||
name: "{{ hostname }}"
|
name: "{{ hostname }}"
|
||||||
vmid: "{{ vm_id }}"
|
vmid: "{{ system_cfg.id }}"
|
||||||
disk: "{{ item }}"
|
disk: "{{ item }}"
|
||||||
state: absent
|
state: absent
|
||||||
loop:
|
loop:
|
||||||
@@ -19,9 +19,9 @@
|
|||||||
|
|
||||||
- name: Start the VM
|
- name: Start the VM
|
||||||
community.proxmox.proxmox_kvm:
|
community.proxmox.proxmox_kvm:
|
||||||
api_host: "{{ hypervisor_url }}"
|
api_host: "{{ hypervisor_cfg.url }}"
|
||||||
api_user: "{{ hypervisor_username }}"
|
api_user: "{{ hypervisor_cfg.username }}"
|
||||||
api_password: "{{ hypervisor_password }}"
|
api_password: "{{ hypervisor_cfg.password }}"
|
||||||
node: "{{ hypervisor_node }}"
|
node: "{{ hypervisor_cfg.host }}"
|
||||||
vmid: "{{ vm_id }}"
|
vmid: "{{ system_cfg.id }}"
|
||||||
state: restarted
|
state: restarted
|
||||||
|
|||||||
@@ -13,3 +13,196 @@
|
|||||||
|
|
||||||
- name: Cleanup libvirt resources
|
- name: Cleanup libvirt resources
|
||||||
ansible.builtin.include_tasks: libvirt.yml
|
ansible.builtin.include_tasks: libvirt.yml
|
||||||
|
|
||||||
|
- name: Cleanup Xen resources
|
||||||
|
ansible.builtin.include_tasks: xen.yml
|
||||||
|
|
||||||
|
- name: Determine post-reboot connectivity
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
cleanup_post_reboot_can_connect: >-
|
||||||
|
{{
|
||||||
|
(
|
||||||
|
post_reboot_can_connect
|
||||||
|
if post_reboot_can_connect is defined
|
||||||
|
else (
|
||||||
|
(ansible_connection | default('ssh')) != 'ssh'
|
||||||
|
or ((system_cfg.ip | default('') | string | length) > 0)
|
||||||
|
or (
|
||||||
|
system_cfg.type == 'physical'
|
||||||
|
and (ansible_host | default('') | string | length) > 0
|
||||||
|
)
|
||||||
|
)
|
||||||
|
) | bool
|
||||||
|
}}
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: Check VM accessibility after reboot
|
||||||
|
when:
|
||||||
|
- system_cfg.type == "virtual"
|
||||||
|
- cleanup_post_reboot_can_connect | bool
|
||||||
|
block:
|
||||||
|
- name: Attempt to connect to VM
|
||||||
|
delegate_to: "{{ inventory_hostname }}"
|
||||||
|
ansible.builtin.wait_for_connection:
|
||||||
|
timeout: 300
|
||||||
|
register: cleanup_vm_connection_check
|
||||||
|
failed_when: false
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: VM failed to boot - initiate cleanup
|
||||||
|
when:
|
||||||
|
- cleanup_vm_connection_check is defined
|
||||||
|
- cleanup_vm_connection_check.failed | bool
|
||||||
|
block:
|
||||||
|
- name: VM boot failure detected - removing VM
|
||||||
|
ansible.builtin.debug:
|
||||||
|
msg: |
|
||||||
|
VM {{ hostname }} failed to boot after provisioning.
|
||||||
|
This VM was created in the current playbook run and will be removed
|
||||||
|
to prevent orphaned resources.
|
||||||
|
|
||||||
|
- name: Remove VM for libvirt
|
||||||
|
when:
|
||||||
|
- hypervisor_type == "libvirt"
|
||||||
|
- virtualization_vm_created_in_run | default(false) | bool
|
||||||
|
delegate_to: localhost
|
||||||
|
become: false
|
||||||
|
community.libvirt.virt:
|
||||||
|
name: "{{ hostname }}"
|
||||||
|
state: destroyed
|
||||||
|
|
||||||
|
- name: Undefine VM for libvirt
|
||||||
|
when:
|
||||||
|
- hypervisor_type == "libvirt"
|
||||||
|
- virtualization_vm_created_in_run | default(false) | bool
|
||||||
|
delegate_to: localhost
|
||||||
|
become: false
|
||||||
|
community.libvirt.virt:
|
||||||
|
name: "{{ hostname }}"
|
||||||
|
command: undefine
|
||||||
|
|
||||||
|
- name: Remove VM disk for libvirt
|
||||||
|
when:
|
||||||
|
- hypervisor_type == "libvirt"
|
||||||
|
- virtualization_vm_created_in_run | default(false) | bool
|
||||||
|
delegate_to: localhost
|
||||||
|
become: false
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ item.path }}"
|
||||||
|
state: absent
|
||||||
|
loop: "{{ virtualization_libvirt_disks | default([]) }}"
|
||||||
|
loop_control:
|
||||||
|
label: "{{ item.path }}"
|
||||||
|
|
||||||
|
- name: Remove cloud-init disk for libvirt
|
||||||
|
when:
|
||||||
|
- hypervisor_type == "libvirt"
|
||||||
|
- virtualization_vm_created_in_run | default(false) | bool
|
||||||
|
delegate_to: localhost
|
||||||
|
become: false
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ virtualization_libvirt_cloudinit_path }}"
|
||||||
|
state: absent
|
||||||
|
|
||||||
|
- name: Remove VM for proxmox
|
||||||
|
when:
|
||||||
|
- hypervisor_type == "proxmox"
|
||||||
|
- virtualization_vm_created_in_run | default(false) | bool
|
||||||
|
delegate_to: localhost
|
||||||
|
become: false
|
||||||
|
community.proxmox.proxmox_kvm:
|
||||||
|
api_host: "{{ hypervisor_cfg.url }}"
|
||||||
|
api_user: "{{ hypervisor_cfg.username }}"
|
||||||
|
api_password: "{{ hypervisor_cfg.password }}"
|
||||||
|
node: "{{ hypervisor_cfg.host }}"
|
||||||
|
name: "{{ hostname }}"
|
||||||
|
vmid: "{{ system_cfg.id }}"
|
||||||
|
state: stopped
|
||||||
|
|
||||||
|
- name: Delete VM for proxmox
|
||||||
|
when:
|
||||||
|
- hypervisor_type == "proxmox"
|
||||||
|
- virtualization_vm_created_in_run | default(false) | bool
|
||||||
|
delegate_to: localhost
|
||||||
|
become: false
|
||||||
|
community.proxmox.proxmox_kvm:
|
||||||
|
api_host: "{{ hypervisor_cfg.url }}"
|
||||||
|
api_user: "{{ hypervisor_cfg.username }}"
|
||||||
|
api_password: "{{ hypervisor_cfg.password }}"
|
||||||
|
node: "{{ hypervisor_cfg.host }}"
|
||||||
|
name: "{{ hostname }}"
|
||||||
|
vmid: "{{ system_cfg.id }}"
|
||||||
|
state: absent
|
||||||
|
unprivileged: false
|
||||||
|
|
||||||
|
- name: Remove VM for VMware
|
||||||
|
when:
|
||||||
|
- hypervisor_type == "vmware"
|
||||||
|
- virtualization_vm_created_in_run | default(false) | bool
|
||||||
|
delegate_to: localhost
|
||||||
|
become: false
|
||||||
|
community.vmware.vmware_guest:
|
||||||
|
hostname: "{{ hypervisor_cfg.url }}"
|
||||||
|
username: "{{ hypervisor_cfg.username }}"
|
||||||
|
password: "{{ hypervisor_cfg.password }}"
|
||||||
|
validate_certs: "{{ hypervisor_cfg.certs | bool }}"
|
||||||
|
name: "{{ hostname }}"
|
||||||
|
folder: "{{ system_cfg.path | default('/') }}"
|
||||||
|
state: poweredoff
|
||||||
|
|
||||||
|
- name: Delete VM for VMware
|
||||||
|
when:
|
||||||
|
- hypervisor_type == "vmware"
|
||||||
|
- virtualization_vm_created_in_run | default(false) | bool
|
||||||
|
delegate_to: localhost
|
||||||
|
become: false
|
||||||
|
community.vmware.vmware_guest:
|
||||||
|
hostname: "{{ hypervisor_cfg.url }}"
|
||||||
|
username: "{{ hypervisor_cfg.username }}"
|
||||||
|
password: "{{ hypervisor_cfg.password }}"
|
||||||
|
validate_certs: "{{ hypervisor_cfg.certs | bool }}"
|
||||||
|
name: "{{ hostname }}"
|
||||||
|
folder: "{{ system_cfg.path | default('/') }}"
|
||||||
|
state: absent
|
||||||
|
|
||||||
|
- name: Destroy Xen VM if running
|
||||||
|
when:
|
||||||
|
- hypervisor_type == "xen"
|
||||||
|
- virtualization_vm_created_in_run | default(false) | bool
|
||||||
|
delegate_to: localhost
|
||||||
|
become: false
|
||||||
|
ansible.builtin.command:
|
||||||
|
argv:
|
||||||
|
- xl
|
||||||
|
- destroy
|
||||||
|
- "{{ hostname }}"
|
||||||
|
register: cleanup_xen_destroy
|
||||||
|
failed_when: false
|
||||||
|
changed_when: cleanup_xen_destroy.rc == 0
|
||||||
|
|
||||||
|
- name: Remove Xen VM disk
|
||||||
|
when:
|
||||||
|
- hypervisor_type == "xen"
|
||||||
|
- virtualization_vm_created_in_run | default(false) | bool
|
||||||
|
delegate_to: localhost
|
||||||
|
become: false
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ item.path }}"
|
||||||
|
state: absent
|
||||||
|
loop: "{{ virtualization_xen_disks | default([]) }}"
|
||||||
|
loop_control:
|
||||||
|
label: "{{ item.path }}"
|
||||||
|
|
||||||
|
- name: Remove Xen VM config file
|
||||||
|
when:
|
||||||
|
- hypervisor_type == "xen"
|
||||||
|
- virtualization_vm_created_in_run | default(false) | bool
|
||||||
|
delegate_to: localhost
|
||||||
|
become: false
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "/tmp/xen-{{ hostname }}.cfg"
|
||||||
|
state: absent
|
||||||
|
|
||||||
|
- name: VM cleanup completed
|
||||||
|
ansible.builtin.debug:
|
||||||
|
msg: VM {{ hostname }} has been successfully removed due to boot failure.
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
---
|
---
|
||||||
- name: Clean vCenter VM
|
- name: Clean vCenter VM
|
||||||
when: hypervisor == "vmware"
|
when: hypervisor_type == "vmware"
|
||||||
delegate_to: localhost
|
delegate_to: localhost
|
||||||
become: false
|
become: false
|
||||||
block:
|
block:
|
||||||
- name: Remove CD-ROM from VM in vCenter
|
- name: Remove CD-ROM from VM in vCenter
|
||||||
when: hypervisor == "vmware"
|
when: hypervisor_type == "vmware"
|
||||||
community.vmware.vmware_guest:
|
community.vmware.vmware_guest:
|
||||||
hostname: "{{ hypervisor_url }}"
|
hostname: "{{ hypervisor_cfg.url }}"
|
||||||
username: "{{ hypervisor_username }}"
|
username: "{{ hypervisor_cfg.username }}"
|
||||||
password: "{{ hypervisor_password }}"
|
password: "{{ hypervisor_cfg.password }}"
|
||||||
validate_certs: false
|
validate_certs: "{{ hypervisor_cfg.certs | bool }}"
|
||||||
datacenter: "{{ hypervisor_datacenter }}"
|
datacenter: "{{ hypervisor_cfg.datacenter }}"
|
||||||
name: "{{ hostname }}"
|
name: "{{ hostname }}"
|
||||||
cdrom:
|
cdrom:
|
||||||
- controller_number: 0
|
- controller_number: 0
|
||||||
@@ -29,12 +29,12 @@
|
|||||||
failed_when: false
|
failed_when: false
|
||||||
|
|
||||||
- name: Start VM in vCenter
|
- name: Start VM in vCenter
|
||||||
when: hypervisor == "vmware"
|
when: hypervisor_type == "vmware"
|
||||||
vmware.vmware.vm_powerstate:
|
vmware.vmware.vm_powerstate:
|
||||||
hostname: "{{ hypervisor_url }}"
|
hostname: "{{ hypervisor_cfg.url }}"
|
||||||
username: "{{ hypervisor_username }}"
|
username: "{{ hypervisor_cfg.username }}"
|
||||||
password: "{{ hypervisor_password }}"
|
password: "{{ hypervisor_cfg.password }}"
|
||||||
validate_certs: false
|
validate_certs: "{{ hypervisor_cfg.certs | bool }}"
|
||||||
datacenter: "{{ hypervisor_datacenter }}"
|
datacenter: "{{ hypervisor_cfg.datacenter }}"
|
||||||
name: "{{ hostname }}"
|
name: "{{ hostname }}"
|
||||||
state: powered-on
|
state: powered-on
|
||||||
|
|||||||
58
roles/cleanup/tasks/xen.yml
Normal file
58
roles/cleanup/tasks/xen.yml
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
---
|
||||||
|
- name: Cleanup Xen installer media
|
||||||
|
when: hypervisor_type == "xen"
|
||||||
|
delegate_to: localhost
|
||||||
|
become: false
|
||||||
|
block:
|
||||||
|
- name: Ensure Xen disk definitions exist
|
||||||
|
when: virtualization_xen_disks is not defined
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
cleanup_xen_disks: "{{ cleanup_xen_disks | default([]) + [cleanup_xen_disk_cfg] }}"
|
||||||
|
vars:
|
||||||
|
device_letter_map: "abcdefghijklmnopqrstuvwxyz"
|
||||||
|
device_letter: "{{ device_letter_map[ansible_loop.index0] }}"
|
||||||
|
cleanup_xen_disk_cfg: >-
|
||||||
|
{{
|
||||||
|
{
|
||||||
|
'path': (
|
||||||
|
virtualization_xen_disk_path ~ '/' ~ hostname ~ '.qcow2'
|
||||||
|
if ansible_loop.index0 == 0
|
||||||
|
else virtualization_xen_disk_path ~ '/' ~ hostname ~ '-disk' ~ ansible_loop.index0 ~ '.qcow2'
|
||||||
|
),
|
||||||
|
'target': 'xvd' ~ device_letter,
|
||||||
|
'size': (item.size | float)
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
loop: "{{ system_cfg.disks }}"
|
||||||
|
loop_control:
|
||||||
|
label: "{{ item | to_json }}"
|
||||||
|
extended: true
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: Render Xen VM configuration without installer media
|
||||||
|
vars:
|
||||||
|
xen_installer_media_enabled: false
|
||||||
|
virtualization_xen_disks: "{{ virtualization_xen_disks | default(cleanup_xen_disks | default([])) }}"
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: xen.cfg.j2
|
||||||
|
dest: /tmp/xen-{{ hostname }}.cfg
|
||||||
|
mode: "0644"
|
||||||
|
|
||||||
|
- name: Destroy Xen VM if running
|
||||||
|
ansible.builtin.command:
|
||||||
|
argv:
|
||||||
|
- xl
|
||||||
|
- destroy
|
||||||
|
- "{{ hostname }}"
|
||||||
|
register: cleanup_xen_destroy
|
||||||
|
failed_when: false
|
||||||
|
changed_when: cleanup_xen_destroy.rc == 0
|
||||||
|
|
||||||
|
- name: Start Xen VM without installer media
|
||||||
|
ansible.builtin.command:
|
||||||
|
argv:
|
||||||
|
- xl
|
||||||
|
- create
|
||||||
|
- /tmp/xen-{{ hostname }}.cfg
|
||||||
|
register: cleanup_xen_start_result
|
||||||
|
changed_when: cleanup_xen_start_result.rc == 0
|
||||||
5
roles/configuration/defaults/main.yml
Normal file
5
roles/configuration/defaults/main.yml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
configuration_motd_enabled: "{{ system_cfg.features.banner.motd | bool }}"
|
||||||
|
configuration_sudo_banner_enabled: "{{ system_cfg.features.banner.sudo | bool }}"
|
||||||
|
configuration_firewall_enabled: "{{ system_cfg.features.firewall.enabled | bool }}"
|
||||||
|
configuration_luks_enabled: "{{ system_cfg.luks.enabled | bool }}"
|
||||||
55
roles/configuration/tasks/banner.yml
Normal file
55
roles/configuration/tasks/banner.yml
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
---
|
||||||
|
- name: Configure MOTD
|
||||||
|
when: configuration_motd_enabled | bool
|
||||||
|
block:
|
||||||
|
- name: Create MOTD file
|
||||||
|
ansible.builtin.copy:
|
||||||
|
content: |
|
||||||
|
********************************************************************
|
||||||
|
* AUTHORIZED ACCESS ONLY. ALL ACTIVITIES ARE MONITORED AND LOGGED. *
|
||||||
|
********************************************************************
|
||||||
|
dest: /mnt/etc/motd
|
||||||
|
mode: "0644"
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
|
||||||
|
- name: Remove other MOTD files
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ item }}"
|
||||||
|
state: absent
|
||||||
|
loop:
|
||||||
|
- /mnt/etc/motd.d/99-motd
|
||||||
|
- /mnt/etc/motd.d/cockpit
|
||||||
|
- /mnt/etc/motd.d/insights-client
|
||||||
|
failed_when: false
|
||||||
|
|
||||||
|
- name: Configure sudo banner
|
||||||
|
when: configuration_sudo_banner_enabled | bool
|
||||||
|
block:
|
||||||
|
- name: Create sudoers banner directory
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: /mnt/etc/sudoers.d
|
||||||
|
state: directory
|
||||||
|
mode: "0755"
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
|
||||||
|
- name: Create sudo banner file
|
||||||
|
ansible.builtin.copy:
|
||||||
|
content: |
|
||||||
|
I am Groot, and I know what I'm doing.
|
||||||
|
dest: /mnt/etc/sudoers.d/banner
|
||||||
|
mode: "0644"
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
|
||||||
|
- name: Enable sudo banner in sudoers
|
||||||
|
ansible.builtin.lineinfile:
|
||||||
|
path: /mnt/etc/sudoers
|
||||||
|
line: "Defaults lecture=@/etc/sudoers.d/banner"
|
||||||
|
state: present
|
||||||
|
create: true
|
||||||
|
mode: "0440"
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
validate: "visudo -cf - %s"
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
configuration_bootloader_id: >-
|
configuration_bootloader_id: >-
|
||||||
{{ "ubuntu" if os | lower in ["ubuntu", "ubuntu-lts"] else os }}
|
{{ "ubuntu" if os | lower in ["ubuntu", "ubuntu-lts"] else os }}
|
||||||
configuration_efi_vendor: >-
|
configuration_efi_vendor: >-
|
||||||
{{ "redhat" if os | lower in ["rhel8", "rhel9", "rhel10"] else os | lower }}
|
{{ "redhat" if os | lower == "rhel" else os | lower }}
|
||||||
configuration_efibootmgr_cmd: >-
|
configuration_efibootmgr_cmd: >-
|
||||||
/usr/sbin/efibootmgr -c -L '{{ os }}' -d "{{ install_drive }}" -p 1
|
/usr/sbin/efibootmgr -c -L '{{ os }}' -d "{{ install_drive }}" -p 1
|
||||||
-l '\efi\EFI\{{ configuration_efi_vendor }}\shimx64.efi'
|
-l '\efi\EFI\{{ configuration_efi_vendor }}\shimx64.efi'
|
||||||
@@ -18,19 +18,20 @@
|
|||||||
--bootloader-id={{ configuration_bootloader_id }}
|
--bootloader-id={{ configuration_bootloader_id }}
|
||||||
configuration_bootloader_cmd: >-
|
configuration_bootloader_cmd: >-
|
||||||
{{ configuration_efibootmgr_cmd if configuration_use_efibootmgr else configuration_grub_cmd }}
|
{{ configuration_efibootmgr_cmd if configuration_use_efibootmgr else configuration_grub_cmd }}
|
||||||
ansible.builtin.command: "{{ chroot_command }} /mnt {{ configuration_bootloader_cmd }}"
|
ansible.builtin.command: "{{ chroot_command }} {{ configuration_bootloader_cmd }}"
|
||||||
register: configuration_bootloader_result
|
register: configuration_bootloader_result
|
||||||
changed_when: configuration_bootloader_result.rc == 0
|
changed_when: configuration_bootloader_result.rc == 0
|
||||||
|
|
||||||
- name: Ensure lvm2 for non btrfs filesystems
|
- name: Ensure lvm2 for non btrfs filesystems
|
||||||
when: os | lower == "archlinux" and filesystem != "btrfs"
|
when: os | lower == "archlinux" and system_cfg.filesystem != "btrfs"
|
||||||
ansible.builtin.lineinfile:
|
ansible.builtin.lineinfile:
|
||||||
path: /mnt/etc/mkinitcpio.conf
|
path: /mnt/etc/mkinitcpio.conf
|
||||||
regexp: "^(HOOKS=.*block)(?!.*lvm2)(.*)"
|
regexp: "^(HOOKS=.*block)(?!.*lvm2)(.*)"
|
||||||
line: '\1 lvm2\2'
|
line: "\\1 lvm2\\2"
|
||||||
backrefs: true
|
backrefs: true
|
||||||
|
|
||||||
- name: Regenerate initramfs
|
- name: Regenerate initramfs
|
||||||
|
when: os | lower not in ["alpine", "void"]
|
||||||
vars:
|
vars:
|
||||||
configuration_initramfs_cmd: >-
|
configuration_initramfs_cmd: >-
|
||||||
{{
|
{{
|
||||||
@@ -43,14 +44,14 @@
|
|||||||
else '/usr/bin/dracut --regenerate-all --force'
|
else '/usr/bin/dracut --regenerate-all --force'
|
||||||
)
|
)
|
||||||
}}
|
}}
|
||||||
ansible.builtin.command: "{{ chroot_command }} /mnt {{ configuration_initramfs_cmd }}"
|
ansible.builtin.command: "{{ chroot_command }} {{ configuration_initramfs_cmd }}"
|
||||||
register: configuration_initramfs_result
|
register: configuration_initramfs_result
|
||||||
changed_when: configuration_initramfs_result.rc == 0
|
changed_when: configuration_initramfs_result.rc == 0
|
||||||
|
|
||||||
- name: Generate grub config
|
- name: Generate grub config
|
||||||
vars:
|
vars:
|
||||||
configuration_efi_vendor: >-
|
configuration_efi_vendor: >-
|
||||||
{{ "redhat" if os | lower in ["rhel8", "rhel9", "rhel10"] else os | lower }}
|
{{ "redhat" if os | lower == "rhel" else os | lower }}
|
||||||
configuration_grub_cfg_cmd: >-
|
configuration_grub_cfg_cmd: >-
|
||||||
{{
|
{{
|
||||||
'/usr/sbin/grub2-mkconfig -o '
|
'/usr/sbin/grub2-mkconfig -o '
|
||||||
@@ -59,6 +60,6 @@
|
|||||||
if is_rhel | bool
|
if is_rhel | bool
|
||||||
else '/usr/sbin/grub-mkconfig -o /boot/grub/grub.cfg'
|
else '/usr/sbin/grub-mkconfig -o /boot/grub/grub.cfg'
|
||||||
}}
|
}}
|
||||||
ansible.builtin.command: "{{ chroot_command }} /mnt {{ configuration_grub_cfg_cmd }}"
|
ansible.builtin.command: "{{ chroot_command }} {{ configuration_grub_cfg_cmd }}"
|
||||||
register: configuration_grub_result
|
register: configuration_grub_result
|
||||||
changed_when: configuration_grub_result.rc == 0
|
changed_when: configuration_grub_result.rc == 0
|
||||||
|
|||||||
@@ -2,22 +2,17 @@
|
|||||||
- name: Configure disk encryption
|
- name: Configure disk encryption
|
||||||
when: partitioning_luks_enabled | bool
|
when: partitioning_luks_enabled | bool
|
||||||
vars:
|
vars:
|
||||||
configuration_luks_passphrase_effective: >-
|
configuration_luks_passphrase: >-
|
||||||
{{ partitioning_luks_passphrase | string }}
|
{{ partitioning_luks_passphrase | string }}
|
||||||
block:
|
block:
|
||||||
- name: Set LUKS configuration facts
|
- name: Set LUKS configuration facts
|
||||||
vars:
|
vars:
|
||||||
configuration_luks_mapper_name_value: >-
|
luks_tpm2_pcrs: >-
|
||||||
{{ partitioning_luks_mapper_name }}
|
|
||||||
configuration_luks_device_value: "{{ partitioning_luks_device }}"
|
|
||||||
configuration_luks_tpm2_pcrs_raw: >-
|
|
||||||
{{ partitioning_luks_tpm2_pcrs }}
|
|
||||||
configuration_luks_tpm2_pcrs_effective_value: >-
|
|
||||||
{{
|
{{
|
||||||
(
|
(
|
||||||
configuration_luks_tpm2_pcrs_raw
|
partitioning_luks_tpm2_pcrs
|
||||||
if configuration_luks_tpm2_pcrs_raw is string
|
if partitioning_luks_tpm2_pcrs is string
|
||||||
else (configuration_luks_tpm2_pcrs_raw | map('string') | join('+'))
|
else (partitioning_luks_tpm2_pcrs | map('string') | join('+'))
|
||||||
)
|
)
|
||||||
| string
|
| string
|
||||||
| replace(',', '+')
|
| replace(',', '+')
|
||||||
@@ -25,11 +20,10 @@
|
|||||||
| regex_replace('^\\+|\\+$', '')
|
| regex_replace('^\\+|\\+$', '')
|
||||||
}}
|
}}
|
||||||
ansible.builtin.set_fact:
|
ansible.builtin.set_fact:
|
||||||
configuration_luks_mapper_name: "{{ configuration_luks_mapper_name_value }}"
|
configuration_luks_mapper_name: "{{ partitioning_luks_mapper_name }}"
|
||||||
configuration_luks_uuid: "{{ partitioning_luks_uuid | default('') }}"
|
configuration_luks_uuid: "{{ partitioning_luks_uuid | default('') }}"
|
||||||
configuration_luks_device: "{{ configuration_luks_device_value }}"
|
configuration_luks_device: "{{ partitioning_luks_device }}"
|
||||||
configuration_luks_options: >-
|
configuration_luks_options: "{{ partitioning_luks_options }}"
|
||||||
{{ partitioning_luks_options }}
|
|
||||||
configuration_luks_auto_method: >-
|
configuration_luks_auto_method: >-
|
||||||
{{
|
{{
|
||||||
(partitioning_luks_auto_decrypt | bool)
|
(partitioning_luks_auto_decrypt | bool)
|
||||||
@@ -38,12 +32,9 @@
|
|||||||
'manual'
|
'manual'
|
||||||
)
|
)
|
||||||
}}
|
}}
|
||||||
configuration_luks_tpm2_device: >-
|
configuration_luks_tpm2_device: "{{ partitioning_luks_tpm2_device }}"
|
||||||
{{ partitioning_luks_tpm2_device }}
|
configuration_luks_tpm2_pcrs: "{{ luks_tpm2_pcrs }}"
|
||||||
configuration_luks_tpm2_pcrs: "{{ configuration_luks_tpm2_pcrs_raw }}"
|
configuration_luks_keyfile_path: "/etc/cryptsetup-keys.d/{{ partitioning_luks_mapper_name }}.key"
|
||||||
configuration_luks_tpm2_pcrs_effective: "{{ configuration_luks_tpm2_pcrs_effective_value }}"
|
|
||||||
configuration_luks_keyfile_path: >-
|
|
||||||
/etc/cryptsetup-keys.d/{{ configuration_luks_mapper_name_value }}.key
|
|
||||||
changed_when: false
|
changed_when: false
|
||||||
|
|
||||||
- name: Validate LUKS UUID is available
|
- name: Validate LUKS UUID is available
|
||||||
@@ -56,8 +47,8 @@
|
|||||||
when: configuration_luks_auto_method in ['tpm2', 'keyfile']
|
when: configuration_luks_auto_method in ['tpm2', 'keyfile']
|
||||||
ansible.builtin.assert:
|
ansible.builtin.assert:
|
||||||
that:
|
that:
|
||||||
- configuration_luks_passphrase_effective | length > 0
|
- configuration_luks_passphrase | length > 0
|
||||||
fail_msg: luks_passphrase (or partitioning_luks_passphrase) must be set for LUKS auto-decrypt.
|
fail_msg: system.luks.passphrase must be set for LUKS auto-decrypt.
|
||||||
no_log: true
|
no_log: true
|
||||||
|
|
||||||
- name: Enroll TPM2 for LUKS
|
- name: Enroll TPM2 for LUKS
|
||||||
@@ -70,54 +61,52 @@
|
|||||||
|
|
||||||
- name: Build LUKS parameters
|
- name: Build LUKS parameters
|
||||||
vars:
|
vars:
|
||||||
configuration_luks_keyfile_in_use_value: "{{ configuration_luks_auto_method == 'keyfile' }}"
|
luks_keyfile_in_use: "{{ configuration_luks_auto_method == 'keyfile' }}"
|
||||||
configuration_luks_option_list_value: >-
|
luks_option_list: >-
|
||||||
{{
|
{{
|
||||||
(configuration_luks_options | trim).split(',')
|
(configuration_luks_options | trim).split(',')
|
||||||
if configuration_luks_options | trim | length > 0
|
if configuration_luks_options | trim | length > 0
|
||||||
else []
|
else []
|
||||||
}}
|
}}
|
||||||
configuration_luks_tpm2_option_list_value: >-
|
luks_tpm2_option_list: >-
|
||||||
{{
|
{{
|
||||||
(configuration_luks_auto_method == 'tpm2')
|
(configuration_luks_auto_method == 'tpm2')
|
||||||
| ternary(
|
| ternary(
|
||||||
['tpm2-device=' + configuration_luks_tpm2_device]
|
['tpm2-device=' + configuration_luks_tpm2_device]
|
||||||
+ (['tpm2-pcrs=' + configuration_luks_tpm2_pcrs_effective]
|
+ (['tpm2-pcrs=' + configuration_luks_tpm2_pcrs]
|
||||||
if configuration_luks_tpm2_pcrs_effective | length > 0 else []),
|
if configuration_luks_tpm2_pcrs | length > 0 else []),
|
||||||
[]
|
[]
|
||||||
)
|
)
|
||||||
}}
|
}}
|
||||||
configuration_luks_crypttab_keyfile_value: >-
|
luks_crypttab_keyfile: "{{ configuration_luks_keyfile_path if luks_keyfile_in_use else 'none' }}"
|
||||||
{{ configuration_luks_keyfile_path if configuration_luks_keyfile_in_use_value else 'none' }}
|
luks_crypttab_options: >-
|
||||||
configuration_luks_crypttab_options_value: >-
|
|
||||||
{{
|
{{
|
||||||
(['luks'] + configuration_luks_option_list_value + configuration_luks_tpm2_option_list_value)
|
(['luks'] + luks_option_list + luks_tpm2_option_list)
|
||||||
| join(',')
|
| join(',')
|
||||||
}}
|
}}
|
||||||
configuration_luks_rd_options_value: >-
|
luks_rd_options: "{{ (luks_option_list + luks_tpm2_option_list) | join(',') }}"
|
||||||
{{ (configuration_luks_option_list_value + configuration_luks_tpm2_option_list_value) | join(',') }}
|
luks_kernel_args: >-
|
||||||
configuration_luks_kernel_args_value: >-
|
|
||||||
{{
|
{{
|
||||||
(
|
(
|
||||||
['rd.luks.name=' + configuration_luks_uuid + '=' + configuration_luks_mapper_name]
|
['rd.luks.name=' + configuration_luks_uuid + '=' + configuration_luks_mapper_name]
|
||||||
+ (
|
+ (
|
||||||
['rd.luks.options=' + configuration_luks_uuid + '=' + configuration_luks_rd_options_value]
|
['rd.luks.options=' + configuration_luks_uuid + '=' + luks_rd_options]
|
||||||
if configuration_luks_rd_options_value | length > 0 else []
|
if luks_rd_options | length > 0 else []
|
||||||
)
|
)
|
||||||
+ (
|
+ (
|
||||||
['rd.luks.key=' + configuration_luks_uuid + '=' + configuration_luks_keyfile_path]
|
['rd.luks.key=' + configuration_luks_uuid + '=' + configuration_luks_keyfile_path]
|
||||||
if configuration_luks_keyfile_in_use_value else []
|
if luks_keyfile_in_use else []
|
||||||
)
|
)
|
||||||
) | join(' ')
|
) | join(' ')
|
||||||
}}
|
}}
|
||||||
ansible.builtin.set_fact:
|
ansible.builtin.set_fact:
|
||||||
configuration_luks_keyfile_in_use: "{{ configuration_luks_keyfile_in_use_value }}"
|
configuration_luks_keyfile_in_use: "{{ luks_keyfile_in_use }}"
|
||||||
configuration_luks_option_list: "{{ configuration_luks_option_list_value }}"
|
configuration_luks_option_list: "{{ luks_option_list }}"
|
||||||
configuration_luks_tpm2_option_list: "{{ configuration_luks_tpm2_option_list_value }}"
|
configuration_luks_tpm2_option_list: "{{ luks_tpm2_option_list }}"
|
||||||
configuration_luks_crypttab_keyfile: "{{ configuration_luks_crypttab_keyfile_value }}"
|
configuration_luks_crypttab_keyfile: "{{ luks_crypttab_keyfile }}"
|
||||||
configuration_luks_crypttab_options: "{{ configuration_luks_crypttab_options_value }}"
|
configuration_luks_crypttab_options: "{{ luks_crypttab_options }}"
|
||||||
configuration_luks_rd_options: "{{ configuration_luks_rd_options_value }}"
|
configuration_luks_rd_options: "{{ luks_rd_options }}"
|
||||||
configuration_luks_kernel_args: "{{ configuration_luks_kernel_args_value }}"
|
configuration_luks_kernel_args: "{{ luks_kernel_args }}"
|
||||||
|
|
||||||
- name: Remove LUKS keyfile if TPM2 auto-decrypt is active
|
- name: Remove LUKS keyfile if TPM2 auto-decrypt is active
|
||||||
when: configuration_luks_auto_method == 'tpm2'
|
when: configuration_luks_auto_method == 'tpm2'
|
||||||
@@ -141,8 +130,8 @@
|
|||||||
- configuration_luks_keyfile_in_use
|
- configuration_luks_keyfile_in_use
|
||||||
ansible.builtin.lineinfile:
|
ansible.builtin.lineinfile:
|
||||||
path: /mnt/etc/cryptsetup-initramfs/conf-hook
|
path: /mnt/etc/cryptsetup-initramfs/conf-hook
|
||||||
regexp: '^KEYFILE_PATTERN='
|
regexp: "^KEYFILE_PATTERN="
|
||||||
line: 'KEYFILE_PATTERN=/etc/cryptsetup-keys.d/*.key'
|
line: "KEYFILE_PATTERN=/etc/cryptsetup-keys.d/*.key"
|
||||||
create: true
|
create: true
|
||||||
mode: "0644"
|
mode: "0644"
|
||||||
|
|
||||||
@@ -150,7 +139,7 @@
|
|||||||
when: os | lower == 'archlinux'
|
when: os | lower == 'archlinux'
|
||||||
ansible.builtin.lineinfile:
|
ansible.builtin.lineinfile:
|
||||||
path: /mnt/etc/mkinitcpio.conf
|
path: /mnt/etc/mkinitcpio.conf
|
||||||
regexp: '^HOOKS='
|
regexp: "^HOOKS="
|
||||||
line: >-
|
line: >-
|
||||||
HOOKS=(base systemd autodetect microcode modconf kms keyboard sd-vconsole
|
HOOKS=(base systemd autodetect microcode modconf kms keyboard sd-vconsole
|
||||||
block sd-encrypt lvm2 filesystems fsck)
|
block sd-encrypt lvm2 filesystems fsck)
|
||||||
@@ -164,7 +153,7 @@
|
|||||||
- name: Build mkinitcpio FILES list
|
- name: Build mkinitcpio FILES list
|
||||||
when: os | lower == 'archlinux'
|
when: os | lower == 'archlinux'
|
||||||
vars:
|
vars:
|
||||||
configuration_mkinitcpio_files_list_value: >-
|
mkinitcpio_files_list: >-
|
||||||
{{
|
{{
|
||||||
(
|
(
|
||||||
configuration_mkinitcpio_slurp.content | b64decode
|
configuration_mkinitcpio_slurp.content | b64decode
|
||||||
@@ -174,13 +163,13 @@
|
|||||||
| default('')
|
| default('')
|
||||||
).split()
|
).split()
|
||||||
}}
|
}}
|
||||||
configuration_mkinitcpio_files_list_new_value: >-
|
mkinitcpio_files_list_new: >-
|
||||||
{{
|
{{
|
||||||
(
|
(
|
||||||
(configuration_mkinitcpio_files_list_value + [configuration_luks_keyfile_path])
|
(mkinitcpio_files_list + [configuration_luks_keyfile_path])
|
||||||
if configuration_luks_keyfile_in_use
|
if configuration_luks_keyfile_in_use
|
||||||
else (
|
else (
|
||||||
configuration_mkinitcpio_files_list_value
|
mkinitcpio_files_list
|
||||||
| reject('equalto', configuration_luks_keyfile_path)
|
| reject('equalto', configuration_luks_keyfile_path)
|
||||||
| list
|
| list
|
||||||
)
|
)
|
||||||
@@ -188,13 +177,13 @@
|
|||||||
| unique
|
| unique
|
||||||
}}
|
}}
|
||||||
ansible.builtin.set_fact:
|
ansible.builtin.set_fact:
|
||||||
configuration_mkinitcpio_files_list_new: "{{ configuration_mkinitcpio_files_list_new_value }}"
|
configuration_mkinitcpio_files_list_new: "{{ mkinitcpio_files_list_new }}"
|
||||||
|
|
||||||
- name: Configure mkinitcpio FILES list
|
- name: Configure mkinitcpio FILES list
|
||||||
when: os | lower == 'archlinux'
|
when: os | lower == 'archlinux'
|
||||||
ansible.builtin.lineinfile:
|
ansible.builtin.lineinfile:
|
||||||
path: /mnt/etc/mkinitcpio.conf
|
path: /mnt/etc/mkinitcpio.conf
|
||||||
regexp: '^FILES='
|
regexp: "^FILES="
|
||||||
line: >-
|
line: >-
|
||||||
FILES=({{
|
FILES=({{
|
||||||
configuration_mkinitcpio_files_list_new | join(' ')
|
configuration_mkinitcpio_files_list_new | join(' ')
|
||||||
@@ -227,27 +216,27 @@
|
|||||||
- name: Build kernel cmdline with LUKS args
|
- name: Build kernel cmdline with LUKS args
|
||||||
when: is_rhel | bool
|
when: is_rhel | bool
|
||||||
vars:
|
vars:
|
||||||
configuration_kernel_cmdline_current_value: >-
|
kernel_cmdline_current: >-
|
||||||
{{ configuration_kernel_cmdline_slurp.content | b64decode | trim }}
|
{{ configuration_kernel_cmdline_slurp.content | b64decode | trim }}
|
||||||
configuration_kernel_cmdline_list_value: >-
|
kernel_cmdline_list: >-
|
||||||
{{
|
{{
|
||||||
configuration_kernel_cmdline_current_value.split()
|
kernel_cmdline_current.split()
|
||||||
if configuration_kernel_cmdline_current_value | length > 0 else []
|
if kernel_cmdline_current | length > 0 else []
|
||||||
}}
|
}}
|
||||||
configuration_kernel_cmdline_filtered_value: >-
|
kernel_cmdline_filtered: >-
|
||||||
{{
|
{{
|
||||||
configuration_kernel_cmdline_list_value
|
kernel_cmdline_list
|
||||||
| reject('match', '^rd\\.luks\\.(name|options|key)=' ~ configuration_luks_uuid ~ '=')
|
| reject('match', '^rd\\.luks\\.(name|options|key)=' ~ configuration_luks_uuid ~ '=')
|
||||||
| list
|
| list
|
||||||
}}
|
}}
|
||||||
configuration_kernel_cmdline_new_value: >-
|
kernel_cmdline_new: >-
|
||||||
{{
|
{{
|
||||||
(configuration_kernel_cmdline_filtered_value + configuration_luks_kernel_args.split())
|
(kernel_cmdline_filtered + configuration_luks_kernel_args.split())
|
||||||
| unique
|
| unique
|
||||||
| join(' ')
|
| join(' ')
|
||||||
}}
|
}}
|
||||||
ansible.builtin.set_fact:
|
ansible.builtin.set_fact:
|
||||||
configuration_kernel_cmdline_new: "{{ configuration_kernel_cmdline_new_value }}"
|
configuration_kernel_cmdline_new: "{{ kernel_cmdline_new }}"
|
||||||
changed_when: false
|
changed_when: false
|
||||||
|
|
||||||
- name: Write kernel cmdline with LUKS args
|
- name: Write kernel cmdline with LUKS args
|
||||||
@@ -271,7 +260,7 @@
|
|||||||
- configuration_kernel_bls_entries.files | length > 0
|
- configuration_kernel_bls_entries.files | length > 0
|
||||||
ansible.builtin.lineinfile:
|
ansible.builtin.lineinfile:
|
||||||
path: "{{ item.path }}"
|
path: "{{ item.path }}"
|
||||||
regexp: '^options '
|
regexp: "^options "
|
||||||
line: "options {{ configuration_kernel_cmdline_new }}"
|
line: "options {{ configuration_kernel_cmdline_new }}"
|
||||||
loop: "{{ configuration_kernel_bls_entries.files }}"
|
loop: "{{ configuration_kernel_bls_entries.files }}"
|
||||||
loop_control:
|
loop_control:
|
||||||
@@ -286,70 +275,70 @@
|
|||||||
- name: Build grub command lines with LUKS args
|
- name: Build grub command lines with LUKS args
|
||||||
when: not is_rhel | bool
|
when: not is_rhel | bool
|
||||||
vars:
|
vars:
|
||||||
configuration_grub_content_value: "{{ configuration_grub_slurp.content | b64decode }}"
|
grub_content: "{{ configuration_grub_slurp.content | b64decode }}"
|
||||||
configuration_grub_cmdline_linux_value: >-
|
grub_cmdline_linux: >-
|
||||||
{{
|
{{
|
||||||
configuration_grub_content_value
|
grub_content
|
||||||
| regex_findall('^GRUB_CMDLINE_LINUX=\"(.*)\"', multiline=True)
|
| regex_findall('^GRUB_CMDLINE_LINUX=\"(.*)\"', multiline=True)
|
||||||
| default([])
|
| default([])
|
||||||
| first
|
| first
|
||||||
| default('')
|
| default('')
|
||||||
}}
|
}}
|
||||||
configuration_grub_cmdline_default_value: >-
|
grub_cmdline_default: >-
|
||||||
{{
|
{{
|
||||||
configuration_grub_content_value
|
grub_content
|
||||||
| regex_findall('^GRUB_CMDLINE_LINUX_DEFAULT=\"(.*)\"', multiline=True)
|
| regex_findall('^GRUB_CMDLINE_LINUX_DEFAULT=\"(.*)\"', multiline=True)
|
||||||
| default([])
|
| default([])
|
||||||
| first
|
| first
|
||||||
| default('')
|
| default('')
|
||||||
}}
|
}}
|
||||||
configuration_grub_cmdline_linux_list_value: >-
|
grub_cmdline_linux_list: >-
|
||||||
{{
|
{{
|
||||||
configuration_grub_cmdline_linux_value.split()
|
grub_cmdline_linux.split()
|
||||||
if configuration_grub_cmdline_linux_value | length > 0 else []
|
if grub_cmdline_linux | length > 0 else []
|
||||||
}}
|
}}
|
||||||
configuration_grub_cmdline_default_list_value: >-
|
grub_cmdline_default_list: >-
|
||||||
{{
|
{{
|
||||||
configuration_grub_cmdline_default_value.split()
|
grub_cmdline_default.split()
|
||||||
if configuration_grub_cmdline_default_value | length > 0 else []
|
if grub_cmdline_default | length > 0 else []
|
||||||
}}
|
}}
|
||||||
configuration_luks_kernel_args_list_value: "{{ configuration_luks_kernel_args.split() }}"
|
luks_kernel_args_list: "{{ configuration_luks_kernel_args.split() }}"
|
||||||
configuration_grub_cmdline_linux_new_value: >-
|
grub_cmdline_linux_new: >-
|
||||||
{{
|
{{
|
||||||
(
|
(
|
||||||
(
|
(
|
||||||
configuration_grub_cmdline_linux_list_value
|
grub_cmdline_linux_list
|
||||||
| reject('match', '^rd\\.luks\\.(name|options|key)=' ~ configuration_luks_uuid ~ '=')
|
| reject('match', '^rd\\.luks\\.(name|options|key)=' ~ configuration_luks_uuid ~ '=')
|
||||||
| list
|
| list
|
||||||
)
|
)
|
||||||
+ configuration_luks_kernel_args_list_value
|
+ luks_kernel_args_list
|
||||||
)
|
)
|
||||||
| unique
|
| unique
|
||||||
| join(' ')
|
| join(' ')
|
||||||
}}
|
}}
|
||||||
configuration_grub_cmdline_default_new_value: >-
|
grub_cmdline_default_new: >-
|
||||||
{{
|
{{
|
||||||
(
|
(
|
||||||
(
|
(
|
||||||
configuration_grub_cmdline_default_list_value
|
grub_cmdline_default_list
|
||||||
| reject('match', '^rd\\.luks\\.(name|options|key)=' ~ configuration_luks_uuid ~ '=')
|
| reject('match', '^rd\\.luks\\.(name|options|key)=' ~ configuration_luks_uuid ~ '=')
|
||||||
| list
|
| list
|
||||||
)
|
)
|
||||||
+ configuration_luks_kernel_args_list_value
|
+ luks_kernel_args_list
|
||||||
)
|
)
|
||||||
| unique
|
| unique
|
||||||
| join(' ')
|
| join(' ')
|
||||||
}}
|
}}
|
||||||
ansible.builtin.set_fact:
|
ansible.builtin.set_fact:
|
||||||
configuration_grub_content: "{{ configuration_grub_content_value }}"
|
configuration_grub_content: "{{ grub_content }}"
|
||||||
configuration_grub_cmdline_linux: "{{ configuration_grub_cmdline_linux_value }}"
|
configuration_grub_cmdline_linux: "{{ grub_cmdline_linux }}"
|
||||||
configuration_grub_cmdline_default: "{{ configuration_grub_cmdline_default_value }}"
|
configuration_grub_cmdline_default: "{{ grub_cmdline_default }}"
|
||||||
configuration_grub_cmdline_linux_new: "{{ configuration_grub_cmdline_linux_new_value }}"
|
configuration_grub_cmdline_linux_new: "{{ grub_cmdline_linux_new }}"
|
||||||
configuration_grub_cmdline_default_new: "{{ configuration_grub_cmdline_default_new_value }}"
|
configuration_grub_cmdline_default_new: "{{ grub_cmdline_default_new }}"
|
||||||
|
|
||||||
- name: Update GRUB_CMDLINE_LINUX_DEFAULT for LUKS
|
- name: Update GRUB_CMDLINE_LINUX_DEFAULT for LUKS
|
||||||
when: not is_rhel | bool
|
when: not is_rhel | bool
|
||||||
ansible.builtin.lineinfile:
|
ansible.builtin.lineinfile:
|
||||||
path: /mnt/etc/default/grub
|
path: /mnt/etc/default/grub
|
||||||
regexp: '^GRUB_CMDLINE_LINUX_DEFAULT='
|
regexp: "^GRUB_CMDLINE_LINUX_DEFAULT="
|
||||||
line: 'GRUB_CMDLINE_LINUX_DEFAULT="{{ configuration_grub_cmdline_default_new }}"'
|
line: 'GRUB_CMDLINE_LINUX_DEFAULT="{{ configuration_grub_cmdline_default_new }}"'
|
||||||
|
|||||||
@@ -52,7 +52,7 @@
|
|||||||
when: configuration_luks_keyfile_unlock_test.rc != 0
|
when: configuration_luks_keyfile_unlock_test.rc != 0
|
||||||
community.crypto.luks_device:
|
community.crypto.luks_device:
|
||||||
device: "{{ configuration_luks_device }}"
|
device: "{{ configuration_luks_device }}"
|
||||||
passphrase: "{{ configuration_luks_passphrase_effective }}"
|
passphrase: "{{ configuration_luks_passphrase }}"
|
||||||
new_keyfile: "/mnt{{ configuration_luks_keyfile_path }}"
|
new_keyfile: "/mnt{{ configuration_luks_keyfile_path }}"
|
||||||
register: configuration_luks_addkey_result
|
register: configuration_luks_addkey_result
|
||||||
failed_when: false
|
failed_when: false
|
||||||
@@ -84,7 +84,7 @@
|
|||||||
- name: Retry adding keyfile to LUKS header
|
- name: Retry adding keyfile to LUKS header
|
||||||
community.crypto.luks_device:
|
community.crypto.luks_device:
|
||||||
device: "{{ configuration_luks_device }}"
|
device: "{{ configuration_luks_device }}"
|
||||||
passphrase: "{{ configuration_luks_passphrase_effective }}"
|
passphrase: "{{ configuration_luks_passphrase }}"
|
||||||
new_keyfile: "/mnt{{ configuration_luks_keyfile_path }}"
|
new_keyfile: "/mnt{{ configuration_luks_keyfile_path }}"
|
||||||
register: configuration_luks_addkey_retry
|
register: configuration_luks_addkey_retry
|
||||||
failed_when: false
|
failed_when: false
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
- name: Write passphrase into temporary file for TPM2 enrollment
|
- name: Write passphrase into temporary file for TPM2 enrollment
|
||||||
ansible.builtin.copy:
|
ansible.builtin.copy:
|
||||||
dest: "{{ configuration_luks_tpm2_passphrase_tempfile.path }}"
|
dest: "{{ configuration_luks_tpm2_passphrase_tempfile.path }}"
|
||||||
content: "{{ configuration_luks_passphrase_effective }}"
|
content: "{{ configuration_luks_passphrase }}"
|
||||||
owner: root
|
owner: root
|
||||||
group: root
|
group: root
|
||||||
mode: "0600"
|
mode: "0600"
|
||||||
@@ -31,12 +31,12 @@
|
|||||||
| regex_replace('^/mnt', '')
|
| regex_replace('^/mnt', '')
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
+ (['--tpm2-pcrs=' + configuration_luks_tpm2_pcrs_effective]
|
+ (['--tpm2-pcrs=' + configuration_luks_tpm2_pcrs]
|
||||||
if configuration_luks_tpm2_pcrs_effective | length > 0 else [])
|
if configuration_luks_tpm2_pcrs | length > 0 else [])
|
||||||
+ [configuration_luks_device]
|
+ [configuration_luks_device]
|
||||||
}}
|
}}
|
||||||
configuration_luks_enroll_chroot_cmd: >-
|
configuration_luks_enroll_chroot_cmd: >-
|
||||||
{{ chroot_command }} /mnt {{ configuration_luks_enroll_args | join(' ') }}
|
{{ chroot_command }} {{ configuration_luks_enroll_args | join(' ') }}
|
||||||
ansible.builtin.command: "{{ configuration_luks_enroll_chroot_cmd }}"
|
ansible.builtin.command: "{{ configuration_luks_enroll_chroot_cmd }}"
|
||||||
register: configuration_luks_tpm2_enroll_chroot
|
register: configuration_luks_tpm2_enroll_chroot
|
||||||
changed_when: configuration_luks_tpm2_enroll_chroot.rc == 0
|
changed_when: configuration_luks_tpm2_enroll_chroot.rc == 0
|
||||||
@@ -55,8 +55,8 @@
|
|||||||
'--wipe-slot=tpm2',
|
'--wipe-slot=tpm2',
|
||||||
'--unlock-key-file=' + configuration_luks_tpm2_passphrase_tempfile.path
|
'--unlock-key-file=' + configuration_luks_tpm2_passphrase_tempfile.path
|
||||||
]
|
]
|
||||||
+ (['--tpm2-pcrs=' + configuration_luks_tpm2_pcrs_effective]
|
+ (['--tpm2-pcrs=' + configuration_luks_tpm2_pcrs]
|
||||||
if configuration_luks_tpm2_pcrs_effective | length > 0 else [])
|
if configuration_luks_tpm2_pcrs | length > 0 else [])
|
||||||
+ [configuration_luks_device]
|
+ [configuration_luks_device]
|
||||||
}}
|
}}
|
||||||
ansible.builtin.command:
|
ansible.builtin.command:
|
||||||
|
|||||||
@@ -27,14 +27,15 @@
|
|||||||
|
|
||||||
- name: Create zram config
|
- name: Create zram config
|
||||||
when:
|
when:
|
||||||
- os | lower not in ['debian11', 'rhel8']
|
- (os != "debian" or (os_version | string) != "11") and os != "rhel"
|
||||||
- swap_enabled | bool
|
- os | lower not in ["alpine", "void"]
|
||||||
|
- system_cfg.features.swap.enabled | bool
|
||||||
ansible.builtin.copy:
|
ansible.builtin.copy:
|
||||||
dest: /mnt/etc/systemd/zram-generator.conf
|
dest: /mnt/etc/systemd/zram-generator.conf
|
||||||
content: |
|
content: |
|
||||||
[zram0]
|
[zram0]
|
||||||
zram-size = ram / 2
|
zram-size = ram / 2
|
||||||
compression-algorithm = {{ 'zstd' if zstd_enabled | bool else 'lz4' }}
|
compression-algorithm = {{ 'zstd' if system_cfg.features.zstd.enabled | bool else 'lz4' }}
|
||||||
swap-priority = 100
|
swap-priority = 100
|
||||||
fs-type = swap
|
fs-type = swap
|
||||||
mode: "0644"
|
mode: "0644"
|
||||||
@@ -62,7 +63,7 @@
|
|||||||
- /mnt/etc/issue.net
|
- /mnt/etc/issue.net
|
||||||
|
|
||||||
- name: Remove motd files
|
- name: Remove motd files
|
||||||
when: os | lower in ["rhel8", "rhel9", "rhel10"]
|
when: os == "rhel"
|
||||||
ansible.builtin.file:
|
ansible.builtin.file:
|
||||||
path: "{{ item }}"
|
path: "{{ item }}"
|
||||||
state: absent
|
state: absent
|
||||||
|
|||||||
@@ -16,30 +16,30 @@
|
|||||||
group: root
|
group: root
|
||||||
mode: "0644"
|
mode: "0644"
|
||||||
|
|
||||||
- name: Remove deprecated attr2 and disable large extent
|
- name: Adjust XFS mount options and disable large extent
|
||||||
when: os | lower in ["almalinux", "rhel8", "rhel9", "rhel10", "rocky"] and filesystem == "xfs"
|
when: os in ["almalinux", "rocky", "rhel"] and system_cfg.filesystem == "xfs"
|
||||||
ansible.builtin.replace:
|
ansible.builtin.replace:
|
||||||
path: /mnt/etc/fstab
|
path: /mnt/etc/fstab
|
||||||
regexp: "(xfs.*?)(attr2)"
|
regexp: "(xfs.*?)(attr2)"
|
||||||
replace: '\1allocsize=64m'
|
replace: "\\1allocsize=64m"
|
||||||
|
|
||||||
- name: Replace ISO UUID entry with /dev/sr0 in fstab
|
- name: Replace ISO UUID entry with /dev/sr0 in fstab
|
||||||
when: os in ["rhel8", "rhel9", "rhel10"]
|
when: os == "rhel"
|
||||||
vars:
|
vars:
|
||||||
configuration_fstab_dvd_line: >-
|
configuration_fstab_dvd_line: >-
|
||||||
{{
|
{{
|
||||||
'/usr/local/install/redhat/rhel.iso /usr/local/install/redhat/dvd iso9660 loop,nofail 0 0'
|
'/usr/local/install/redhat/rhel.iso /usr/local/install/redhat/dvd iso9660 loop,nofail 0 0'
|
||||||
if hypervisor == 'vmware'
|
if hypervisor_type == 'vmware'
|
||||||
else '/dev/sr0 /usr/local/install/redhat/dvd iso9660 ro,relatime,nojoliet,check=s,map=n,nofail 0 0'
|
else '/dev/sr0 /usr/local/install/redhat/dvd iso9660 ro,relatime,nojoliet,check=s,map=n,nofail 0 0'
|
||||||
}}
|
}}
|
||||||
ansible.builtin.lineinfile:
|
ansible.builtin.lineinfile:
|
||||||
path: /mnt/etc/fstab
|
path: /mnt/etc/fstab
|
||||||
regexp: '^.*\/dvd.*$'
|
regexp: "^.*\\/dvd.*$"
|
||||||
line: "{{ configuration_fstab_dvd_line }}"
|
line: "{{ configuration_fstab_dvd_line }}"
|
||||||
state: present
|
state: present
|
||||||
|
|
||||||
- name: Write image from RHEL ISO to the target machine
|
- name: Write image from RHEL ISO to the target machine
|
||||||
when: os in ["rhel8", "rhel9", "rhel10"] and hypervisor == 'vmware'
|
when: os == "rhel" and hypervisor_type == 'vmware'
|
||||||
ansible.builtin.command:
|
ansible.builtin.command:
|
||||||
argv:
|
argv:
|
||||||
- dd
|
- dd
|
||||||
@@ -57,9 +57,9 @@
|
|||||||
line: "{{ fstab_entry.line }}"
|
line: "{{ fstab_entry.line }}"
|
||||||
insertafter: EOF
|
insertafter: EOF
|
||||||
loop:
|
loop:
|
||||||
- {regexp: '^# TempFS$', line: '# TempFS'}
|
- { regexp: "^# TempFS$", line: "# TempFS" }
|
||||||
- {regexp: '^tmpfs\\s+/tmp\\s+', line: 'tmpfs /tmp tmpfs defaults,nosuid,nodev,noexec 0 0'}
|
- { regexp: "^tmpfs\\\\s+/tmp\\\\s+", line: "tmpfs /tmp tmpfs defaults,nosuid,nodev,noexec 0 0" }
|
||||||
- {regexp: '^tmpfs\\s+/var/tmp\\s+', line: 'tmpfs /var/tmp tmpfs defaults,nosuid,nodev,noexec 0 0'}
|
- { regexp: "^tmpfs\\\\s+/var/tmp\\\\s+", line: "tmpfs /var/tmp tmpfs defaults,nosuid,nodev,noexec 0 0" }
|
||||||
- {regexp: '^tmpfs\\s+/dev/shm\\s+', line: 'tmpfs /dev/shm tmpfs defaults,nosuid,nodev,noexec 0 0'}
|
- { regexp: "^tmpfs\\\\s+/dev/shm\\\\s+", line: "tmpfs /dev/shm tmpfs defaults,nosuid,nodev,noexec 0 0" }
|
||||||
loop_control:
|
loop_control:
|
||||||
loop_var: fstab_entry
|
loop_var: fstab_entry
|
||||||
|
|||||||
@@ -16,50 +16,50 @@
|
|||||||
block:
|
block:
|
||||||
- name: Build RHEL kernel command line defaults
|
- name: Build RHEL kernel command line defaults
|
||||||
vars:
|
vars:
|
||||||
configuration_grub_root_uuid_value: >-
|
grub_root_uuid: >-
|
||||||
{{
|
{{
|
||||||
(
|
(
|
||||||
partitioning_main_uuid.stdout
|
partitioning_main_uuid.stdout
|
||||||
if (filesystem | lower) == 'btrfs'
|
if (system_cfg.filesystem | lower) == 'btrfs'
|
||||||
else (partitioning_uuid_root | default([]) | first | default(''))
|
else (partitioning_uuid_root | default([]) | first | default(''))
|
||||||
)
|
)
|
||||||
| default('')
|
| default('')
|
||||||
| trim
|
| trim
|
||||||
}}
|
}}
|
||||||
configuration_grub_lvm_args_value: >-
|
grub_lvm_args: >-
|
||||||
{{
|
{{
|
||||||
(
|
(
|
||||||
['rd.lvm.lv=sys/root']
|
['rd.lvm.lv=sys/root']
|
||||||
+ (
|
+ (
|
||||||
['rd.lvm.lv=sys/swap', 'resume=/dev/mapper/sys-swap']
|
['rd.lvm.lv=sys/swap', 'resume=/dev/mapper/sys-swap']
|
||||||
if swap_enabled | bool
|
if system_cfg.features.swap.enabled | bool
|
||||||
else []
|
else []
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
if (filesystem | lower) != 'btrfs'
|
if (system_cfg.filesystem | lower) != 'btrfs'
|
||||||
else []
|
else []
|
||||||
}}
|
}}
|
||||||
configuration_grub_root_flags_value: >-
|
grub_root_flags: >-
|
||||||
{{ ['rootflags=subvol=@'] if (filesystem | lower) == 'btrfs' else [] }}
|
{{ ['rootflags=subvol=@'] if (system_cfg.filesystem | lower) == 'btrfs' else [] }}
|
||||||
configuration_grub_cmdline_linux_base_value: >-
|
grub_cmdline_linux_base: >-
|
||||||
{{
|
{{
|
||||||
(['crashkernel=auto'] + configuration_grub_lvm_args_value)
|
(['crashkernel=auto'] + grub_lvm_args)
|
||||||
| join(' ')
|
| join(' ')
|
||||||
}}
|
}}
|
||||||
configuration_grub_kernel_cmdline_base_value: >-
|
grub_kernel_cmdline_base: >-
|
||||||
{{
|
{{
|
||||||
(
|
(
|
||||||
(['root=UUID=' + configuration_grub_root_uuid_value]
|
(['root=UUID=' + grub_root_uuid]
|
||||||
if configuration_grub_root_uuid_value | length > 0 else [])
|
if grub_root_uuid | length > 0 else [])
|
||||||
+ ['ro', 'crashkernel=auto']
|
+ ['ro', 'crashkernel=auto']
|
||||||
+ configuration_grub_lvm_args_value
|
+ grub_lvm_args
|
||||||
+ configuration_grub_root_flags_value
|
+ grub_root_flags
|
||||||
)
|
)
|
||||||
| join(' ')
|
| join(' ')
|
||||||
}}
|
}}
|
||||||
ansible.builtin.set_fact:
|
ansible.builtin.set_fact:
|
||||||
configuration_grub_cmdline_linux_base: "{{ configuration_grub_cmdline_linux_base_value }}"
|
configuration_grub_cmdline_linux_base: "{{ grub_cmdline_linux_base }}"
|
||||||
configuration_kernel_cmdline_base: "{{ configuration_grub_kernel_cmdline_base_value }}"
|
configuration_kernel_cmdline_base: "{{ grub_kernel_cmdline_base }}"
|
||||||
changed_when: false
|
changed_when: false
|
||||||
|
|
||||||
- name: Check if grub defaults file exists
|
- name: Check if grub defaults file exists
|
||||||
@@ -106,7 +106,7 @@
|
|||||||
when: configuration_grub_bls_entries.files | length > 0
|
when: configuration_grub_bls_entries.files | length > 0
|
||||||
ansible.builtin.lineinfile:
|
ansible.builtin.lineinfile:
|
||||||
path: "{{ item.path }}"
|
path: "{{ item.path }}"
|
||||||
regexp: '^options '
|
regexp: "^options "
|
||||||
line: "options {{ configuration_kernel_cmdline_base }}"
|
line: "options {{ configuration_kernel_cmdline_base }}"
|
||||||
loop: "{{ configuration_grub_bls_entries.files }}"
|
loop: "{{ configuration_grub_bls_entries.files }}"
|
||||||
loop_control:
|
loop_control:
|
||||||
@@ -116,5 +116,5 @@
|
|||||||
when: partitioning_grub_enable_cryptodisk | bool
|
when: partitioning_grub_enable_cryptodisk | bool
|
||||||
ansible.builtin.lineinfile:
|
ansible.builtin.lineinfile:
|
||||||
path: /mnt/etc/default/grub
|
path: /mnt/etc/default/grub
|
||||||
regexp: '^GRUB_ENABLE_CRYPTODISK='
|
regexp: "^GRUB_ENABLE_CRYPTODISK="
|
||||||
line: GRUB_ENABLE_CRYPTODISK=y
|
line: GRUB_ENABLE_CRYPTODISK=y
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
---
|
---
|
||||||
- name: Reload systemd in installer environment
|
- name: Reload systemd in installer environment
|
||||||
|
when: ansible_service_mgr == 'systemd'
|
||||||
ansible.builtin.systemd:
|
ansible.builtin.systemd:
|
||||||
daemon_reload: true
|
daemon_reload: true
|
||||||
|
|
||||||
@@ -23,19 +24,21 @@
|
|||||||
|
|
||||||
- name: Generate locales
|
- name: Generate locales
|
||||||
when: not is_rhel | bool
|
when: not is_rhel | bool
|
||||||
ansible.builtin.command: "{{ chroot_command }} /mnt /usr/sbin/locale-gen"
|
ansible.builtin.command: "{{ chroot_command }} /usr/sbin/locale-gen"
|
||||||
register: configuration_locale_result
|
register: configuration_locale_result
|
||||||
changed_when: configuration_locale_result.rc == 0
|
changed_when: configuration_locale_result.rc == 0
|
||||||
|
|
||||||
|
|
||||||
- name: Set hostname
|
- name: Set hostname
|
||||||
vars:
|
vars:
|
||||||
|
configuration_dns_domain: "{{ (system_cfg.dns.search | default([]) | first | default('')) | string }}"
|
||||||
configuration_hostname_fqdn: >-
|
configuration_hostname_fqdn: >-
|
||||||
{{
|
{{
|
||||||
hostname
|
hostname
|
||||||
if '.' in hostname
|
if '.' in hostname
|
||||||
else (
|
else (
|
||||||
hostname + '.' + vm_dns_search
|
hostname + '.' + configuration_dns_domain
|
||||||
if vm_dns_search is defined and vm_dns_search | length
|
if configuration_dns_domain | length > 0
|
||||||
else hostname
|
else hostname
|
||||||
)
|
)
|
||||||
}}
|
}}
|
||||||
@@ -46,21 +49,28 @@
|
|||||||
|
|
||||||
- name: Add host entry to /etc/hosts
|
- name: Add host entry to /etc/hosts
|
||||||
vars:
|
vars:
|
||||||
|
configuration_dns_domain: "{{ (system_cfg.dns.search | default([]) | first | default('')) | string }}"
|
||||||
configuration_hostname_fqdn: >-
|
configuration_hostname_fqdn: >-
|
||||||
{{
|
{{
|
||||||
hostname
|
hostname
|
||||||
if '.' in hostname
|
if '.' in hostname
|
||||||
else (
|
else (
|
||||||
hostname + '.' + vm_dns_search
|
hostname + '.' + configuration_dns_domain
|
||||||
if vm_dns_search is defined and vm_dns_search | length
|
if configuration_dns_domain | length > 0
|
||||||
else hostname
|
else hostname
|
||||||
)
|
)
|
||||||
}}
|
}}
|
||||||
configuration_hostname_short: "{{ hostname.split('.')[0] }}"
|
configuration_hostname_short: "{{ hostname.split('.')[0] }}"
|
||||||
configuration_hostname_entries: >-
|
configuration_hostname_entries: >-
|
||||||
{{ [configuration_hostname_fqdn, configuration_hostname_short] | unique | join(' ') }}
|
{{ [configuration_hostname_fqdn, configuration_hostname_short] | unique | join(' ') }}
|
||||||
|
configuration_hosts_ip: >-
|
||||||
|
{{
|
||||||
|
system_cfg.ip
|
||||||
|
if system_cfg.ip is defined and (system_cfg.ip | string | length) > 0
|
||||||
|
else inventory_hostname
|
||||||
|
}}
|
||||||
configuration_hosts_line: >-
|
configuration_hosts_line: >-
|
||||||
{{ (vm_ip if vm_ip is defined and vm_ip | length > 0 else inventory_hostname) }} {{ configuration_hostname_entries }}
|
{{ configuration_hosts_ip }} {{ configuration_hostname_entries }}
|
||||||
ansible.builtin.lineinfile:
|
ansible.builtin.lineinfile:
|
||||||
path: /mnt/etc/hosts
|
path: /mnt/etc/hosts
|
||||||
line: "{{ configuration_hosts_line }}"
|
line: "{{ configuration_hosts_line }}"
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
- name: Include configuration tasks
|
- name: Include configuration tasks
|
||||||
ansible.builtin.include_tasks: "{{ configuration_task }}"
|
ansible.builtin.include_tasks: "{{ configuration_task }}"
|
||||||
loop:
|
loop:
|
||||||
|
- banner.yml
|
||||||
- fstab.yml
|
- fstab.yml
|
||||||
- locales.yml
|
- locales.yml
|
||||||
- services.yml
|
- services.yml
|
||||||
|
|||||||
@@ -30,17 +30,17 @@
|
|||||||
)
|
)
|
||||||
| default('')
|
| default('')
|
||||||
}}
|
}}
|
||||||
configuration_net_inf_effective: >-
|
configuration_net_inf_detected: >-
|
||||||
{{ configuration_net_inf_from_facts | default(configuration_net_inf_from_ip, true) }}
|
{{ configuration_net_inf_from_facts | default(configuration_net_inf_from_ip, true) }}
|
||||||
configuration_net_inf_regex: "{{ configuration_net_inf_effective | ansible.builtin.regex_escape }}"
|
configuration_net_inf_regex: "{{ configuration_net_inf_detected | ansible.builtin.regex_escape }}"
|
||||||
configuration_net_mac_from_virtualization: "{{ virtualization_mac_address | default('') }}"
|
configuration_net_mac_from_virtualization: "{{ virtualization_mac_address | default('') }}"
|
||||||
configuration_net_mac_from_facts: >-
|
configuration_net_mac_from_facts: >-
|
||||||
{{
|
{{
|
||||||
(
|
(
|
||||||
(ansible_facts | default({})).get(configuration_net_inf_effective, {}).get('macaddress', '')
|
(ansible_facts | default({})).get(configuration_net_inf_detected, {}).get('macaddress', '')
|
||||||
)
|
)
|
||||||
| default(
|
| default(
|
||||||
(ansible_facts | default({})).get('ansible_' + configuration_net_inf_effective, {}).get('macaddress', ''),
|
(ansible_facts | default({})).get('ansible_' + configuration_net_inf_detected, {}).get('macaddress', ''),
|
||||||
true
|
true
|
||||||
)
|
)
|
||||||
}}
|
}}
|
||||||
@@ -58,7 +58,7 @@
|
|||||||
| default('')
|
| default('')
|
||||||
}}
|
}}
|
||||||
ansible.builtin.set_fact:
|
ansible.builtin.set_fact:
|
||||||
configuration_net_inf: "{{ configuration_net_inf_effective }}"
|
configuration_net_inf: "{{ configuration_net_inf_detected }}"
|
||||||
configuration_net_mac: >-
|
configuration_net_mac: >-
|
||||||
{{
|
{{
|
||||||
(
|
(
|
||||||
@@ -82,6 +82,9 @@
|
|||||||
- configuration_net_mac | length > 0
|
- configuration_net_mac | length > 0
|
||||||
fail_msg: Failed to detect the MAC address for network interface {{ configuration_net_inf }}.
|
fail_msg: Failed to detect the MAC address for network interface {{ configuration_net_inf }}.
|
||||||
|
|
||||||
|
- name: Configure NetworkManager profile
|
||||||
|
when: os | lower not in ["alpine", "void"]
|
||||||
|
block:
|
||||||
- name: Copy NetworkManager keyfile
|
- name: Copy NetworkManager keyfile
|
||||||
ansible.builtin.template:
|
ansible.builtin.template:
|
||||||
src: network.j2
|
src: network.j2
|
||||||
@@ -94,3 +97,69 @@
|
|||||||
path: /mnt/etc/NetworkManager/conf.d/10-globally-managed-devices.conf
|
path: /mnt/etc/NetworkManager/conf.d/10-globally-managed-devices.conf
|
||||||
state: touch
|
state: touch
|
||||||
mode: "0644"
|
mode: "0644"
|
||||||
|
|
||||||
|
- name: Configure Alpine networking
|
||||||
|
when: os | lower == "alpine"
|
||||||
|
vars:
|
||||||
|
configuration_dns_list: "{{ system_cfg.dns.servers | default([]) }}"
|
||||||
|
configuration_alpine_static: >-
|
||||||
|
{{
|
||||||
|
system_cfg.ip is defined
|
||||||
|
and system_cfg.ip | string | length > 0
|
||||||
|
and system_cfg.prefix is defined
|
||||||
|
and (system_cfg.prefix | string | length) > 0
|
||||||
|
}}
|
||||||
|
block:
|
||||||
|
- name: Write Alpine network interfaces
|
||||||
|
ansible.builtin.copy:
|
||||||
|
dest: /mnt/etc/network/interfaces
|
||||||
|
mode: "0644"
|
||||||
|
content: |
|
||||||
|
auto lo
|
||||||
|
iface lo inet loopback
|
||||||
|
|
||||||
|
auto {{ configuration_net_inf }}
|
||||||
|
iface {{ configuration_net_inf }} inet {{ 'static' if configuration_alpine_static | bool else 'dhcp' }}
|
||||||
|
{% if configuration_alpine_static | bool %}
|
||||||
|
address {{ system_cfg.ip }}/{{ system_cfg.prefix }}
|
||||||
|
{% if system_cfg.gateway is defined and system_cfg.gateway | string | length %}
|
||||||
|
gateway {{ system_cfg.gateway }}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
- name: Set Alpine DNS resolvers
|
||||||
|
when: configuration_dns_list | length > 0
|
||||||
|
ansible.builtin.copy:
|
||||||
|
dest: /mnt/etc/resolv.conf
|
||||||
|
mode: "0644"
|
||||||
|
content: |
|
||||||
|
{% for resolver in configuration_dns_list %}
|
||||||
|
nameserver {{ resolver }}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
- name: Configure Void networking
|
||||||
|
when: os | lower == "void"
|
||||||
|
vars:
|
||||||
|
configuration_dns_list: "{{ system_cfg.dns.servers | default([]) }}"
|
||||||
|
configuration_void_static: >-
|
||||||
|
{{
|
||||||
|
system_cfg.ip is defined
|
||||||
|
and system_cfg.ip | string | length > 0
|
||||||
|
and system_cfg.prefix is defined
|
||||||
|
and (system_cfg.prefix | string | length) > 0
|
||||||
|
}}
|
||||||
|
block:
|
||||||
|
- name: Write dhcpcd configuration for static networking
|
||||||
|
when: configuration_void_static | bool
|
||||||
|
ansible.builtin.copy:
|
||||||
|
dest: /mnt/etc/dhcpcd.conf
|
||||||
|
mode: "0644"
|
||||||
|
content: |
|
||||||
|
interface {{ configuration_net_inf }}
|
||||||
|
static ip_address={{ system_cfg.ip }}/{{ system_cfg.prefix }}
|
||||||
|
{% if system_cfg.gateway is defined and system_cfg.gateway | string | length %}
|
||||||
|
static routers={{ system_cfg.gateway }}
|
||||||
|
{% endif %}
|
||||||
|
{% if configuration_dns_list | length > 0 %}
|
||||||
|
static domain_name_servers={{ configuration_dns_list | join(' ') }}
|
||||||
|
{% endif %}
|
||||||
|
|||||||
@@ -3,16 +3,16 @@
|
|||||||
when: is_rhel | bool
|
when: is_rhel | bool
|
||||||
block:
|
block:
|
||||||
- name: Fix SELinux by pre-labeling the filesystem before first boot
|
- name: Fix SELinux by pre-labeling the filesystem before first boot
|
||||||
when: os | lower in ['almalinux', 'rhel8', 'rhel9', 'rhel10', 'rocky'] and selinux | bool
|
when: os in ['almalinux', 'rocky', 'rhel'] and system_cfg.features.selinux.enabled | bool
|
||||||
ansible.builtin.command: >
|
ansible.builtin.command: >
|
||||||
{{ chroot_command }} /mnt /sbin/setfiles -v -F
|
{{ chroot_command }} /sbin/setfiles -v -F
|
||||||
-e /dev -e /proc -e /sys -e /run
|
-e /dev -e /proc -e /sys -e /run
|
||||||
/etc/selinux/targeted/contexts/files/file_contexts /
|
/etc/selinux/targeted/contexts/files/file_contexts /
|
||||||
register: configuration_setfiles_result
|
register: configuration_setfiles_result
|
||||||
changed_when: configuration_setfiles_result.rc == 0
|
changed_when: configuration_setfiles_result.rc == 0
|
||||||
|
|
||||||
- name: Disable SELinux
|
- name: Disable SELinux
|
||||||
when: os | lower == "fedora" or not selinux | bool
|
when: os | lower == "fedora" or not system_cfg.features.selinux.enabled | bool
|
||||||
ansible.builtin.lineinfile:
|
ansible.builtin.lineinfile:
|
||||||
path: /mnt/etc/selinux/config
|
path: /mnt/etc/selinux/config
|
||||||
regexp: ^SELINUX=
|
regexp: ^SELINUX=
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
---
|
---
|
||||||
- name: Enable Systemd Services
|
- name: Enable Systemd Services
|
||||||
|
when: os | lower not in ['alpine', 'void']
|
||||||
ansible.builtin.command: >
|
ansible.builtin.command: >
|
||||||
{{ chroot_command }} /mnt systemctl enable NetworkManager
|
{{ chroot_command }} systemctl enable NetworkManager
|
||||||
{{ ' firewalld' if firewalld_enabled | bool else '' }}
|
{{ ' firewalld' if system_cfg.features.firewall.backend == 'firewalld' and system_cfg.features.firewall.enabled | bool else '' }}
|
||||||
|
{{ ' ufw' if system_cfg.features.firewall.backend == 'ufw' and system_cfg.features.firewall.enabled | bool else '' }}
|
||||||
{{
|
{{
|
||||||
(' ssh' if os | lower in ['ubuntu', 'ubuntu-lts'] else
|
(' ssh' if is_debian | bool else ' sshd')
|
||||||
(' sshd' if os | lower not in ['debian11', 'debian12', 'debian13'] else ''))
|
if system_cfg.features.ssh.enabled | bool else ''
|
||||||
if ssh_enabled | bool else ''
|
|
||||||
}}
|
}}
|
||||||
{{
|
{{
|
||||||
'logrotate systemd-resolved systemd-timesyncd systemd-networkd'
|
'logrotate systemd-resolved systemd-timesyncd systemd-networkd'
|
||||||
@@ -14,3 +15,65 @@
|
|||||||
}}
|
}}
|
||||||
register: configuration_enable_services_result
|
register: configuration_enable_services_result
|
||||||
changed_when: configuration_enable_services_result.rc == 0
|
changed_when: configuration_enable_services_result.rc == 0
|
||||||
|
|
||||||
|
- name: Enable OpenRC services
|
||||||
|
when: os | lower == 'alpine'
|
||||||
|
vars:
|
||||||
|
configuration_openrc_services: >-
|
||||||
|
{{
|
||||||
|
['networking']
|
||||||
|
+ (['sshd'] if system_cfg.features.ssh.enabled | bool else [])
|
||||||
|
+ ([system_cfg.features.firewall.backend] if system_cfg.features.firewall.enabled | bool else [])
|
||||||
|
}}
|
||||||
|
block:
|
||||||
|
- name: Ensure OpenRC runlevel directory exists
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: /mnt/etc/runlevels/default
|
||||||
|
state: directory
|
||||||
|
mode: "0755"
|
||||||
|
|
||||||
|
- name: Check OpenRC init scripts
|
||||||
|
ansible.builtin.stat:
|
||||||
|
path: "/mnt/etc/init.d/{{ item }}"
|
||||||
|
loop: "{{ configuration_openrc_services }}"
|
||||||
|
register: configuration_openrc_service_stats
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: Enable OpenRC services
|
||||||
|
ansible.builtin.file:
|
||||||
|
src: "/mnt/etc/init.d/{{ item.item }}"
|
||||||
|
dest: "/mnt/etc/runlevels/default/{{ item.item }}"
|
||||||
|
state: link
|
||||||
|
loop: "{{ configuration_openrc_service_stats.results }}"
|
||||||
|
when: item.stat.exists
|
||||||
|
|
||||||
|
- name: Enable runit services
|
||||||
|
when: os | lower == 'void'
|
||||||
|
vars:
|
||||||
|
configuration_runit_services: >-
|
||||||
|
{{
|
||||||
|
['dhcpcd']
|
||||||
|
+ (['sshd'] if system_cfg.features.ssh.enabled | bool else [])
|
||||||
|
+ ([system_cfg.features.firewall.backend] if system_cfg.features.firewall.enabled | bool else [])
|
||||||
|
}}
|
||||||
|
block:
|
||||||
|
- name: Ensure runit service directory exists
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: /mnt/var/service
|
||||||
|
state: directory
|
||||||
|
mode: "0755"
|
||||||
|
|
||||||
|
- name: Check runit service definitions
|
||||||
|
ansible.builtin.stat:
|
||||||
|
path: "/mnt/etc/sv/{{ item }}"
|
||||||
|
loop: "{{ configuration_runit_services }}"
|
||||||
|
register: configuration_runit_service_stats
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: Enable runit services
|
||||||
|
ansible.builtin.file:
|
||||||
|
src: "/mnt/etc/sv/{{ item.item }}"
|
||||||
|
dest: "/mnt/var/service/{{ item.item }}"
|
||||||
|
state: link
|
||||||
|
loop: "{{ configuration_runit_service_stats.results }}"
|
||||||
|
when: item.stat.exists
|
||||||
|
|||||||
@@ -4,12 +4,12 @@
|
|||||||
configuration_user_group: >-
|
configuration_user_group: >-
|
||||||
{{ "sudo" if is_debian | bool else "wheel" }}
|
{{ "sudo" if is_debian | bool else "wheel" }}
|
||||||
configuration_useradd_cmd: >-
|
configuration_useradd_cmd: >-
|
||||||
{{ chroot_command }} /mnt /usr/sbin/useradd --create-home --user-group
|
{{ chroot_command }} /usr/sbin/useradd --create-home --user-group
|
||||||
--groups {{ configuration_user_group }} {{ user_name }}
|
--groups {{ configuration_user_group }} {{ system_cfg.user.name }}
|
||||||
--password {{ user_password | password_hash('sha512') }} --shell /bin/bash
|
--password {{ system_cfg.user.password | password_hash('sha512') }} --shell /bin/bash
|
||||||
configuration_root_cmd: >-
|
configuration_root_cmd: >-
|
||||||
{{ chroot_command }} /mnt /usr/sbin/usermod --password
|
{{ chroot_command }} /usr/sbin/usermod --password
|
||||||
'{{ root_password | password_hash('sha512') }}' root --shell /bin/bash
|
'{{ system_cfg.root.password | password_hash('sha512') }}' root --shell /bin/bash
|
||||||
ansible.builtin.command: "{{ item }}"
|
ansible.builtin.command: "{{ item }}"
|
||||||
loop:
|
loop:
|
||||||
- "{{ configuration_useradd_cmd }}"
|
- "{{ configuration_useradd_cmd }}"
|
||||||
@@ -18,19 +18,19 @@
|
|||||||
changed_when: configuration_user_result.rc == 0
|
changed_when: configuration_user_result.rc == 0
|
||||||
|
|
||||||
- name: Ensure .ssh directory exists
|
- name: Ensure .ssh directory exists
|
||||||
when: user_public_key | length > 0
|
when: system_cfg.user.key | length > 0
|
||||||
ansible.builtin.file:
|
ansible.builtin.file:
|
||||||
path: /mnt/home/{{ user_name }}/.ssh
|
path: /mnt/home/{{ system_cfg.user.name }}/.ssh
|
||||||
state: directory
|
state: directory
|
||||||
owner: 1000
|
owner: 1000
|
||||||
group: 1000
|
group: 1000
|
||||||
mode: "0700"
|
mode: "0700"
|
||||||
|
|
||||||
- name: Add SSH public key to authorized_keys
|
- name: Add SSH public key to authorized_keys
|
||||||
when: user_public_key | length > 0
|
when: system_cfg.user.key | length > 0
|
||||||
ansible.builtin.lineinfile:
|
ansible.builtin.lineinfile:
|
||||||
path: /mnt/home/{{ user_name }}/.ssh/authorized_keys
|
path: /mnt/home/{{ system_cfg.user.name }}/.ssh/authorized_keys
|
||||||
line: "{{ user_public_key }}"
|
line: "{{ system_cfg.user.key }}"
|
||||||
owner: 1000
|
owner: 1000
|
||||||
group: 1000
|
group: 1000
|
||||||
mode: "0600"
|
mode: "0600"
|
||||||
|
|||||||
@@ -4,14 +4,10 @@ uuid={{ configuration_net_uuid }}
|
|||||||
type=ethernet
|
type=ethernet
|
||||||
|
|
||||||
[ipv4]
|
[ipv4]
|
||||||
{% set dns_value = vm_dns if vm_dns is defined else '' %}
|
{% set dns_list = system_cfg.dns.servers | default([]) %}
|
||||||
{% set dns_list_raw = dns_value if dns_value is iterable and dns_value is not string else dns_value.split(',') %}
|
{% set search_list = system_cfg.dns.search | default([]) %}
|
||||||
{% set dns_list = dns_list_raw | map('trim') | reject('equalto', '') | list %}
|
{% if system_cfg.ip is defined and system_cfg.ip | string | length %}
|
||||||
{% set search_value = vm_dns_search if vm_dns_search is defined else '' %}
|
address1={{ system_cfg.ip }}/{{ system_cfg.prefix }}{{ (',' ~ system_cfg.gateway) if (system_cfg.gateway is defined and system_cfg.gateway | string | length) else '' }}
|
||||||
{% set search_list_raw = search_value if search_value is iterable and search_value is not string else search_value.split(',') %}
|
|
||||||
{% set search_list = search_list_raw | map('trim') | reject('equalto', '') | list %}
|
|
||||||
{% if vm_ip is defined and vm_ip | length %}
|
|
||||||
address1={{ vm_ip }}/{{ vm_nms }}{{ (',' ~ vm_gw) if (vm_gw is defined and vm_gw | length) else '' }}
|
|
||||||
method=manual
|
method=manual
|
||||||
{% else %}
|
{% else %}
|
||||||
method=auto
|
method=auto
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
- name: Configure work environment
|
- name: Configure work environment
|
||||||
become: "{{ hypervisor != 'vmware' }}"
|
become: "{{ hypervisor_type != 'vmware' }}"
|
||||||
block:
|
block:
|
||||||
- name: Wait for connection
|
- name: Wait for connection
|
||||||
ansible.builtin.wait_for_connection:
|
ansible.builtin.wait_for_connection:
|
||||||
@@ -10,20 +10,78 @@
|
|||||||
- name: Gather facts
|
- name: Gather facts
|
||||||
ansible.builtin.setup:
|
ansible.builtin.setup:
|
||||||
|
|
||||||
- name: Check if host is booted from the Arch install media
|
- name: Check for live environment markers
|
||||||
ansible.builtin.stat:
|
ansible.builtin.stat:
|
||||||
path: /run/archiso
|
path: "{{ item }}"
|
||||||
register: environment_archiso_stat
|
loop:
|
||||||
|
- /run/archiso
|
||||||
|
- /run/live
|
||||||
|
- /run/initramfs
|
||||||
|
- /run/initramfs/live
|
||||||
|
register: environment_live_marker_stat
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: Determine root filesystem type
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
environment_root_fstype: >-
|
||||||
|
{{
|
||||||
|
ansible_mounts
|
||||||
|
| selectattr('mount', 'equalto', '/')
|
||||||
|
| map(attribute='fstype')
|
||||||
|
| list
|
||||||
|
| first
|
||||||
|
| default('')
|
||||||
|
| lower
|
||||||
|
}}
|
||||||
|
environment_archiso_present: >-
|
||||||
|
{{
|
||||||
|
(
|
||||||
|
environment_live_marker_stat.results
|
||||||
|
| selectattr('item', 'equalto', '/run/archiso')
|
||||||
|
| selectattr('stat.exists')
|
||||||
|
| list
|
||||||
|
| length
|
||||||
|
) > 0
|
||||||
|
}}
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: Identify live environment indicators
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
environment_is_live_environment: >-
|
||||||
|
{{
|
||||||
|
(
|
||||||
|
environment_live_marker_stat.results
|
||||||
|
| selectattr('stat.exists')
|
||||||
|
| list
|
||||||
|
| length
|
||||||
|
) > 0
|
||||||
|
or environment_root_fstype in ['overlay', 'overlayfs', 'squashfs', 'aufs']
|
||||||
|
or (ansible_hostname | default('') | lower is search('live'))
|
||||||
|
}}
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: Abort if target is not a live environment
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- environment_is_live_environment | bool
|
||||||
|
fail_msg: |
|
||||||
|
PRODUCTION SYSTEM DETECTED - ABORTING
|
||||||
|
|
||||||
|
The target system does not appear to be a live installer environment.
|
||||||
|
This playbook must run from a live ISO to avoid wiping production data.
|
||||||
|
|
||||||
|
Boot from a live installer (Arch, Debian, Ubuntu, etc.) and retry.
|
||||||
|
quiet: true
|
||||||
|
|
||||||
- name: Abort if the host is not booted from the Arch install media
|
- name: Abort if the host is not booted from the Arch install media
|
||||||
when:
|
when:
|
||||||
- not (custom_iso | bool)
|
- not (custom_iso | bool)
|
||||||
- not environment_archiso_stat.stat.exists
|
- not environment_archiso_present | bool
|
||||||
ansible.builtin.fail:
|
ansible.builtin.fail:
|
||||||
msg: This host is not booted from the Arch install media!
|
msg: This host is not booted from the Arch install media!
|
||||||
|
|
||||||
- name: Select primary Network Interface
|
- name: Select primary Network Interface
|
||||||
when: hypervisor == "vmware"
|
when: hypervisor_type == "vmware"
|
||||||
ansible.builtin.set_fact:
|
ansible.builtin.set_fact:
|
||||||
environment_interface_name: >-
|
environment_interface_name: >-
|
||||||
{{
|
{{
|
||||||
@@ -39,20 +97,20 @@
|
|||||||
|
|
||||||
- name: Set IP-Address
|
- name: Set IP-Address
|
||||||
when:
|
when:
|
||||||
- hypervisor == "vmware"
|
- hypervisor_type == "vmware"
|
||||||
- vm_ip is defined and vm_ip | length > 0
|
- system_cfg.ip is defined and system_cfg.ip | string | length > 0
|
||||||
ansible.builtin.command: >-
|
ansible.builtin.command: >-
|
||||||
ip addr replace {{ vm_ip }}/{{ vm_nms }}
|
ip addr replace {{ system_cfg.ip }}/{{ system_cfg.prefix }}
|
||||||
dev {{ environment_interface_name }}
|
dev {{ environment_interface_name }}
|
||||||
register: environment_ip_result
|
register: environment_ip_result
|
||||||
changed_when: environment_ip_result.rc == 0
|
changed_when: environment_ip_result.rc == 0
|
||||||
|
|
||||||
- name: Set Default Gateway
|
- name: Set Default Gateway
|
||||||
when:
|
when:
|
||||||
- hypervisor == "vmware"
|
- hypervisor_type == "vmware"
|
||||||
- vm_gw is defined and vm_gw | length > 0
|
- system_cfg.gateway is defined and system_cfg.gateway | string | length > 0
|
||||||
- vm_ip is defined and vm_ip | length > 0
|
- system_cfg.ip is defined and system_cfg.ip | string | length > 0
|
||||||
ansible.builtin.command: "ip route replace default via {{ vm_gw }}"
|
ansible.builtin.command: "ip route replace default via {{ system_cfg.gateway }}"
|
||||||
register: environment_gateway_result
|
register: environment_gateway_result
|
||||||
changed_when: environment_gateway_result.rc == 0
|
changed_when: environment_gateway_result.rc == 0
|
||||||
|
|
||||||
@@ -62,7 +120,7 @@
|
|||||||
changed_when: false
|
changed_when: false
|
||||||
|
|
||||||
- name: Configure SSH for root login
|
- name: Configure SSH for root login
|
||||||
when: hypervisor == "vmware" and vmware_ssh | bool
|
when: hypervisor_type == "vmware" and hypervisor_cfg.ssh | bool
|
||||||
block:
|
block:
|
||||||
- name: Allow login
|
- name: Allow login
|
||||||
ansible.builtin.replace:
|
ansible.builtin.replace:
|
||||||
@@ -105,7 +163,7 @@
|
|||||||
- name: Setup Pacman
|
- name: Setup Pacman
|
||||||
when:
|
when:
|
||||||
- not (custom_iso | bool)
|
- not (custom_iso | bool)
|
||||||
- "'os' not in item or os in item.os"
|
- item.os is not defined or (os_resolved | default(os)) in item.os
|
||||||
community.general.pacman:
|
community.general.pacman:
|
||||||
update_cache: true
|
update_cache: true
|
||||||
force: true
|
force: true
|
||||||
@@ -113,15 +171,15 @@
|
|||||||
state: latest
|
state: latest
|
||||||
loop:
|
loop:
|
||||||
- { name: glibc }
|
- { name: glibc }
|
||||||
- {name: dnf, os: [almalinux, fedora, rhel8, rhel9, rhel10, rocky]}
|
- { name: dnf, os: [almalinux8, almalinux9, almalinux10, fedora40, fedora41, fedora42, fedora43, rhel8, rhel9, rhel10, rocky8, rocky9, rocky10] }
|
||||||
- {name: debootstrap, os: [debian11, debian12, debian13, ubuntu, ubuntu-lts]}
|
- { name: debootstrap, os: [debian10, debian11, debian12, debian13, debianunstable, ubuntu, ubuntu-lts] }
|
||||||
- {name: debian-archive-keyring, os: [debian11, debian12, debian13]}
|
- { name: debian-archive-keyring, os: [debian10, debian11, debian12, debian13, debianunstable] }
|
||||||
- { name: ubuntu-keyring, os: [ubuntu, ubuntu-lts] }
|
- { name: ubuntu-keyring, os: [ubuntu, ubuntu-lts] }
|
||||||
retries: 4
|
retries: 4
|
||||||
delay: 15
|
delay: 15
|
||||||
|
|
||||||
- name: Prepare /iso mount and repository for RHEL-based systems
|
- name: Prepare /iso mount and repository for RHEL-based systems
|
||||||
when: os | lower in ["rhel8", "rhel9", "rhel10"]
|
when: os == "rhel"
|
||||||
block:
|
block:
|
||||||
- name: Create /iso directory
|
- name: Create /iso directory
|
||||||
ansible.builtin.file:
|
ansible.builtin.file:
|
||||||
@@ -129,9 +187,19 @@
|
|||||||
state: directory
|
state: directory
|
||||||
mode: "0755"
|
mode: "0755"
|
||||||
|
|
||||||
|
- name: Select RHEL ISO device
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
environment_rhel_iso_device: >-
|
||||||
|
{{
|
||||||
|
'/dev/sr2'
|
||||||
|
if hypervisor_type == 'libvirt'
|
||||||
|
else '/dev/sr1'
|
||||||
|
}}
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
- name: Mount RHEL ISO
|
- name: Mount RHEL ISO
|
||||||
ansible.posix.mount:
|
ansible.posix.mount:
|
||||||
src: "{{ '/dev/sr1' if hypervisor == 'vmware' else '/dev/sr2' }}"
|
src: "{{ environment_rhel_iso_device }}"
|
||||||
path: /usr/local/install/redhat/dvd
|
path: /usr/local/install/redhat/dvd
|
||||||
fstype: iso9660
|
fstype: iso9660
|
||||||
opts: "ro,loop"
|
opts: "ro,loop"
|
||||||
@@ -140,6 +208,16 @@
|
|||||||
- name: Configure RHEL Repos for installation
|
- name: Configure RHEL Repos for installation
|
||||||
when: is_rhel | bool
|
when: is_rhel | bool
|
||||||
block:
|
block:
|
||||||
|
- name: Select repository template
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
environment_repo_template: >-
|
||||||
|
{{
|
||||||
|
(os_resolved | default(os)) | lower
|
||||||
|
if os == 'rhel'
|
||||||
|
else os | lower
|
||||||
|
}}
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
- name: Create directories for repository files and RPM GPG keys
|
- name: Create directories for repository files and RPM GPG keys
|
||||||
ansible.builtin.file:
|
ansible.builtin.file:
|
||||||
path: /etc/yum.repos.d
|
path: /etc/yum.repos.d
|
||||||
@@ -148,8 +226,8 @@
|
|||||||
|
|
||||||
- name: Create RHEL repository file
|
- name: Create RHEL repository file
|
||||||
ansible.builtin.template:
|
ansible.builtin.template:
|
||||||
src: "{{ os | lower }}.repo.j2"
|
src: "{{ environment_repo_template }}.repo.j2"
|
||||||
dest: /etc/yum.repos.d/{{ os | lower }}.repo
|
dest: /etc/yum.repos.d/{{ environment_repo_template }}.repo
|
||||||
mode: "0644"
|
mode: "0644"
|
||||||
|
|
||||||
- name: Check for third-party preparation tasks
|
- name: Check for third-party preparation tasks
|
||||||
|
|||||||
@@ -1,31 +1,94 @@
|
|||||||
---
|
---
|
||||||
hypervisor: "none"
|
# User input. Normalized into hypervisor_cfg + hypervisor_type.
|
||||||
|
hypervisor:
|
||||||
|
type: "none"
|
||||||
|
hypervisor_defaults:
|
||||||
|
type: "none"
|
||||||
|
url: ""
|
||||||
|
username: ""
|
||||||
|
password: ""
|
||||||
|
host: ""
|
||||||
|
storage: ""
|
||||||
|
datacenter: ""
|
||||||
|
cluster: ""
|
||||||
|
certs: false
|
||||||
|
ssh: false
|
||||||
|
|
||||||
custom_iso: false
|
custom_iso: false
|
||||||
cis: false
|
|
||||||
selinux: true
|
|
||||||
vmware_ssh: false
|
|
||||||
firewalld_enabled: true
|
|
||||||
ssh_enabled: true
|
|
||||||
zstd_enabled: true
|
|
||||||
swap_enabled: true
|
|
||||||
chroot_command: "arch-chroot"
|
|
||||||
thirdparty_preparation_tasks_path: "dropins/preparation.yml"
|
thirdparty_preparation_tasks_path: "dropins/preparation.yml"
|
||||||
|
|
||||||
cis_enabled: "{{ cis | bool }}"
|
system_defaults:
|
||||||
|
type: "virtual" # virtual|physical
|
||||||
|
os: ""
|
||||||
|
version: ""
|
||||||
|
filesystem: ""
|
||||||
|
name: ""
|
||||||
|
id: ""
|
||||||
|
cpus: 0
|
||||||
|
memory: 0 # MiB
|
||||||
|
balloon: 0 # MiB
|
||||||
|
network: ""
|
||||||
|
vlan: ""
|
||||||
|
ip: ""
|
||||||
|
prefix: ""
|
||||||
|
gateway: ""
|
||||||
|
dns:
|
||||||
|
servers: []
|
||||||
|
search: []
|
||||||
|
path: ""
|
||||||
|
packages: []
|
||||||
|
disks: []
|
||||||
|
user:
|
||||||
|
name: ""
|
||||||
|
password: ""
|
||||||
|
key: ""
|
||||||
|
root:
|
||||||
|
password: ""
|
||||||
|
luks:
|
||||||
|
enabled: false
|
||||||
|
passphrase: ""
|
||||||
|
mapper: "SYSTEM_DECRYPTED"
|
||||||
|
auto: true
|
||||||
|
method: "tpm2"
|
||||||
|
tpm2:
|
||||||
|
device: "auto"
|
||||||
|
pcrs: ""
|
||||||
|
keysize: 64
|
||||||
|
options: "discard,tries=3"
|
||||||
|
type: "luks2"
|
||||||
|
cipher: "aes-xts-plain64"
|
||||||
|
hash: "sha512"
|
||||||
|
iter: 4000
|
||||||
|
bits: 512
|
||||||
|
pbkdf: "argon2id"
|
||||||
|
urandom: true
|
||||||
|
verify: true
|
||||||
|
features:
|
||||||
|
cis:
|
||||||
|
enabled: false
|
||||||
|
selinux:
|
||||||
|
enabled: true
|
||||||
|
firewall:
|
||||||
|
enabled: true
|
||||||
|
backend: "firewalld" # firewalld|ufw
|
||||||
|
toolkit: "nftables" # nftables|iptables
|
||||||
|
ssh:
|
||||||
|
enabled: true
|
||||||
|
zstd:
|
||||||
|
enabled: true
|
||||||
|
swap:
|
||||||
|
enabled: true
|
||||||
|
banner:
|
||||||
|
motd: false
|
||||||
|
sudo: true
|
||||||
|
chroot:
|
||||||
|
tool: "arch-chroot" # arch-chroot|chroot|systemd-nspawn
|
||||||
|
|
||||||
luks_enabled: false
|
system_disk_defaults:
|
||||||
luks_mapper_name: "SYSTEM_DECRYPTED"
|
size: 0
|
||||||
luks_auto_decrypt: true
|
device: ""
|
||||||
luks_auto_decrypt_method: "tpm2"
|
mount:
|
||||||
luks_tpm2_device: "auto"
|
path: ""
|
||||||
luks_tpm2_pcrs: ""
|
fstype: ""
|
||||||
luks_keyfile_size: 64
|
label: ""
|
||||||
luks_options: "discard,tries=3"
|
opts: "defaults"
|
||||||
luks_type: "luks2"
|
|
||||||
luks_cipher: "aes-xts-plain64"
|
|
||||||
luks_hash: "sha512"
|
|
||||||
luks_iter_time: 4000
|
|
||||||
luks_key_size: 512
|
|
||||||
luks_pbkdf: "argon2id"
|
|
||||||
luks_use_urandom: true
|
|
||||||
luks_verify_passphrase: true
|
|
||||||
|
|||||||
22
roles/global_defaults/tasks/hypervisor.yml
Normal file
22
roles/global_defaults/tasks/hypervisor.yml
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
---
|
||||||
|
- name: Ensure hypervisor input is a dictionary
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
hypervisor: "{{ hypervisor | default({}) }}"
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: Validate hypervisor input
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- hypervisor is mapping
|
||||||
|
- hypervisor.type is defined
|
||||||
|
- hypervisor.type | string | length > 0
|
||||||
|
fail_msg: "hypervisor must be a dictionary and hypervisor.type must be set (e.g. libvirt|proxmox|vmware|xen|none)."
|
||||||
|
quiet: true
|
||||||
|
|
||||||
|
- name: Normalize hypervisor configuration
|
||||||
|
vars:
|
||||||
|
merged: "{{ hypervisor_defaults | combine(hypervisor, recursive=True) }}"
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
hypervisor_cfg: "{{ merged }}"
|
||||||
|
hypervisor_type: "{{ merged.type | string | lower }}"
|
||||||
|
changed_when: false
|
||||||
@@ -4,111 +4,76 @@
|
|||||||
msg: Global defaults loaded.
|
msg: Global defaults loaded.
|
||||||
changed_when: false
|
changed_when: false
|
||||||
|
|
||||||
|
- name: Normalize hypervisor inputs
|
||||||
|
ansible.builtin.include_tasks: hypervisor.yml
|
||||||
|
|
||||||
|
- name: Normalize system inputs
|
||||||
|
ansible.builtin.include_tasks: system.yml
|
||||||
|
|
||||||
- name: Validate variables
|
- name: Validate variables
|
||||||
ansible.builtin.assert:
|
ansible.builtin.include_tasks: validation.yml
|
||||||
that:
|
|
||||||
- install_type is defined and install_type in ["virtual", "physical"]
|
|
||||||
- hypervisor in ["libvirt", "proxmox", "vmware", "none"]
|
|
||||||
- >-
|
|
||||||
install_type is defined and (
|
|
||||||
install_type == "physical"
|
|
||||||
or hypervisor in ["libvirt", "proxmox", "vmware"]
|
|
||||||
)
|
|
||||||
- filesystem is defined and filesystem in ["btrfs", "ext4", "xfs"]
|
|
||||||
- install_drive is defined and install_drive | length > 0
|
|
||||||
- hostname is defined and hostname | length > 0
|
|
||||||
- >-
|
|
||||||
os is defined and os in [
|
|
||||||
"archlinux", "almalinux", "debian11", "debian12", "debian13", "fedora",
|
|
||||||
"rhel8", "rhel9", "rhel10", "rocky", "ubuntu", "ubuntu-lts"
|
|
||||||
]
|
|
||||||
- >-
|
|
||||||
os is defined and (
|
|
||||||
os not in ["rhel8", "rhel9", "rhel10"]
|
|
||||||
or (rhel_iso is defined and rhel_iso | length > 0)
|
|
||||||
)
|
|
||||||
- >-
|
|
||||||
install_type is defined and (
|
|
||||||
install_type == "physical"
|
|
||||||
or (boot_iso is defined and boot_iso | length > 0)
|
|
||||||
)
|
|
||||||
- >-
|
|
||||||
install_type is defined and (
|
|
||||||
install_type == "physical"
|
|
||||||
or (vm_cpus is defined and (vm_cpus | int) > 0)
|
|
||||||
)
|
|
||||||
- >-
|
|
||||||
install_type is defined and (
|
|
||||||
install_type == "physical"
|
|
||||||
or (vm_size is defined and (vm_size | float) > 0)
|
|
||||||
)
|
|
||||||
- >-
|
|
||||||
install_type is defined and (
|
|
||||||
install_type == "physical"
|
|
||||||
or (vm_memory is defined and (vm_memory | float) > 0)
|
|
||||||
)
|
|
||||||
- >-
|
|
||||||
install_type is defined and filesystem is defined and (
|
|
||||||
install_type == "physical"
|
|
||||||
or (
|
|
||||||
vm_size is defined
|
|
||||||
and (vm_size | int) >= 20
|
|
||||||
)
|
|
||||||
)
|
|
||||||
- >-
|
|
||||||
install_type is defined and (
|
|
||||||
install_type == "physical"
|
|
||||||
or (
|
|
||||||
vm_size is defined
|
|
||||||
and vm_memory is defined
|
|
||||||
and filesystem is defined
|
|
||||||
and (
|
|
||||||
filesystem != "btrfs"
|
|
||||||
or (
|
|
||||||
(vm_size | float)
|
|
||||||
>= (
|
|
||||||
(vm_memory | float / 1024 >= 16.0)
|
|
||||||
| ternary(
|
|
||||||
(vm_memory | float / 2048),
|
|
||||||
[vm_memory | float / 1024, 4.0] | max
|
|
||||||
)
|
|
||||||
+ 5.5
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
- >-
|
|
||||||
vm_ip is not defined
|
|
||||||
or vm_ip | length == 0
|
|
||||||
or (vm_nms is defined and (vm_nms | int) > 0)
|
|
||||||
fail_msg: Invalid input specified, please try again.
|
|
||||||
|
|
||||||
- name: Set OS family flags
|
- name: Set OS family flags
|
||||||
ansible.builtin.set_fact:
|
ansible.builtin.set_fact:
|
||||||
is_rhel: "{{ os | lower in ['almalinux', 'fedora', 'rhel8', 'rhel9', 'rhel10', 'rocky'] }}"
|
is_rhel: "{{ os | lower in ['almalinux', 'fedora', 'rhel', 'rocky'] }}"
|
||||||
is_debian: "{{ os | lower in ['debian11', 'debian12', 'debian13', 'ubuntu', 'ubuntu-lts'] }}"
|
is_debian: "{{ os | lower in ['debian', 'ubuntu', 'ubuntu-lts'] }}"
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: Normalize OS version for keying
|
||||||
|
when:
|
||||||
|
- os_version is defined
|
||||||
|
- (os_version | string | length) > 0
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
os_version_major: "{{ (os_version | string).split('.')[0] }}"
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: Resolve final OS key with version
|
||||||
|
when:
|
||||||
|
- os_version is defined
|
||||||
|
- (os_version | string | length) > 0
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
os_resolved: >-
|
||||||
|
{{
|
||||||
|
'debian' + os_version | string if os == 'debian'
|
||||||
|
else 'fedora' + os_version | string if os == 'fedora'
|
||||||
|
else 'rocky' + os_version_major if os == 'rocky'
|
||||||
|
else 'almalinux' + os_version_major if os == 'almalinux'
|
||||||
|
else 'rhel' + os_version_major if os == 'rhel'
|
||||||
|
else os
|
||||||
|
}}
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: Set chroot command wrapper
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
chroot_command: >-
|
||||||
|
{{
|
||||||
|
'systemd-nspawn -D /mnt'
|
||||||
|
if (system_cfg.features.chroot.tool | default('arch-chroot')) == 'systemd-nspawn'
|
||||||
|
else (system_cfg.features.chroot.tool | default('arch-chroot')) ~ ' /mnt'
|
||||||
|
}}
|
||||||
changed_when: false
|
changed_when: false
|
||||||
|
|
||||||
- name: Set Python interpreter for RHEL-based installers
|
- name: Set Python interpreter for RHEL-based installers
|
||||||
when:
|
when:
|
||||||
- ansible_python_interpreter is not defined
|
- ansible_python_interpreter is not defined
|
||||||
- os | lower in ["almalinux", "rhel8", "rhel9", "rhel10", "rocky"]
|
- is_rhel | bool
|
||||||
ansible.builtin.set_fact:
|
ansible.builtin.set_fact:
|
||||||
ansible_python_interpreter: /usr/bin/python3
|
ansible_python_interpreter: /usr/bin/python3
|
||||||
changed_when: false
|
changed_when: false
|
||||||
|
|
||||||
- name: Set SSH access
|
- name: Set SSH access
|
||||||
when:
|
when:
|
||||||
- install_type == "virtual"
|
- system_cfg.type == "virtual"
|
||||||
- hypervisor != "vmware"
|
- hypervisor_type != "vmware"
|
||||||
ansible.builtin.set_fact:
|
ansible.builtin.set_fact:
|
||||||
ansible_user: "{{ user_name }}"
|
ansible_user: "{{ system_cfg.user.name }}"
|
||||||
ansible_password: "{{ user_password }}"
|
ansible_password: "{{ system_cfg.user.password }}"
|
||||||
ansible_become_password: "{{ user_password }}"
|
ansible_become_password: "{{ system_cfg.user.password }}"
|
||||||
ansible_ssh_extra_args: "-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no"
|
ansible_ssh_extra_args: "-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no"
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
- name: Set connection for VMware
|
- name: Set connection for VMware
|
||||||
when: hypervisor == "vmware"
|
when: hypervisor_type == "vmware"
|
||||||
ansible.builtin.set_fact:
|
ansible.builtin.set_fact:
|
||||||
ansible_connection: vmware_tools
|
ansible_connection: vmware_tools
|
||||||
|
changed_when: false
|
||||||
|
|||||||
257
roles/global_defaults/tasks/system.yml
Normal file
257
roles/global_defaults/tasks/system.yml
Normal file
@@ -0,0 +1,257 @@
|
|||||||
|
---
|
||||||
|
- name: Ensure system input is a dictionary
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
system: "{{ system | default({}) }}"
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: Validate system input types
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- system is mapping
|
||||||
|
- system.dns is not defined or system.dns is mapping
|
||||||
|
- system.user is not defined or system.user is mapping
|
||||||
|
- system.root is not defined or system.root is mapping
|
||||||
|
- system.luks is not defined or system.luks is mapping
|
||||||
|
- system.features is not defined or system.features is mapping
|
||||||
|
fail_msg: "system and its nested keys (dns, user, root, luks, features) must be dictionaries."
|
||||||
|
quiet: true
|
||||||
|
|
||||||
|
- name: Validate system features input types
|
||||||
|
when: system.features is defined
|
||||||
|
loop: "{{ system_defaults.features | dict2items | map(attribute='key') | list }}"
|
||||||
|
loop_control:
|
||||||
|
label: "system.features.{{ item }}"
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- (system.features[item] | default({})) is mapping
|
||||||
|
fail_msg: "system.features.{{ item }} must be a dictionary."
|
||||||
|
quiet: true
|
||||||
|
|
||||||
|
- name: Validate system LUKS TPM2 input type
|
||||||
|
when: system.luks is defined and system.luks is mapping
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- system.luks.tpm2 is not defined or system.luks.tpm2 is mapping
|
||||||
|
fail_msg: "system.luks.tpm2 must be a dictionary."
|
||||||
|
quiet: true
|
||||||
|
|
||||||
|
- name: Build normalized system configuration
|
||||||
|
vars:
|
||||||
|
system_raw: "{{ system_defaults | combine(system, recursive=True) }}"
|
||||||
|
system_type: "{{ system_raw.type | string | lower }}"
|
||||||
|
system_os_input: "{{ system_raw.os | default('') | string | lower }}"
|
||||||
|
system_name: >-
|
||||||
|
{{
|
||||||
|
system_raw.name | string | trim
|
||||||
|
if (system_raw.name | default('') | string | trim | length) > 0
|
||||||
|
else inventory_hostname
|
||||||
|
}}
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
system_cfg:
|
||||||
|
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 }}"
|
||||||
|
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: "{{ system_raw.network | default('') | string }}"
|
||||||
|
vlan: "{{ system_raw.vlan | default('') | string }}"
|
||||||
|
ip: "{{ system_raw.ip | default('') | string }}"
|
||||||
|
prefix: >-
|
||||||
|
{{
|
||||||
|
(system_raw.prefix | int)
|
||||||
|
if (system_raw.prefix | default('') | string | length) > 0
|
||||||
|
else ''
|
||||||
|
}}
|
||||||
|
gateway: "{{ system_raw.gateway | default('') | string }}"
|
||||||
|
dns:
|
||||||
|
servers: >-
|
||||||
|
{{
|
||||||
|
(
|
||||||
|
system_raw.dns.servers
|
||||||
|
if system_raw.dns.servers is iterable and system_raw.dns.servers is not string
|
||||||
|
else (system_raw.dns.servers | string).split(',')
|
||||||
|
)
|
||||||
|
| map('trim')
|
||||||
|
| reject('equalto', '')
|
||||||
|
| list
|
||||||
|
}}
|
||||||
|
search: >-
|
||||||
|
{{
|
||||||
|
(
|
||||||
|
system_raw.dns.search
|
||||||
|
if system_raw.dns.search is iterable and system_raw.dns.search is not string
|
||||||
|
else (system_raw.dns.search | string).split(',')
|
||||||
|
)
|
||||||
|
| map('trim')
|
||||||
|
| reject('equalto', '')
|
||||||
|
| list
|
||||||
|
}}
|
||||||
|
path: "{{ system_raw.path | default('') | string }}"
|
||||||
|
packages: >-
|
||||||
|
{{
|
||||||
|
(
|
||||||
|
system_raw.packages
|
||||||
|
if system_raw.packages is iterable and system_raw.packages is not string
|
||||||
|
else (system_raw.packages | string).split(',')
|
||||||
|
)
|
||||||
|
| map('trim')
|
||||||
|
| reject('equalto', '')
|
||||||
|
| list
|
||||||
|
}}
|
||||||
|
disks: "{{ system_raw.disks | default([]) }}"
|
||||||
|
user:
|
||||||
|
name: "{{ system_raw.user.name | string }}"
|
||||||
|
password: "{{ system_raw.user.password | string }}"
|
||||||
|
key: "{{ system_raw.user.key | string }}"
|
||||||
|
root:
|
||||||
|
password: "{{ system_raw.root.password | string }}"
|
||||||
|
luks:
|
||||||
|
enabled: "{{ system_raw.luks.enabled | bool }}"
|
||||||
|
passphrase: "{{ system_raw.luks.passphrase | string }}"
|
||||||
|
mapper: "{{ system_raw.luks.mapper | string }}"
|
||||||
|
auto: "{{ system_raw.luks.auto | bool }}"
|
||||||
|
method: "{{ system_raw.luks.method | string | lower }}"
|
||||||
|
tpm2:
|
||||||
|
device: "{{ system_raw.luks.tpm2.device | string }}"
|
||||||
|
pcrs: "{{ system_raw.luks.tpm2.pcrs | string }}"
|
||||||
|
keysize: "{{ system_raw.luks.keysize | int }}"
|
||||||
|
options: "{{ system_raw.luks.options | string }}"
|
||||||
|
type: "{{ system_raw.luks.type | string }}"
|
||||||
|
cipher: "{{ system_raw.luks.cipher | string }}"
|
||||||
|
hash: "{{ system_raw.luks.hash | string }}"
|
||||||
|
iter: "{{ system_raw.luks.iter | int }}"
|
||||||
|
bits: "{{ system_raw.luks.bits | int }}"
|
||||||
|
pbkdf: "{{ system_raw.luks.pbkdf | string }}"
|
||||||
|
urandom: "{{ system_raw.luks.urandom | bool }}"
|
||||||
|
verify: "{{ system_raw.luks.verify | bool }}"
|
||||||
|
features:
|
||||||
|
cis:
|
||||||
|
enabled: "{{ system_raw.features.cis.enabled | bool }}"
|
||||||
|
selinux:
|
||||||
|
enabled: "{{ system_raw.features.selinux.enabled | bool }}"
|
||||||
|
firewall:
|
||||||
|
enabled: "{{ system_raw.features.firewall.enabled | bool }}"
|
||||||
|
backend: "{{ system_raw.features.firewall.backend | string | lower }}"
|
||||||
|
toolkit: "{{ system_raw.features.firewall.toolkit | string | lower }}"
|
||||||
|
ssh:
|
||||||
|
enabled: "{{ system_raw.features.ssh.enabled | bool }}"
|
||||||
|
zstd:
|
||||||
|
enabled: "{{ system_raw.features.zstd.enabled | bool }}"
|
||||||
|
swap:
|
||||||
|
enabled: "{{ system_raw.features.swap.enabled | bool }}"
|
||||||
|
banner:
|
||||||
|
motd: "{{ system_raw.features.banner.motd | bool }}"
|
||||||
|
sudo: "{{ system_raw.features.banner.sudo | bool }}"
|
||||||
|
chroot:
|
||||||
|
tool: "{{ system_raw.features.chroot.tool | string }}"
|
||||||
|
hostname: "{{ system_name }}"
|
||||||
|
os: "{{ system_os_input if system_os_input | length > 0 else ('archlinux' if system_type == 'physical' else '') }}"
|
||||||
|
os_version: "{{ system_raw.version | default('') | string }}"
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: Normalize system disks input
|
||||||
|
vars:
|
||||||
|
system_disks: "{{ system_cfg.disks | default([]) }}"
|
||||||
|
system_disk_letter_map: "abcdefghijklmnopqrstuvwxyz"
|
||||||
|
system_disk_device_prefix: >-
|
||||||
|
{{
|
||||||
|
{'libvirt': '/dev/vd', 'xen': '/dev/xvd', 'proxmox': '/dev/sd', 'vmware': '/dev/sd'}.get(hypervisor_type, '')
|
||||||
|
if system_cfg.type == 'virtual'
|
||||||
|
else ''
|
||||||
|
}}
|
||||||
|
block:
|
||||||
|
- name: Validate system disks structure
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- system_disks is sequence
|
||||||
|
- (system_disks | length) <= 26
|
||||||
|
fail_msg: "system.disks must be a list with at most 26 entries."
|
||||||
|
quiet: true
|
||||||
|
|
||||||
|
- name: Validate system disk entries
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- item is mapping
|
||||||
|
- item.mount is not defined or item.mount is mapping
|
||||||
|
fail_msg: "Each disk entry must be a dictionary, and disk.mount (if set) must be a dictionary."
|
||||||
|
quiet: true
|
||||||
|
loop: "{{ system_disks }}"
|
||||||
|
loop_control:
|
||||||
|
label: "{{ item | to_json }}"
|
||||||
|
|
||||||
|
- name: Initialize normalized disk list
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
system_disks_cfg: []
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: Build normalized system disk configuration
|
||||||
|
vars:
|
||||||
|
disk_idx: "{{ ansible_loop.index0 }}"
|
||||||
|
disk_letter: "{{ system_disk_letter_map[disk_idx] }}"
|
||||||
|
disk_cfg_base: "{{ system_disk_defaults | combine(item, recursive=True) }}"
|
||||||
|
disk_mount: "{{ system_disk_defaults.mount | combine((disk_cfg_base.mount | default({})), recursive=True) }}"
|
||||||
|
disk_mount_path: "{{ (disk_mount.path | default('') | string) | trim }}"
|
||||||
|
disk_mount_fstype: >-
|
||||||
|
{{
|
||||||
|
disk_mount.fstype
|
||||||
|
if (disk_mount.fstype | default('') | string | length) > 0
|
||||||
|
else ('ext4' if disk_mount_path | length > 0 else '')
|
||||||
|
}}
|
||||||
|
disk_device: >-
|
||||||
|
{{
|
||||||
|
disk_cfg_base.device
|
||||||
|
if (disk_cfg_base.device | string | length) > 0
|
||||||
|
else (
|
||||||
|
(system_disk_device_prefix ~ disk_letter)
|
||||||
|
if system_cfg.type == 'virtual'
|
||||||
|
else ''
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
disk_partition: >-
|
||||||
|
{{
|
||||||
|
disk_device ~ ('p1' if (disk_device | regex_search('\\d$')) else '1')
|
||||||
|
if disk_device | length > 0
|
||||||
|
else ''
|
||||||
|
}}
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
system_disks_cfg: >-
|
||||||
|
{{
|
||||||
|
system_disks_cfg + [
|
||||||
|
disk_cfg_base
|
||||||
|
| combine(
|
||||||
|
{
|
||||||
|
'device': disk_device,
|
||||||
|
'mount': {
|
||||||
|
'path': disk_mount_path,
|
||||||
|
'fstype': disk_mount_fstype,
|
||||||
|
'label': disk_mount.label | default('') | string,
|
||||||
|
'opts': disk_mount.opts | default('defaults') | string
|
||||||
|
},
|
||||||
|
'partition': disk_partition
|
||||||
|
},
|
||||||
|
recursive=True
|
||||||
|
)
|
||||||
|
]
|
||||||
|
}}
|
||||||
|
loop: "{{ system_disks }}"
|
||||||
|
loop_control:
|
||||||
|
loop_var: item
|
||||||
|
extended: true
|
||||||
|
label: "{{ item | to_json }}"
|
||||||
|
|
||||||
|
- name: Update system configuration with normalized disks
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
system_cfg: "{{ system_cfg | combine({'disks': system_disks_cfg}, recursive=True) }}"
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: Set install_drive from primary disk
|
||||||
|
when:
|
||||||
|
- system_disks_cfg | length > 0
|
||||||
|
- system_disks_cfg[0].device | string | length > 0
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
install_drive: "{{ system_disks_cfg[0].device }}"
|
||||||
|
changed_when: false
|
||||||
331
roles/global_defaults/tasks/validation.yml
Normal file
331
roles/global_defaults/tasks/validation.yml
Normal file
@@ -0,0 +1,331 @@
|
|||||||
|
---
|
||||||
|
- name: Validate core variables
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- system_cfg is defined
|
||||||
|
- system_cfg is mapping
|
||||||
|
- system_cfg.type is defined
|
||||||
|
- system_cfg.type in ["virtual", "physical"]
|
||||||
|
- hypervisor_cfg is defined
|
||||||
|
- hypervisor_cfg is mapping
|
||||||
|
- hypervisor_type is defined
|
||||||
|
- hypervisor_type in ["libvirt", "proxmox", "vmware", "xen", "none"]
|
||||||
|
- system_cfg.filesystem is defined
|
||||||
|
- system_cfg.filesystem in ["btrfs", "ext4", "xfs"]
|
||||||
|
- install_drive is defined
|
||||||
|
- install_drive | string | length > 0
|
||||||
|
- hostname is defined
|
||||||
|
- hostname | string | length > 0
|
||||||
|
fail_msg: Invalid core variables were specified, please check your inventory/vars.
|
||||||
|
quiet: true
|
||||||
|
|
||||||
|
- name: Validate hypervisor relationship
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- system_cfg.type == "physical" or hypervisor_type in ["libvirt", "proxmox", "vmware", "xen"]
|
||||||
|
fail_msg: "hypervisor.type must be one of: libvirt, proxmox, vmware, xen when system.type=virtual."
|
||||||
|
quiet: true
|
||||||
|
|
||||||
|
- name: Validate hypervisor schema
|
||||||
|
vars:
|
||||||
|
hypervisor_allowed_keys: "{{ hypervisor_defaults | dict2items | map(attribute='key') | list }}"
|
||||||
|
hypervisor_keys: "{{ (hypervisor | default({})) | dict2items | map(attribute='key') | list }}"
|
||||||
|
hypervisor_unknown_keys: "{{ hypervisor_keys | difference(hypervisor_allowed_keys) }}"
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- hypervisor_unknown_keys | length == 0
|
||||||
|
fail_msg: "Unsupported hypervisor keys: {{ hypervisor_unknown_keys | join(', ') }}"
|
||||||
|
quiet: true
|
||||||
|
|
||||||
|
- name: Validate system schema
|
||||||
|
vars:
|
||||||
|
system_allowed_keys: "{{ system_defaults | dict2items | map(attribute='key') | list }}"
|
||||||
|
system_keys: "{{ (system | default({})) | dict2items | map(attribute='key') | list }}"
|
||||||
|
system_unknown_keys: "{{ system_keys | difference(system_allowed_keys) }}"
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- system_unknown_keys | length == 0
|
||||||
|
fail_msg: "Unsupported system keys: {{ system_unknown_keys | join(', ') }}."
|
||||||
|
quiet: true
|
||||||
|
|
||||||
|
- name: Validate nested system mappings
|
||||||
|
loop:
|
||||||
|
- dns
|
||||||
|
- user
|
||||||
|
- root
|
||||||
|
- luks
|
||||||
|
- features
|
||||||
|
loop_control:
|
||||||
|
label: "{{ item }}"
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- system[item] is not defined or system[item] is mapping
|
||||||
|
fail_msg: "system.{{ item }} must be a dictionary."
|
||||||
|
quiet: true
|
||||||
|
|
||||||
|
- name: Validate system sub-dict schemas
|
||||||
|
loop:
|
||||||
|
- dns
|
||||||
|
- user
|
||||||
|
- root
|
||||||
|
- luks
|
||||||
|
loop_control:
|
||||||
|
label: "system.{{ item }}"
|
||||||
|
vars:
|
||||||
|
sub_input: "{{ (system[item] | default({})) | dict2items | map(attribute='key') | list }}"
|
||||||
|
sub_allowed: "{{ system_defaults[item] | dict2items | map(attribute='key') | list }}"
|
||||||
|
sub_unknown: "{{ sub_input | difference(sub_allowed) }}"
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- sub_unknown | length == 0
|
||||||
|
fail_msg: "Unsupported system.{{ item }} keys: {{ sub_unknown | join(', ') }}"
|
||||||
|
quiet: true
|
||||||
|
|
||||||
|
- name: Validate system.luks.tpm2 schema
|
||||||
|
vars:
|
||||||
|
tpm2_input: >-
|
||||||
|
{{
|
||||||
|
(system.luks if (system.luks is defined and system.luks is mapping) else {}).tpm2
|
||||||
|
| default({})
|
||||||
|
}}
|
||||||
|
tpm2_allowed_keys: "{{ system_defaults.luks.tpm2 | dict2items | map(attribute='key') | list }}"
|
||||||
|
tpm2_unknown: "{{ (tpm2_input | dict2items | map(attribute='key') | list) | difference(tpm2_allowed_keys) }}"
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- system.luks is not defined or system.luks.tpm2 is not defined or system.luks.tpm2 is mapping
|
||||||
|
- tpm2_unknown | length == 0
|
||||||
|
fail_msg: "Unsupported system.luks.tpm2 keys: {{ tpm2_unknown | join(', ') }}"
|
||||||
|
quiet: true
|
||||||
|
|
||||||
|
- name: Validate system.features schema
|
||||||
|
vars:
|
||||||
|
features_allowed_keys: "{{ system_defaults.features | dict2items | map(attribute='key') | list }}"
|
||||||
|
features_unknown: >-
|
||||||
|
{{
|
||||||
|
((system.features | default({})) | dict2items | map(attribute='key') | list)
|
||||||
|
| difference(features_allowed_keys)
|
||||||
|
}}
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- features_unknown | length == 0
|
||||||
|
fail_msg: "Unsupported system.features keys: {{ features_unknown | join(', ') }}"
|
||||||
|
quiet: true
|
||||||
|
|
||||||
|
- name: Validate system.features leaf schemas
|
||||||
|
loop: "{{ system_defaults.features | dict2items }}"
|
||||||
|
loop_control:
|
||||||
|
label: "system.features.{{ item.key }}"
|
||||||
|
vars:
|
||||||
|
feature_input: "{{ (system.features | default({}))[item.key] | default({}) }}"
|
||||||
|
feature_allowed_keys: "{{ item.value | dict2items | map(attribute='key') | list }}"
|
||||||
|
feature_unknown: "{{ (feature_input | dict2items | map(attribute='key') | list) | difference(feature_allowed_keys) }}"
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- feature_input is mapping
|
||||||
|
- feature_unknown | length == 0
|
||||||
|
fail_msg: "Unsupported system.features.{{ item.key }} keys: {{ feature_unknown | join(', ') }}"
|
||||||
|
quiet: true
|
||||||
|
|
||||||
|
- name: Validate OS and version inputs
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- os is defined
|
||||||
|
- os in ["almalinux", "alpine", "archlinux", "debian", "fedora", "opensuse", "rhel", "rocky", "ubuntu", "ubuntu-lts", "void"]
|
||||||
|
- >-
|
||||||
|
os not in ["debian", "fedora", "rocky", "almalinux", "rhel"]
|
||||||
|
or (os_version is defined and (os_version | string | length) > 0)
|
||||||
|
- >-
|
||||||
|
os_version is not defined or (os_version | string | length) == 0
|
||||||
|
or (
|
||||||
|
os == "debian" and (os_version | string) in ["10", "11", "12", "13", "unstable"]
|
||||||
|
) or (
|
||||||
|
os == "fedora" and (os_version | string) in ["40", "41", "42", "43"]
|
||||||
|
) or (
|
||||||
|
os in ["rocky", "almalinux"]
|
||||||
|
and (os_version | string) is match("^(8|9|10)(\\.\\d+)?$")
|
||||||
|
) or (
|
||||||
|
os == "rhel"
|
||||||
|
and (os_version | string) is match("^(8|9|10)(\\.\\d+)?$")
|
||||||
|
) or (
|
||||||
|
os in ["alpine", "archlinux", "opensuse", "ubuntu", "ubuntu-lts", "void"]
|
||||||
|
)
|
||||||
|
fail_msg: "Invalid os/version specified. Please check README.md for supported values."
|
||||||
|
quiet: true
|
||||||
|
|
||||||
|
- name: Validate RHEL ISO requirement
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- os != "rhel" or (rhel_iso is defined and (rhel_iso | string | length) > 0)
|
||||||
|
fail_msg: "rhel_iso is required when os=rhel."
|
||||||
|
quiet: true
|
||||||
|
|
||||||
|
- name: Validate Proxmox hypervisor inputs
|
||||||
|
when:
|
||||||
|
- system_cfg.type == "virtual"
|
||||||
|
- hypervisor_type == "proxmox"
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- hypervisor_cfg.url | string | length > 0
|
||||||
|
- hypervisor_cfg.username | string | length > 0
|
||||||
|
- hypervisor_cfg.password | string | length > 0
|
||||||
|
- hypervisor_cfg.host | string | length > 0
|
||||||
|
- hypervisor_cfg.storage | string | length > 0
|
||||||
|
- system_cfg.id | string | length > 0
|
||||||
|
- system_cfg.network | string | length > 0
|
||||||
|
fail_msg: "Missing required Proxmox inputs. Define hypervisor.(url,username,password,host,storage) and system.(id,network)."
|
||||||
|
quiet: true
|
||||||
|
|
||||||
|
- name: Validate VMware hypervisor inputs
|
||||||
|
when:
|
||||||
|
- system_cfg.type == "virtual"
|
||||||
|
- hypervisor_type == "vmware"
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- hypervisor_cfg.url | string | length > 0
|
||||||
|
- hypervisor_cfg.username | string | length > 0
|
||||||
|
- hypervisor_cfg.password | string | length > 0
|
||||||
|
- hypervisor_cfg.datacenter | string | length > 0
|
||||||
|
- hypervisor_cfg.cluster | string | length > 0
|
||||||
|
- hypervisor_cfg.storage | string | length > 0
|
||||||
|
- system_cfg.network | string | length > 0
|
||||||
|
fail_msg: "Missing required VMware inputs. Define hypervisor.(url,username,password,datacenter,cluster,storage) and system.network."
|
||||||
|
quiet: true
|
||||||
|
|
||||||
|
- name: Validate Xen hypervisor inputs
|
||||||
|
when:
|
||||||
|
- system_cfg.type == "virtual"
|
||||||
|
- hypervisor_type == "xen"
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- system_cfg.network | string | length > 0
|
||||||
|
fail_msg: "Missing required Xen inputs. Define system.network."
|
||||||
|
quiet: true
|
||||||
|
|
||||||
|
- name: Validate virtual installer ISO requirement
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- system_cfg.type == "physical" or (boot_iso is defined and (boot_iso | string | length) > 0)
|
||||||
|
fail_msg: "boot_iso is required when system.type=virtual."
|
||||||
|
quiet: true
|
||||||
|
|
||||||
|
- name: Validate firewall and feature flags
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- system_cfg.features.firewall.backend is defined
|
||||||
|
- system_cfg.features.firewall.backend in ["firewalld", "ufw"]
|
||||||
|
- system_cfg.features.firewall.toolkit is defined
|
||||||
|
- system_cfg.features.firewall.toolkit in ["iptables", "nftables"]
|
||||||
|
- system_cfg.features.firewall.enabled is defined
|
||||||
|
- system_cfg.features.banner.motd is defined
|
||||||
|
- system_cfg.features.banner.sudo is defined
|
||||||
|
- system_cfg.luks.enabled is defined
|
||||||
|
- system_cfg.features.chroot.tool is defined
|
||||||
|
- system_cfg.features.chroot.tool in ["arch-chroot", "chroot", "systemd-nspawn"]
|
||||||
|
fail_msg: Invalid feature flags were specified, please check your inventory/vars.
|
||||||
|
quiet: true
|
||||||
|
|
||||||
|
- name: Validate virtual system sizing
|
||||||
|
when: system_cfg.type == "virtual"
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- system_cfg.cpus is defined and (system_cfg.cpus | int) > 0
|
||||||
|
- system_cfg.memory is defined and (system_cfg.memory | int) > 0
|
||||||
|
- system_cfg.disks is defined and (system_cfg.disks | length) > 0
|
||||||
|
- (system_cfg.disks[0].size | float) > 0
|
||||||
|
- (system_cfg.disks[0].size | float) >= 20
|
||||||
|
- >-
|
||||||
|
system_cfg.filesystem != "btrfs"
|
||||||
|
or (
|
||||||
|
(system_cfg.disks[0].size | float)
|
||||||
|
>= (
|
||||||
|
(
|
||||||
|
(system_cfg.memory | float / 1024 >= 16.0)
|
||||||
|
| ternary(
|
||||||
|
(system_cfg.memory | float / 2048),
|
||||||
|
[system_cfg.memory | float / 1024, 4.0] | max
|
||||||
|
)
|
||||||
|
)
|
||||||
|
+ 5.5
|
||||||
|
)
|
||||||
|
)
|
||||||
|
fail_msg: "Invalid system sizing. Check system.cpus, system.memory, and system.disks[0].size."
|
||||||
|
quiet: true
|
||||||
|
|
||||||
|
- name: Validate all virtual disks have a positive size
|
||||||
|
when: system_cfg.type == "virtual"
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- item.size is defined
|
||||||
|
- (item.size | float) > 0
|
||||||
|
fail_msg: "Each system disk must have a positive size when system.type=virtual: {{ item | to_json }}"
|
||||||
|
quiet: true
|
||||||
|
loop: "{{ system_cfg.disks | default([]) }}"
|
||||||
|
loop_control:
|
||||||
|
label: "{{ item | to_json }}"
|
||||||
|
|
||||||
|
- name: Validate primary disk mount is not used
|
||||||
|
when:
|
||||||
|
- system_cfg.disks is defined
|
||||||
|
- system_cfg.disks | length > 0
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- (system_cfg.disks[0].mount.path | default('') | string | trim) == ''
|
||||||
|
fail_msg: "system.disks[0].mount.path must be empty; use system.disks[1:] for additional mounts."
|
||||||
|
quiet: true
|
||||||
|
|
||||||
|
- name: Validate disk mountpoint inputs
|
||||||
|
vars:
|
||||||
|
system_disk_mounts: >-
|
||||||
|
{{
|
||||||
|
(system_cfg.disks | default([]))
|
||||||
|
| map(attribute='mount')
|
||||||
|
| map(attribute='path')
|
||||||
|
| map('string')
|
||||||
|
| map('trim')
|
||||||
|
| reject('equalto', '')
|
||||||
|
| list
|
||||||
|
}}
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- system_disk_mounts | length == (system_disk_mounts | unique | list | length)
|
||||||
|
fail_msg: "Duplicate disk mountpoints found in system.disks."
|
||||||
|
quiet: true
|
||||||
|
|
||||||
|
- name: Validate disk mount definitions
|
||||||
|
when: system_cfg.disks is defined
|
||||||
|
vars:
|
||||||
|
reserved_mounts:
|
||||||
|
- /boot
|
||||||
|
- /boot/efi
|
||||||
|
- /home
|
||||||
|
- /swap
|
||||||
|
- /var
|
||||||
|
- /var/cache/pacman/pkg
|
||||||
|
- /var/log
|
||||||
|
- /var/log/audit
|
||||||
|
disk_mount: "{{ (item.mount.path | default('') | string) | trim }}"
|
||||||
|
disk_fstype: "{{ (item.mount.fstype | default('') | string) | trim }}"
|
||||||
|
disk_device: "{{ (item.device | default('') | string) | trim }}"
|
||||||
|
disk_size: "{{ item.size | default(0) }}"
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- disk_mount == "" or disk_mount.startswith("/")
|
||||||
|
- disk_mount == "" or disk_mount != "/"
|
||||||
|
- disk_mount == "" or disk_mount not in reserved_mounts
|
||||||
|
- disk_mount == "" or disk_fstype in ["btrfs", "ext4", "xfs"]
|
||||||
|
- disk_mount == "" or system_cfg.type == "virtual" or (disk_device | length) > 0
|
||||||
|
- disk_mount == "" or system_cfg.type != "virtual" or (disk_size | float) > 0
|
||||||
|
fail_msg: "Invalid system disk entry: {{ item | to_json }}"
|
||||||
|
quiet: true
|
||||||
|
loop: "{{ system_cfg.disks }}"
|
||||||
|
loop_control:
|
||||||
|
label: "{{ item | to_json }}"
|
||||||
|
|
||||||
|
- name: Validate static IP requirements
|
||||||
|
when: system_cfg.ip is defined and (system_cfg.ip | string | length) > 0
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- system_cfg.prefix is defined
|
||||||
|
- (system_cfg.prefix | int) > 0
|
||||||
|
fail_msg: "system.prefix is required when system.ip is set."
|
||||||
|
quiet: true
|
||||||
@@ -1,22 +1,22 @@
|
|||||||
---
|
---
|
||||||
partitioning_luks_enabled: "{{ luks_enabled | bool }}"
|
partitioning_luks_enabled: "{{ system_cfg.luks.enabled | bool }}"
|
||||||
partitioning_luks_passphrase: "{{ luks_passphrase }}"
|
partitioning_luks_passphrase: "{{ system_cfg.luks.passphrase }}"
|
||||||
partitioning_luks_mapper_name: "{{ luks_mapper_name }}"
|
partitioning_luks_mapper_name: "{{ system_cfg.luks.mapper }}"
|
||||||
partitioning_luks_type: "{{ luks_type }}"
|
partitioning_luks_type: "{{ system_cfg.luks.type }}"
|
||||||
partitioning_luks_cipher: "{{ luks_cipher }}"
|
partitioning_luks_cipher: "{{ system_cfg.luks.cipher }}"
|
||||||
partitioning_luks_hash: "{{ luks_hash }}"
|
partitioning_luks_hash: "{{ system_cfg.luks.hash }}"
|
||||||
partitioning_luks_iter_time: "{{ luks_iter_time }}"
|
partitioning_luks_iter_time: "{{ system_cfg.luks.iter }}"
|
||||||
partitioning_luks_key_size: "{{ luks_key_size }}"
|
partitioning_luks_key_size: "{{ system_cfg.luks.bits }}"
|
||||||
partitioning_luks_pbkdf: "{{ luks_pbkdf }}"
|
partitioning_luks_pbkdf: "{{ system_cfg.luks.pbkdf }}"
|
||||||
partitioning_luks_use_urandom: "{{ luks_use_urandom | bool }}"
|
partitioning_luks_use_urandom: "{{ system_cfg.luks.urandom | bool }}"
|
||||||
partitioning_luks_verify_passphrase: "{{ luks_verify_passphrase | bool }}"
|
partitioning_luks_verify_passphrase: "{{ system_cfg.luks.verify | bool }}"
|
||||||
partitioning_luks_auto_decrypt: "{{ luks_auto_decrypt | bool }}"
|
partitioning_luks_auto_decrypt: "{{ system_cfg.luks.auto | bool }}"
|
||||||
partitioning_luks_auto_decrypt_method: "{{ luks_auto_decrypt_method }}"
|
partitioning_luks_auto_decrypt_method: "{{ system_cfg.luks.method }}"
|
||||||
partitioning_luks_tpm2_device: "{{ luks_tpm2_device }}"
|
partitioning_luks_tpm2_device: "{{ system_cfg.luks.tpm2.device }}"
|
||||||
partitioning_luks_tpm2_pcrs: "{{ luks_tpm2_pcrs }}"
|
partitioning_luks_tpm2_pcrs: "{{ system_cfg.luks.tpm2.pcrs }}"
|
||||||
partitioning_luks_keyfile_size: "{{ luks_keyfile_size }}"
|
partitioning_luks_keyfile_size: "{{ system_cfg.luks.keysize }}"
|
||||||
partitioning_luks_options: "{{ luks_options }}"
|
partitioning_luks_options: "{{ system_cfg.luks.options }}"
|
||||||
partitioning_btrfs_compress_opt: "{{ 'compress=zstd:15' if zstd_enabled | bool else '' }}"
|
partitioning_btrfs_compress_opt: "{{ 'compress=zstd:15' if system_cfg.features.zstd.enabled | bool else '' }}"
|
||||||
partitioning_boot_partition_suffix: 1
|
partitioning_boot_partition_suffix: 1
|
||||||
partitioning_main_partition_suffix: 2
|
partitioning_main_partition_suffix: 2
|
||||||
partitioning_efi_size_mib: 512
|
partitioning_efi_size_mib: 512
|
||||||
@@ -31,8 +31,8 @@ partitioning_separate_boot: >-
|
|||||||
}}
|
}}
|
||||||
partitioning_boot_fs_fstype: >-
|
partitioning_boot_fs_fstype: >-
|
||||||
{{
|
{{
|
||||||
(filesystem | lower)
|
(system_cfg.filesystem | lower)
|
||||||
if (filesystem | lower) != 'btrfs'
|
if (system_cfg.filesystem | lower) != 'btrfs'
|
||||||
else ('xfs' if is_rhel else 'ext4')
|
else ('xfs' if is_rhel else 'ext4')
|
||||||
}}
|
}}
|
||||||
partitioning_boot_fs_partition_suffix: >-
|
partitioning_boot_fs_partition_suffix: >-
|
||||||
@@ -51,7 +51,7 @@ partitioning_efi_mountpoint: >-
|
|||||||
if (partitioning_separate_boot | bool)
|
if (partitioning_separate_boot | bool)
|
||||||
else (
|
else (
|
||||||
'/boot/efi'
|
'/boot/efi'
|
||||||
if is_rhel or (os | lower in ['debian11', 'debian12', 'debian13', 'ubuntu', 'ubuntu-lts'])
|
if is_rhel or (os in ['ubuntu', 'ubuntu-lts'] or (os == 'debian' and (os_version | string) in ['11', '12', '13']))
|
||||||
else '/boot'
|
else '/boot'
|
||||||
)
|
)
|
||||||
}}
|
}}
|
||||||
@@ -114,29 +114,38 @@ partitioning_root_device: >-
|
|||||||
if (partitioning_luks_enabled | bool)
|
if (partitioning_luks_enabled | bool)
|
||||||
else install_drive ~ (partitioning_root_partition_suffix | string)
|
else install_drive ~ (partitioning_root_partition_suffix | string)
|
||||||
}}
|
}}
|
||||||
partitioning_vm_size_effective: >-
|
partitioning_disk_size_gb: >-
|
||||||
{{
|
{{
|
||||||
(
|
(
|
||||||
partitioning_vm_size
|
partitioning_vm_size
|
||||||
if (partitioning_vm_size is defined and (partitioning_vm_size | float) > 0)
|
if (partitioning_vm_size is defined and (partitioning_vm_size | float) > 0)
|
||||||
else (vm_size if vm_size is defined else 0)
|
else (
|
||||||
|
(
|
||||||
|
(system_cfg.disks | default([]) | first | default({})).size
|
||||||
|
if system_cfg is defined
|
||||||
|
else 0
|
||||||
|
) | default(0)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
| float
|
| float
|
||||||
}}
|
}}
|
||||||
partitioning_vm_memory_effective: >-
|
partitioning_memory_mb: >-
|
||||||
{{
|
{{
|
||||||
(
|
(
|
||||||
partitioning_vm_memory
|
partitioning_vm_memory
|
||||||
if (partitioning_vm_memory is defined and (partitioning_vm_memory | float) > 0)
|
if (partitioning_vm_memory is defined and (partitioning_vm_memory | float) > 0)
|
||||||
else (vm_memory if vm_memory is defined else 0)
|
else (
|
||||||
|
(system_cfg.memory if system_cfg is defined else 0)
|
||||||
|
| default(0)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
| float
|
| float
|
||||||
}}
|
}}
|
||||||
partitioning_swap_size_gb: >-
|
partitioning_swap_size_gb: >-
|
||||||
{{
|
{{
|
||||||
((partitioning_vm_memory_effective / 1024) >= 16.0)
|
((partitioning_memory_mb / 1024) >= 16.0)
|
||||||
| ternary(
|
| ternary(
|
||||||
(partitioning_vm_memory_effective / 2048) | int,
|
(partitioning_memory_mb / 2048) | int,
|
||||||
[partitioning_vm_memory_effective / 1024, 4.0] | max | int
|
[partitioning_memory_mb / 1024, 4.0] | max | int
|
||||||
)
|
)
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -41,8 +41,8 @@
|
|||||||
|
|
||||||
- name: Make root subvolumes
|
- name: Make root subvolumes
|
||||||
when:
|
when:
|
||||||
- cis_enabled or item.subvol not in ['var_log_audit']
|
- system_cfg.features.cis.enabled or item.subvol not in ['var_log_audit']
|
||||||
- swap_enabled | bool or item.subvol != 'swap'
|
- system_cfg.features.swap.enabled | bool or item.subvol != 'swap'
|
||||||
ansible.builtin.command: btrfs su cr /mnt/{{ '@' if item.subvol == 'root' else '@' + item.subvol }}
|
ansible.builtin.command: btrfs su cr /mnt/{{ '@' if item.subvol == 'root' else '@' + item.subvol }}
|
||||||
args:
|
args:
|
||||||
creates: /mnt/{{ '@' if item.subvol == 'root' else '@' + item.subvol }}
|
creates: /mnt/{{ '@' if item.subvol == 'root' else '@' + item.subvol }}
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
register: partitioning_btrfs_subvol_result
|
register: partitioning_btrfs_subvol_result
|
||||||
|
|
||||||
- name: Set quotas for subvolumes
|
- name: Set quotas for subvolumes
|
||||||
when: cis_enabled
|
when: system_cfg.features.cis.enabled
|
||||||
ansible.builtin.command: btrfs qgroup limit {{ item.quota }} /mnt/{{ '@' if item.subvol == 'root' else '@' + item.subvol }}
|
ansible.builtin.command: btrfs qgroup limit {{ item.quota }} /mnt/{{ '@' if item.subvol == 'root' else '@' + item.subvol }}
|
||||||
loop:
|
loop:
|
||||||
- { subvol: home, quota: 2G }
|
- { subvol: home, quota: 2G }
|
||||||
@@ -65,7 +65,7 @@
|
|||||||
changed_when: false
|
changed_when: false
|
||||||
|
|
||||||
- name: Create a Btrfs swap file
|
- name: Create a Btrfs swap file
|
||||||
when: swap_enabled | bool
|
when: system_cfg.features.swap.enabled | bool
|
||||||
ansible.builtin.command: >-
|
ansible.builtin.command: >-
|
||||||
btrfs filesystem mkswapfile --size {{ partitioning_swap_size_gb }}g --uuid clear /mnt/@swap/swapfile
|
btrfs filesystem mkswapfile --size {{ partitioning_swap_size_gb }}g --uuid clear /mnt/@swap/swapfile
|
||||||
args:
|
args:
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
- name: Create and format ext4 logical volumes
|
- name: Create and format ext4 logical volumes
|
||||||
when: cis_enabled or item.lv not in ['home', 'var', 'var_log', 'var_log_audit']
|
when: system_cfg.features.cis.enabled or item.lv not in ['home', 'var', 'var_log', 'var_log_audit']
|
||||||
community.general.filesystem:
|
community.general.filesystem:
|
||||||
dev: /dev/sys/{{ item.lv }}
|
dev: /dev/sys/{{ item.lv }}
|
||||||
fstype: ext4
|
fstype: ext4
|
||||||
@@ -13,7 +13,9 @@
|
|||||||
- { lv: var_log_audit }
|
- { lv: var_log_audit }
|
||||||
|
|
||||||
- name: Remove Unsupported features for older Systems
|
- name: Remove Unsupported features for older Systems
|
||||||
when: (os | lower in ['almalinux', 'debian11', 'rhel8', 'rhel9', 'rocky']) and (cis_enabled or item.lv not in ['home', 'var', 'var_log', 'var_log_audit'])
|
when: >
|
||||||
|
(os in ['almalinux', 'rocky', 'rhel'] or (os == 'debian' and (os_version | string) == '11'))
|
||||||
|
and (system_cfg.features.cis.enabled or item.lv not in ['home', 'var', 'var_log', 'var_log_audit'])
|
||||||
ansible.builtin.command: tune2fs -O "^orphan_file,^metadata_csum_seed" "/dev/sys/{{ item.lv }}"
|
ansible.builtin.command: tune2fs -O "^orphan_file,^metadata_csum_seed" "/dev/sys/{{ item.lv }}"
|
||||||
loop:
|
loop:
|
||||||
- { lv: root }
|
- { lv: root }
|
||||||
|
|||||||
85
roles/partitioning/tasks/extra_disks.yml
Normal file
85
roles/partitioning/tasks/extra_disks.yml
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
---
|
||||||
|
- name: Determine additional disks to auto-mount
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
partitioning_extra_disks: >-
|
||||||
|
{{
|
||||||
|
(system_cfg.disks | default([]))[1:]
|
||||||
|
| selectattr('mount.path')
|
||||||
|
| list
|
||||||
|
}}
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: Validate additional disks do not target install_drive
|
||||||
|
when: partitioning_extra_disks | length > 0
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- item.device is defined
|
||||||
|
- item.device | string | length > 0
|
||||||
|
- item.device != install_drive
|
||||||
|
- item.partition is defined
|
||||||
|
- item.partition | string | length > 0
|
||||||
|
- item.mount.fstype is defined
|
||||||
|
- item.mount.fstype in ['btrfs', 'ext4', 'xfs']
|
||||||
|
- item.mount.path is defined
|
||||||
|
- item.mount.path | string | length > 0
|
||||||
|
- item.mount.path.startswith('/')
|
||||||
|
- item.mount.path != '/'
|
||||||
|
fail_msg: "Invalid additional disk definition: {{ item | to_json }}"
|
||||||
|
quiet: true
|
||||||
|
loop: "{{ partitioning_extra_disks }}"
|
||||||
|
loop_control:
|
||||||
|
label: "{{ item | to_json }}"
|
||||||
|
|
||||||
|
- name: Partition additional disks
|
||||||
|
when: partitioning_extra_disks | length > 0
|
||||||
|
community.general.parted:
|
||||||
|
device: "{{ item.device }}"
|
||||||
|
label: gpt
|
||||||
|
number: 1
|
||||||
|
part_start: "1MiB"
|
||||||
|
part_end: "100%"
|
||||||
|
name: "{{ (item.mount.label | default('') | string | length > 0) | ternary(item.mount.label, 'data') }}"
|
||||||
|
state: present
|
||||||
|
loop: "{{ partitioning_extra_disks }}"
|
||||||
|
loop_control:
|
||||||
|
label: "{{ item.device }}"
|
||||||
|
|
||||||
|
- name: Settle partition tables for additional disks
|
||||||
|
when: partitioning_extra_disks | length > 0
|
||||||
|
ansible.builtin.command: udevadm settle
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: Create filesystems on additional disks
|
||||||
|
when: partitioning_extra_disks | length > 0
|
||||||
|
community.general.filesystem:
|
||||||
|
dev: "{{ item.partition }}"
|
||||||
|
fstype: "{{ item.mount.fstype }}"
|
||||||
|
opts: "{{ ('-L ' ~ item.mount.label) if (item.mount.label | default('') | string | length) > 0 else omit }}"
|
||||||
|
force: true
|
||||||
|
loop: "{{ partitioning_extra_disks }}"
|
||||||
|
loop_control:
|
||||||
|
label: "{{ item.partition }}"
|
||||||
|
|
||||||
|
- name: Ensure mount directories exist for additional disks
|
||||||
|
when: partitioning_extra_disks | length > 0
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "/mnt{{ item.mount.path }}"
|
||||||
|
state: directory
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: "0755"
|
||||||
|
loop: "{{ partitioning_extra_disks }}"
|
||||||
|
loop_control:
|
||||||
|
label: "{{ item.mount.path }}"
|
||||||
|
|
||||||
|
- name: Mount additional disks for fstab generation
|
||||||
|
when: partitioning_extra_disks | length > 0
|
||||||
|
ansible.posix.mount:
|
||||||
|
path: "/mnt{{ item.mount.path }}"
|
||||||
|
src: "{{ item.partition }}"
|
||||||
|
fstype: "{{ item.mount.fstype }}"
|
||||||
|
opts: "{{ item.mount.opts | default('defaults') }}"
|
||||||
|
state: mounted
|
||||||
|
loop: "{{ partitioning_extra_disks }}"
|
||||||
|
loop_control:
|
||||||
|
label: "{{ item.mount.path }}"
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
---
|
---
|
||||||
- name: Detect system memory for swap sizing
|
- name: Detect system memory for swap sizing
|
||||||
when:
|
when:
|
||||||
- swap_enabled | bool
|
- system_cfg.features.swap.enabled | bool
|
||||||
- partitioning_vm_memory is not defined or (partitioning_vm_memory | float) <= 0
|
- partitioning_vm_memory is not defined or (partitioning_vm_memory | float) <= 0
|
||||||
- vm_memory is not defined or (vm_memory | float) <= 0
|
- system_cfg is not defined or (system_cfg.memory | default(0) | float) <= 0
|
||||||
block:
|
block:
|
||||||
- name: Read system memory
|
- name: Read system memory
|
||||||
ansible.builtin.command: awk '/MemTotal/ {print int($2/1024)}' /proc/meminfo
|
ansible.builtin.command: awk '/MemTotal/ {print int($2/1024)}' /proc/meminfo
|
||||||
@@ -17,9 +17,8 @@
|
|||||||
|
|
||||||
- name: Set partitioning vm_size for physical installs
|
- name: Set partitioning vm_size for physical installs
|
||||||
when:
|
when:
|
||||||
- install_type == "physical"
|
- system_cfg.type == "physical"
|
||||||
- partitioning_vm_size is not defined or (partitioning_vm_size | float) <= 0
|
- partitioning_vm_size is not defined or (partitioning_vm_size | float) <= 0
|
||||||
- vm_size is not defined or (vm_size | float) <= 0
|
|
||||||
- install_drive | length > 0
|
- install_drive | length > 0
|
||||||
block:
|
block:
|
||||||
- name: Detect install drive size
|
- name: Detect install drive size
|
||||||
@@ -156,15 +155,12 @@
|
|||||||
|
|
||||||
- name: Configure LUKS encryption
|
- name: Configure LUKS encryption
|
||||||
when: partitioning_luks_enabled | bool
|
when: partitioning_luks_enabled | bool
|
||||||
vars:
|
|
||||||
partitioning_luks_passphrase_effective: >-
|
|
||||||
{{ partitioning_luks_passphrase | string }}
|
|
||||||
block:
|
block:
|
||||||
- name: Validate LUKS passphrase
|
- name: Validate LUKS passphrase
|
||||||
ansible.builtin.assert:
|
ansible.builtin.assert:
|
||||||
that:
|
that:
|
||||||
- partitioning_luks_passphrase_effective | length > 0
|
- (partitioning_luks_passphrase | string | length) > 0
|
||||||
fail_msg: luks_passphrase (or partitioning_luks_passphrase) must be set when LUKS is enabled.
|
fail_msg: system.luks.passphrase must be set when LUKS is enabled.
|
||||||
no_log: true
|
no_log: true
|
||||||
|
|
||||||
- name: Ensure LUKS container exists
|
- name: Ensure LUKS container exists
|
||||||
@@ -178,7 +174,7 @@
|
|||||||
pbkdf:
|
pbkdf:
|
||||||
algorithm: "{{ partitioning_luks_pbkdf }}"
|
algorithm: "{{ partitioning_luks_pbkdf }}"
|
||||||
iteration_time: "{{ (partitioning_luks_iter_time | float) / 1000 }}"
|
iteration_time: "{{ (partitioning_luks_iter_time | float) / 1000 }}"
|
||||||
passphrase: "{{ partitioning_luks_passphrase_effective }}"
|
passphrase: "{{ partitioning_luks_passphrase | string }}"
|
||||||
register: partitioning_luks_format_result
|
register: partitioning_luks_format_result
|
||||||
no_log: true
|
no_log: true
|
||||||
|
|
||||||
@@ -207,7 +203,7 @@
|
|||||||
device: "{{ partitioning_luks_device }}"
|
device: "{{ partitioning_luks_device }}"
|
||||||
state: opened
|
state: opened
|
||||||
name: "{{ partitioning_luks_mapper_name }}"
|
name: "{{ partitioning_luks_mapper_name }}"
|
||||||
passphrase: "{{ partitioning_luks_passphrase_effective }}"
|
passphrase: "{{ partitioning_luks_passphrase | string }}"
|
||||||
allow_discards: "{{ 'discard' in (partitioning_luks_options | lower) }}"
|
allow_discards: "{{ 'discard' in (partitioning_luks_options | lower) }}"
|
||||||
register: partitioning_luks_open_result
|
register: partitioning_luks_open_result
|
||||||
no_log: true
|
no_log: true
|
||||||
@@ -235,7 +231,7 @@
|
|||||||
device: "{{ partitioning_luks_device }}"
|
device: "{{ partitioning_luks_device }}"
|
||||||
state: opened
|
state: opened
|
||||||
name: "{{ partitioning_luks_mapper_name }}"
|
name: "{{ partitioning_luks_mapper_name }}"
|
||||||
passphrase: "{{ partitioning_luks_passphrase_effective }}"
|
passphrase: "{{ partitioning_luks_passphrase | string }}"
|
||||||
allow_discards: "{{ 'discard' in (partitioning_luks_options | lower) }}"
|
allow_discards: "{{ 'discard' in (partitioning_luks_options | lower) }}"
|
||||||
register: partitioning_luks_open_retry
|
register: partitioning_luks_open_retry
|
||||||
no_log: true
|
no_log: true
|
||||||
@@ -250,7 +246,7 @@
|
|||||||
partitioning_luks_uuid: "{{ partitioning_luks_uuid_result.stdout | trim }}"
|
partitioning_luks_uuid: "{{ partitioning_luks_uuid_result.stdout | trim }}"
|
||||||
|
|
||||||
- name: Create LVM logical volumes
|
- name: Create LVM logical volumes
|
||||||
when: filesystem != 'btrfs'
|
when: system_cfg.filesystem != 'btrfs'
|
||||||
block:
|
block:
|
||||||
- name: Create LVM volume group
|
- name: Create LVM volume group
|
||||||
community.general.lvg:
|
community.general.lvg:
|
||||||
@@ -259,8 +255,8 @@
|
|||||||
|
|
||||||
- name: Create LVM logical volumes
|
- name: Create LVM logical volumes
|
||||||
when:
|
when:
|
||||||
- cis_enabled or item.lv not in ['home', 'var', 'var_log', 'var_log_audit']
|
- system_cfg.features.cis.enabled or item.lv not in ['home', 'var', 'var_log', 'var_log_audit']
|
||||||
- swap_enabled | bool or item.lv != 'swap'
|
- system_cfg.features.swap.enabled | bool or item.lv != 'swap'
|
||||||
vars:
|
vars:
|
||||||
partitioning_lvm_extent_reserve_count: 10
|
partitioning_lvm_extent_reserve_count: 10
|
||||||
partitioning_lvm_extent_size_mib: 4
|
partitioning_lvm_extent_size_mib: 4
|
||||||
@@ -276,11 +272,11 @@
|
|||||||
{{
|
{{
|
||||||
(
|
(
|
||||||
[
|
[
|
||||||
(partitioning_vm_memory_effective | float / 1024),
|
(partitioning_memory_mb | float / 1024),
|
||||||
4
|
4
|
||||||
] | max | float
|
] | max | float
|
||||||
)
|
)
|
||||||
if swap_enabled | bool
|
if system_cfg.features.swap.enabled | bool
|
||||||
else 0
|
else 0
|
||||||
}}
|
}}
|
||||||
partitioning_lvm_swap_cap_gb: >-
|
partitioning_lvm_swap_cap_gb: >-
|
||||||
@@ -288,14 +284,14 @@
|
|||||||
(
|
(
|
||||||
4
|
4
|
||||||
+ [
|
+ [
|
||||||
(partitioning_vm_size_effective | float) - 20,
|
(partitioning_disk_size_gb | float) - 20,
|
||||||
0
|
0
|
||||||
] | max
|
] | max
|
||||||
)
|
)
|
||||||
if swap_enabled | bool
|
if system_cfg.features.swap.enabled | bool
|
||||||
else 0
|
else 0
|
||||||
}}
|
}}
|
||||||
partitioning_lvm_swap_target_effective_gb: >-
|
partitioning_lvm_swap_target_limited_gb: >-
|
||||||
{{
|
{{
|
||||||
(
|
(
|
||||||
[
|
[
|
||||||
@@ -303,7 +299,7 @@
|
|||||||
partitioning_lvm_swap_cap_gb
|
partitioning_lvm_swap_cap_gb
|
||||||
] | min
|
] | min
|
||||||
)
|
)
|
||||||
if swap_enabled | bool
|
if system_cfg.features.swap.enabled | bool
|
||||||
else 0
|
else 0
|
||||||
}}
|
}}
|
||||||
partitioning_lvm_swap_max_gb: >-
|
partitioning_lvm_swap_max_gb: >-
|
||||||
@@ -311,31 +307,31 @@
|
|||||||
(
|
(
|
||||||
[
|
[
|
||||||
(
|
(
|
||||||
(partitioning_vm_size_effective | float)
|
(partitioning_disk_size_gb | float)
|
||||||
- (partitioning_reserved_gb | float)
|
- (partitioning_reserved_gb | float)
|
||||||
- (cis_enabled | ternary(7.5, 0))
|
- (system_cfg.features.cis.enabled | ternary(7.5, 0))
|
||||||
- partitioning_lvm_extent_reserve_gb
|
- partitioning_lvm_extent_reserve_gb
|
||||||
- 4
|
- 4
|
||||||
),
|
),
|
||||||
0
|
0
|
||||||
] | max
|
] | max
|
||||||
)
|
)
|
||||||
if swap_enabled | bool
|
if system_cfg.features.swap.enabled | bool
|
||||||
else 0
|
else 0
|
||||||
}}
|
}}
|
||||||
partitioning_lvm_available_gb: >-
|
partitioning_lvm_available_gb: >-
|
||||||
{{
|
{{
|
||||||
(
|
(
|
||||||
(partitioning_vm_size_effective | float)
|
(partitioning_disk_size_gb | float)
|
||||||
- (partitioning_reserved_gb | float)
|
- (partitioning_reserved_gb | float)
|
||||||
- (cis_enabled | ternary(7.5, 0))
|
- (system_cfg.features.cis.enabled | ternary(7.5, 0))
|
||||||
- partitioning_lvm_extent_reserve_gb
|
- partitioning_lvm_extent_reserve_gb
|
||||||
- partitioning_lvm_swap_target_effective_gb
|
- partitioning_lvm_swap_target_limited_gb
|
||||||
) | float
|
) | float
|
||||||
}}
|
}}
|
||||||
partitioning_lvm_home_gb: >-
|
partitioning_lvm_home_gb: >-
|
||||||
{{
|
{{
|
||||||
([([(((partitioning_vm_size_effective | float) - 20) * 0.1), 2] | max), 20] | min)
|
([([(((partitioning_disk_size_gb | float) - 20) * 0.1), 2] | max), 20] | min)
|
||||||
}}
|
}}
|
||||||
partitioning_lvm_root_default_gb: >-
|
partitioning_lvm_root_default_gb: >-
|
||||||
{{
|
{{
|
||||||
@@ -347,7 +343,7 @@
|
|||||||
(
|
(
|
||||||
((partitioning_lvm_available_gb | float) > 12)
|
((partitioning_lvm_available_gb | float) > 12)
|
||||||
| ternary(
|
| ternary(
|
||||||
((partitioning_vm_size_effective | float) * 0.4)
|
((partitioning_disk_size_gb | float) * 0.4)
|
||||||
| round(0, 'ceil'),
|
| round(0, 'ceil'),
|
||||||
partitioning_lvm_available_gb
|
partitioning_lvm_available_gb
|
||||||
)
|
)
|
||||||
@@ -361,24 +357,24 @@
|
|||||||
{{
|
{{
|
||||||
(
|
(
|
||||||
[
|
[
|
||||||
partitioning_lvm_swap_target_effective_gb,
|
partitioning_lvm_swap_target_limited_gb,
|
||||||
partitioning_lvm_swap_max_gb
|
partitioning_lvm_swap_max_gb
|
||||||
] | min | round(2, 'floor')
|
] | min | round(2, 'floor')
|
||||||
)
|
)
|
||||||
if swap_enabled | bool
|
if system_cfg.features.swap.enabled | bool
|
||||||
else 0
|
else 0
|
||||||
}}
|
}}
|
||||||
partitioning_lvm_root_full_gb: >-
|
partitioning_lvm_root_full_gb: >-
|
||||||
{{
|
{{
|
||||||
[
|
[
|
||||||
(
|
(
|
||||||
(partitioning_vm_size_effective | float)
|
(partitioning_disk_size_gb | float)
|
||||||
- (partitioning_reserved_gb | float)
|
- (partitioning_reserved_gb | float)
|
||||||
- (partitioning_lvm_swap_gb | float)
|
- (partitioning_lvm_swap_gb | float)
|
||||||
- partitioning_lvm_extent_reserve_gb
|
- partitioning_lvm_extent_reserve_gb
|
||||||
- (
|
- (
|
||||||
(partitioning_lvm_home_gb | float) + 5.5
|
(partitioning_lvm_home_gb | float) + 5.5
|
||||||
if cis_enabled
|
if system_cfg.features.cis.enabled
|
||||||
else 0
|
else 0
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
@@ -427,7 +423,7 @@
|
|||||||
when:
|
when:
|
||||||
- partitioning_separate_boot | bool
|
- partitioning_separate_boot | bool
|
||||||
- partitioning_boot_fs_fstype == 'ext4'
|
- partitioning_boot_fs_fstype == 'ext4'
|
||||||
- os | lower in ['almalinux', 'debian11', 'rhel8', 'rhel9', 'rocky']
|
- os in ['almalinux', 'rocky', 'rhel'] or (os == 'debian' and (os_version | string) == '11')
|
||||||
ansible.builtin.command: >-
|
ansible.builtin.command: >-
|
||||||
tune2fs -O "^orphan_file,^metadata_csum_seed"
|
tune2fs -O "^orphan_file,^metadata_csum_seed"
|
||||||
"{{ install_drive }}{{ partitioning_boot_fs_partition_suffix }}"
|
"{{ install_drive }}{{ partitioning_boot_fs_partition_suffix }}"
|
||||||
@@ -436,14 +432,14 @@
|
|||||||
|
|
||||||
- name: Create swap filesystem
|
- name: Create swap filesystem
|
||||||
when:
|
when:
|
||||||
- filesystem != 'btrfs'
|
- system_cfg.filesystem != 'btrfs'
|
||||||
- swap_enabled | bool
|
- system_cfg.features.swap.enabled | bool
|
||||||
community.general.filesystem:
|
community.general.filesystem:
|
||||||
fstype: swap
|
fstype: swap
|
||||||
dev: /dev/sys/swap
|
dev: /dev/sys/swap
|
||||||
|
|
||||||
- name: Create filesystem
|
- name: Create filesystem
|
||||||
ansible.builtin.include_tasks: "{{ filesystem }}.yml"
|
ansible.builtin.include_tasks: "{{ system_cfg.filesystem }}.yml"
|
||||||
|
|
||||||
- name: Get UUID for boot filesystem
|
- name: Get UUID for boot filesystem
|
||||||
ansible.builtin.command: blkid -s UUID -o value '{{ install_drive }}{{ partitioning_boot_partition_suffix }}'
|
ansible.builtin.command: blkid -s UUID -o value '{{ install_drive }}{{ partitioning_boot_partition_suffix }}'
|
||||||
@@ -463,83 +459,83 @@
|
|||||||
changed_when: false
|
changed_when: false
|
||||||
|
|
||||||
- name: Get UUID for LVM root filesystem
|
- name: Get UUID for LVM root filesystem
|
||||||
when: filesystem != 'btrfs'
|
when: system_cfg.filesystem != 'btrfs'
|
||||||
ansible.builtin.command: blkid -s UUID -o value /dev/sys/root
|
ansible.builtin.command: blkid -s UUID -o value /dev/sys/root
|
||||||
register: partitioning_uuid_root_result
|
register: partitioning_uuid_root_result
|
||||||
changed_when: false
|
changed_when: false
|
||||||
|
|
||||||
- name: Get UUID for LVM swap filesystem
|
- name: Get UUID for LVM swap filesystem
|
||||||
when:
|
when:
|
||||||
- filesystem != 'btrfs'
|
- system_cfg.filesystem != 'btrfs'
|
||||||
- swap_enabled | bool
|
- system_cfg.features.swap.enabled | bool
|
||||||
ansible.builtin.command: blkid -s UUID -o value /dev/sys/swap
|
ansible.builtin.command: blkid -s UUID -o value /dev/sys/swap
|
||||||
register: partitioning_uuid_swap_result
|
register: partitioning_uuid_swap_result
|
||||||
changed_when: false
|
changed_when: false
|
||||||
|
|
||||||
- name: Get UUID for LVM home filesystem
|
- name: Get UUID for LVM home filesystem
|
||||||
when:
|
when:
|
||||||
- filesystem != 'btrfs'
|
- system_cfg.filesystem != 'btrfs'
|
||||||
- cis_enabled
|
- system_cfg.features.cis.enabled
|
||||||
ansible.builtin.command: blkid -s UUID -o value /dev/sys/home
|
ansible.builtin.command: blkid -s UUID -o value /dev/sys/home
|
||||||
register: partitioning_uuid_home_result
|
register: partitioning_uuid_home_result
|
||||||
changed_when: false
|
changed_when: false
|
||||||
|
|
||||||
- name: Get UUID for LVM var filesystem
|
- name: Get UUID for LVM var filesystem
|
||||||
when:
|
when:
|
||||||
- filesystem != 'btrfs'
|
- system_cfg.filesystem != 'btrfs'
|
||||||
- cis_enabled
|
- system_cfg.features.cis.enabled
|
||||||
ansible.builtin.command: blkid -s UUID -o value /dev/sys/var
|
ansible.builtin.command: blkid -s UUID -o value /dev/sys/var
|
||||||
register: partitioning_uuid_var_result
|
register: partitioning_uuid_var_result
|
||||||
changed_when: false
|
changed_when: false
|
||||||
|
|
||||||
- name: Get UUID for LVM var_log filesystem
|
- name: Get UUID for LVM var_log filesystem
|
||||||
when:
|
when:
|
||||||
- filesystem != 'btrfs'
|
- system_cfg.filesystem != 'btrfs'
|
||||||
- cis_enabled
|
- system_cfg.features.cis.enabled
|
||||||
ansible.builtin.command: blkid -s UUID -o value /dev/sys/var_log
|
ansible.builtin.command: blkid -s UUID -o value /dev/sys/var_log
|
||||||
register: partitioning_uuid_var_log_result
|
register: partitioning_uuid_var_log_result
|
||||||
changed_when: false
|
changed_when: false
|
||||||
|
|
||||||
- name: Get UUID for LVM var_log_audit filesystem
|
- name: Get UUID for LVM var_log_audit filesystem
|
||||||
when:
|
when:
|
||||||
- filesystem != 'btrfs'
|
- system_cfg.filesystem != 'btrfs'
|
||||||
- cis_enabled
|
- system_cfg.features.cis.enabled
|
||||||
ansible.builtin.command: blkid -s UUID -o value /dev/sys/var_log_audit
|
ansible.builtin.command: blkid -s UUID -o value /dev/sys/var_log_audit
|
||||||
register: partitioning_uuid_var_log_audit_result
|
register: partitioning_uuid_var_log_audit_result
|
||||||
changed_when: false
|
changed_when: false
|
||||||
|
|
||||||
- name: Assign UUIDs to Variables
|
- name: Assign UUIDs to Variables
|
||||||
when: filesystem != 'btrfs'
|
when: system_cfg.filesystem != 'btrfs'
|
||||||
ansible.builtin.set_fact:
|
ansible.builtin.set_fact:
|
||||||
partitioning_uuid_root: "{{ partitioning_uuid_root_result.stdout_lines | default([]) }}"
|
partitioning_uuid_root: "{{ partitioning_uuid_root_result.stdout_lines | default([]) }}"
|
||||||
partitioning_uuid_swap: >-
|
partitioning_uuid_swap: >-
|
||||||
{{
|
{{
|
||||||
partitioning_uuid_swap_result.stdout_lines | default([])
|
partitioning_uuid_swap_result.stdout_lines | default([])
|
||||||
if swap_enabled | bool
|
if system_cfg.features.swap.enabled | bool
|
||||||
else ''
|
else ''
|
||||||
}}
|
}}
|
||||||
partitioning_uuid_home: >-
|
partitioning_uuid_home: >-
|
||||||
{{
|
{{
|
||||||
partitioning_uuid_home_result.stdout_lines | default([])
|
partitioning_uuid_home_result.stdout_lines | default([])
|
||||||
if cis_enabled
|
if system_cfg.features.cis.enabled
|
||||||
else ''
|
else ''
|
||||||
}}
|
}}
|
||||||
partitioning_uuid_var: >-
|
partitioning_uuid_var: >-
|
||||||
{{
|
{{
|
||||||
partitioning_uuid_var_result.stdout_lines | default([])
|
partitioning_uuid_var_result.stdout_lines | default([])
|
||||||
if cis_enabled
|
if system_cfg.features.cis.enabled
|
||||||
else ''
|
else ''
|
||||||
}}
|
}}
|
||||||
partitioning_uuid_var_log: >-
|
partitioning_uuid_var_log: >-
|
||||||
{{
|
{{
|
||||||
partitioning_uuid_var_log_result.stdout_lines | default([])
|
partitioning_uuid_var_log_result.stdout_lines | default([])
|
||||||
if cis_enabled
|
if system_cfg.features.cis.enabled
|
||||||
else ''
|
else ''
|
||||||
}}
|
}}
|
||||||
partitioning_uuid_var_log_audit: >-
|
partitioning_uuid_var_log_audit: >-
|
||||||
{{
|
{{
|
||||||
partitioning_uuid_var_log_audit_result.stdout_lines | default([])
|
partitioning_uuid_var_log_audit_result.stdout_lines | default([])
|
||||||
if cis_enabled
|
if system_cfg.features.cis.enabled
|
||||||
else ''
|
else ''
|
||||||
}}
|
}}
|
||||||
|
|
||||||
@@ -548,19 +544,19 @@
|
|||||||
- name: Mount filesystems and subvolumes
|
- name: Mount filesystems and subvolumes
|
||||||
when:
|
when:
|
||||||
- >-
|
- >-
|
||||||
cis_enabled or (
|
system_cfg.features.cis.enabled or (
|
||||||
not cis_enabled and (
|
not system_cfg.features.cis.enabled and (
|
||||||
(filesystem == 'btrfs' and item.path in ['/home', '/var/log', '/var/cache/pacman/pkg'])
|
(system_cfg.filesystem == 'btrfs' and item.path in ['/home', '/var/log', '/var/cache/pacman/pkg'])
|
||||||
or (item.path not in ['/home', '/var', '/var/log', '/var/log/audit', '/var/cache/pacman/pkg'])
|
or (item.path not in ['/home', '/var', '/var/log', '/var/log/audit', '/var/cache/pacman/pkg'])
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
- >-
|
- >-
|
||||||
not (item.path in ['/swap', '/var/cache/pacman/pkg'] and filesystem != 'btrfs')
|
not (item.path in ['/swap', '/var/cache/pacman/pkg'] and system_cfg.filesystem != 'btrfs')
|
||||||
- swap_enabled | bool or item.path != '/swap'
|
- system_cfg.features.swap.enabled | bool or item.path != '/swap'
|
||||||
ansible.posix.mount:
|
ansible.posix.mount:
|
||||||
path: /mnt{{ item.path }}
|
path: /mnt{{ item.path }}
|
||||||
src: "{{ 'UUID=' + (partitioning_main_uuid.stdout if filesystem == 'btrfs' else item.uuid) }}"
|
src: "{{ 'UUID=' + (partitioning_main_uuid.stdout if system_cfg.filesystem == 'btrfs' else item.uuid) }}"
|
||||||
fstype: "{{ filesystem }}"
|
fstype: "{{ system_cfg.filesystem }}"
|
||||||
opts: "{{ item.opts }}"
|
opts: "{{ item.opts }}"
|
||||||
state: mounted
|
state: mounted
|
||||||
loop:
|
loop:
|
||||||
@@ -569,7 +565,7 @@
|
|||||||
opts: >-
|
opts: >-
|
||||||
{{
|
{{
|
||||||
'defaults'
|
'defaults'
|
||||||
if filesystem != 'btrfs'
|
if system_cfg.filesystem != 'btrfs'
|
||||||
else [
|
else [
|
||||||
'rw', 'relatime', partitioning_btrfs_compress_opt, 'ssd', 'space_cache=v2',
|
'rw', 'relatime', partitioning_btrfs_compress_opt, 'ssd', 'space_cache=v2',
|
||||||
'discard=async', 'subvol=@'
|
'discard=async', 'subvol=@'
|
||||||
@@ -588,7 +584,7 @@
|
|||||||
opts: >-
|
opts: >-
|
||||||
{{
|
{{
|
||||||
'defaults,nosuid,nodev'
|
'defaults,nosuid,nodev'
|
||||||
if filesystem != 'btrfs'
|
if system_cfg.filesystem != 'btrfs'
|
||||||
else [
|
else [
|
||||||
'rw', 'nosuid', 'nodev', 'relatime', partitioning_btrfs_compress_opt, 'ssd',
|
'rw', 'nosuid', 'nodev', 'relatime', partitioning_btrfs_compress_opt, 'ssd',
|
||||||
'space_cache=v2', 'discard=async', 'subvol=@home'
|
'space_cache=v2', 'discard=async', 'subvol=@home'
|
||||||
@@ -599,7 +595,7 @@
|
|||||||
opts: >-
|
opts: >-
|
||||||
{{
|
{{
|
||||||
'defaults,nosuid,nodev'
|
'defaults,nosuid,nodev'
|
||||||
if filesystem != 'btrfs'
|
if system_cfg.filesystem != 'btrfs'
|
||||||
else [
|
else [
|
||||||
'rw', 'nosuid', 'nodev', 'relatime', partitioning_btrfs_compress_opt, 'ssd',
|
'rw', 'nosuid', 'nodev', 'relatime', partitioning_btrfs_compress_opt, 'ssd',
|
||||||
'space_cache=v2', 'discard=async', 'subvol=@var'
|
'space_cache=v2', 'discard=async', 'subvol=@var'
|
||||||
@@ -610,7 +606,7 @@
|
|||||||
opts: >-
|
opts: >-
|
||||||
{{
|
{{
|
||||||
'defaults,nosuid,nodev,noexec'
|
'defaults,nosuid,nodev,noexec'
|
||||||
if filesystem != 'btrfs'
|
if system_cfg.filesystem != 'btrfs'
|
||||||
else [
|
else [
|
||||||
'rw', 'nosuid', 'nodev', 'noexec', 'relatime', partitioning_btrfs_compress_opt,
|
'rw', 'nosuid', 'nodev', 'noexec', 'relatime', partitioning_btrfs_compress_opt,
|
||||||
'ssd', 'space_cache=v2', 'discard=async', 'subvol=@var_log'
|
'ssd', 'space_cache=v2', 'discard=async', 'subvol=@var_log'
|
||||||
@@ -621,7 +617,7 @@
|
|||||||
opts: >-
|
opts: >-
|
||||||
{{
|
{{
|
||||||
'defaults,nosuid,nodev,noexec'
|
'defaults,nosuid,nodev,noexec'
|
||||||
if filesystem != 'btrfs'
|
if system_cfg.filesystem != 'btrfs'
|
||||||
else [
|
else [
|
||||||
'rw', 'nosuid', 'nodev', 'noexec', 'relatime', partitioning_btrfs_compress_opt,
|
'rw', 'nosuid', 'nodev', 'noexec', 'relatime', partitioning_btrfs_compress_opt,
|
||||||
'ssd', 'space_cache=v2', 'discard=async', 'subvol=@pkg'
|
'ssd', 'space_cache=v2', 'discard=async', 'subvol=@pkg'
|
||||||
@@ -632,7 +628,7 @@
|
|||||||
opts: >-
|
opts: >-
|
||||||
{{
|
{{
|
||||||
'defaults,nosuid,nodev,noexec'
|
'defaults,nosuid,nodev,noexec'
|
||||||
if filesystem != 'btrfs'
|
if system_cfg.filesystem != 'btrfs'
|
||||||
else [
|
else [
|
||||||
'rw', 'nosuid', 'nodev', 'noexec', 'relatime', partitioning_btrfs_compress_opt,
|
'rw', 'nosuid', 'nodev', 'noexec', 'relatime', partitioning_btrfs_compress_opt,
|
||||||
'ssd', 'space_cache=v2', 'discard=async', 'subvol=@var_log_audit'
|
'ssd', 'space_cache=v2', 'discard=async', 'subvol=@var_log_audit'
|
||||||
@@ -656,10 +652,13 @@
|
|||||||
state: mounted
|
state: mounted
|
||||||
|
|
||||||
- name: Activate swap
|
- name: Activate swap
|
||||||
when: swap_enabled | bool
|
when: system_cfg.features.swap.enabled | bool
|
||||||
vars:
|
vars:
|
||||||
partitioning_swap_cmd: >-
|
partitioning_swap_cmd: >-
|
||||||
{{ 'swapon /mnt/swap/swapfile' if filesystem == 'btrfs' else 'swapon -U ' + partitioning_uuid_swap[0] }}
|
{{ 'swapon /mnt/swap/swapfile' if system_cfg.filesystem == 'btrfs' else 'swapon -U ' + partitioning_uuid_swap[0] }}
|
||||||
ansible.builtin.command: "{{ partitioning_swap_cmd }}"
|
ansible.builtin.command: "{{ partitioning_swap_cmd }}"
|
||||||
register: partitioning_swap_activate_result
|
register: partitioning_swap_activate_result
|
||||||
changed_when: partitioning_swap_activate_result.rc == 0
|
changed_when: partitioning_swap_activate_result.rc == 0
|
||||||
|
|
||||||
|
- name: Mount additional disks
|
||||||
|
ansible.builtin.include_tasks: extra_disks.yml
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
- name: Create and format XFS logical volumes
|
- name: Create and format XFS logical volumes
|
||||||
when: cis_enabled or item.lv not in ['home', 'var', 'var_log', 'var_log_audit']
|
when: system_cfg.features.cis.enabled or item.lv not in ['home', 'var', 'var_log', 'var_log_audit']
|
||||||
community.general.filesystem:
|
community.general.filesystem:
|
||||||
dev: /dev/sys/{{ item.lv }}
|
dev: /dev/sys/{{ item.lv }}
|
||||||
fstype: xfs
|
fstype: xfs
|
||||||
|
|||||||
109
roles/system_check/tasks/main.yml
Normal file
109
roles/system_check/tasks/main.yml
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
---
|
||||||
|
- name: VM existence protection check
|
||||||
|
when: system_cfg.type == "virtual"
|
||||||
|
block:
|
||||||
|
- name: Check if VM already exists on libvirt
|
||||||
|
when: hypervisor_type == "libvirt"
|
||||||
|
delegate_to: localhost
|
||||||
|
become: false
|
||||||
|
community.libvirt.virt:
|
||||||
|
command: list_vms
|
||||||
|
register: system_check_libvirt_existing_vms
|
||||||
|
changed_when: false
|
||||||
|
failed_when: false
|
||||||
|
|
||||||
|
- name: Abort if VM already exists on libvirt
|
||||||
|
when: hypervisor_type == "libvirt"
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- hostname not in system_check_libvirt_existing_vms.domains | default([])
|
||||||
|
fail_msg: |
|
||||||
|
VM {{ hostname }} already exists on libvirt hypervisor.
|
||||||
|
To avoid data loss, the playbook will not overwrite or delete existing VMs.
|
||||||
|
Please choose a different hostname or remove the existing VM manually before proceeding.
|
||||||
|
quiet: true
|
||||||
|
|
||||||
|
- name: Check if VM already exists on Proxmox
|
||||||
|
when: hypervisor_type == "proxmox"
|
||||||
|
delegate_to: localhost
|
||||||
|
become: false
|
||||||
|
community.proxmox.proxmox_vm_info:
|
||||||
|
api_host: "{{ hypervisor_cfg.url }}"
|
||||||
|
api_user: "{{ hypervisor_cfg.username }}"
|
||||||
|
api_password: "{{ hypervisor_cfg.password }}"
|
||||||
|
node: "{{ hypervisor_cfg.host }}"
|
||||||
|
vmid: "{{ system_cfg.id }}"
|
||||||
|
name: "{{ hostname }}"
|
||||||
|
type: qemu
|
||||||
|
register: system_check_proxmox_check_result
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: Abort if VM already exists on Proxmox
|
||||||
|
when: hypervisor_type == "proxmox"
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- system_check_proxmox_check_result.proxmox_vms | default([]) | length == 0
|
||||||
|
fail_msg: |
|
||||||
|
VM {{ hostname }} (ID: {{ system_cfg.id }}) already exists on Proxmox hypervisor.
|
||||||
|
To avoid data loss, the playbook will not overwrite or delete existing VMs.
|
||||||
|
Please choose a different hostname or VM ID, or remove the existing VM manually before proceeding.
|
||||||
|
quiet: true
|
||||||
|
|
||||||
|
- name: Check if VM already exists in vCenter
|
||||||
|
when: hypervisor_type == "vmware"
|
||||||
|
delegate_to: localhost
|
||||||
|
community.vmware.vmware_guest_info:
|
||||||
|
hostname: "{{ hypervisor_cfg.url }}"
|
||||||
|
username: "{{ hypervisor_cfg.username }}"
|
||||||
|
password: "{{ hypervisor_cfg.password }}"
|
||||||
|
validate_certs: "{{ hypervisor_cfg.certs | bool }}"
|
||||||
|
datacenter: "{{ hypervisor_cfg.datacenter }}"
|
||||||
|
name: "{{ hostname }}"
|
||||||
|
folder: "{{ system_cfg.path if system_cfg.path | length > 0 else omit }}"
|
||||||
|
register: system_check_vmware_check_result
|
||||||
|
failed_when: false
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: Fail if vCenter lookup failed unexpectedly
|
||||||
|
when: hypervisor_type == "vmware"
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- not system_check_vmware_check_result.failed
|
||||||
|
or (system_check_vmware_check_result.msg is search('non-existing VM'))
|
||||||
|
fail_msg: |
|
||||||
|
Unable to verify VM existence in vCenter.
|
||||||
|
{{ system_check_vmware_check_result.msg | default('Unknown error') }}
|
||||||
|
quiet: true
|
||||||
|
|
||||||
|
- name: Abort if VM already exists in vCenter
|
||||||
|
when: hypervisor_type == "vmware"
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- system_check_vmware_check_result.instance is not defined
|
||||||
|
fail_msg: |
|
||||||
|
VM {{ hostname }} already exists in vCenter.
|
||||||
|
To avoid data loss, the playbook will not overwrite or delete existing VMs.
|
||||||
|
Please choose a different hostname or remove the existing VM manually before proceeding.
|
||||||
|
quiet: true
|
||||||
|
|
||||||
|
- name: Check if VM already exists on Xen
|
||||||
|
when: hypervisor_type == "xen"
|
||||||
|
delegate_to: localhost
|
||||||
|
ansible.builtin.command:
|
||||||
|
argv:
|
||||||
|
- xl
|
||||||
|
- list
|
||||||
|
register: system_check_xen_existing_vms
|
||||||
|
changed_when: false
|
||||||
|
failed_when: false
|
||||||
|
|
||||||
|
- name: Abort if VM already exists on Xen
|
||||||
|
when: hypervisor_type == "xen"
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- hostname not in system_check_xen_existing_vms.stdout | default('')
|
||||||
|
fail_msg: |
|
||||||
|
VM {{ hostname }} already exists on Xen hypervisor.
|
||||||
|
To avoid data loss, the playbook will not overwrite or delete existing VMs.
|
||||||
|
Please choose a different hostname or remove the existing VM manually before proceeding.
|
||||||
|
quiet: true
|
||||||
@@ -1,12 +1,17 @@
|
|||||||
---
|
---
|
||||||
virtualization_libvirt_image_dir: >-
|
virtualization_libvirt_image_dir: >-
|
||||||
{{ vm_path if vm_path is defined and vm_path | length > 0 else '/var/lib/libvirt/images' }}
|
{{
|
||||||
|
system_cfg.path
|
||||||
|
if system_cfg is defined and (system_cfg.path | string | length) > 0
|
||||||
|
else '/var/lib/libvirt/images'
|
||||||
|
}}
|
||||||
virtualization_libvirt_disk_path: >-
|
virtualization_libvirt_disk_path: >-
|
||||||
{{ [virtualization_libvirt_image_dir, hostname ~ '.qcow2'] | ansible.builtin.path_join }}
|
{{ [virtualization_libvirt_image_dir, hostname ~ '.qcow2'] | ansible.builtin.path_join }}
|
||||||
virtualization_libvirt_cloudinit_path: >-
|
virtualization_libvirt_cloudinit_path: >-
|
||||||
{{ [virtualization_libvirt_image_dir, hostname ~ '-cloudinit.iso'] | ansible.builtin.path_join }}
|
{{ [virtualization_libvirt_image_dir, hostname ~ '-cloudinit.iso'] | ansible.builtin.path_join }}
|
||||||
virtualization_mac_address: >-
|
virtualization_mac_address: >-
|
||||||
{{ '52:54:00' | community.general.random_mac(seed=hostname) }}
|
{{ '52:54:00' | community.general.random_mac(seed=hostname) }}
|
||||||
|
virtualization_xen_disk_path: /var/lib/xen/images
|
||||||
|
|
||||||
virtualization_tpm2_enabled: >-
|
virtualization_tpm2_enabled: >-
|
||||||
{{
|
{{
|
||||||
|
|||||||
@@ -1,5 +1,31 @@
|
|||||||
---
|
---
|
||||||
- name: Create VM disk
|
- name: Build disk definitions
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
virtualization_libvirt_disks: "{{ virtualization_libvirt_disks | default([]) + [virtualization_libvirt_disk_cfg] }}"
|
||||||
|
vars:
|
||||||
|
device_letter_map: "abcdefghijklmnopqrstuvwxyz"
|
||||||
|
device_letter: "{{ device_letter_map[ansible_loop.index0] }}"
|
||||||
|
virtualization_libvirt_disk_cfg: >-
|
||||||
|
{{
|
||||||
|
{
|
||||||
|
'path': (
|
||||||
|
virtualization_libvirt_disk_path
|
||||||
|
if ansible_loop.index0 == 0
|
||||||
|
else ([virtualization_libvirt_image_dir, hostname ~ '-disk' ~ ansible_loop.index0 ~ '.qcow2'] | ansible.builtin.path_join)
|
||||||
|
),
|
||||||
|
'target': 'vd' ~ device_letter,
|
||||||
|
'bus': 'virtio',
|
||||||
|
'format': 'qcow2',
|
||||||
|
'size': (item.size | float)
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
loop: "{{ system_cfg.disks }}"
|
||||||
|
loop_control:
|
||||||
|
label: "{{ item | to_json }}"
|
||||||
|
extended: true
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: Create VM disks
|
||||||
delegate_to: localhost
|
delegate_to: localhost
|
||||||
ansible.builtin.command:
|
ansible.builtin.command:
|
||||||
argv:
|
argv:
|
||||||
@@ -7,16 +33,19 @@
|
|||||||
- create
|
- create
|
||||||
- -f
|
- -f
|
||||||
- qcow2
|
- qcow2
|
||||||
- "{{ virtualization_libvirt_disk_path }}"
|
- "{{ item.path }}"
|
||||||
- "{{ vm_size }}G"
|
- "{{ item.size }}G"
|
||||||
creates: "{{ virtualization_libvirt_disk_path }}"
|
creates: "{{ item.path }}"
|
||||||
|
loop: "{{ virtualization_libvirt_disks }}"
|
||||||
|
loop_control:
|
||||||
|
label: "{{ item.path }}"
|
||||||
|
|
||||||
- name: Render cloud config templates
|
- name: Render cloud config templates
|
||||||
delegate_to: localhost
|
delegate_to: localhost
|
||||||
ansible.builtin.template:
|
ansible.builtin.template:
|
||||||
src: "{{ item.src }}"
|
src: "{{ item.src }}"
|
||||||
dest: /tmp/{{ item.dest_prefix }}-{{ hostname }}.yml
|
dest: /tmp/{{ item.dest_prefix }}-{{ hostname }}.yml
|
||||||
mode: '0644'
|
mode: "0644"
|
||||||
loop:
|
loop:
|
||||||
- { src: cloud-user-data.yml.j2, dest_prefix: cloud-user-data }
|
- { src: cloud-user-data.yml.j2, dest_prefix: cloud-user-data }
|
||||||
- { src: cloud-network-config.yml.j2, dest_prefix: cloud-network-config }
|
- { src: cloud-network-config.yml.j2, dest_prefix: cloud-network-config }
|
||||||
@@ -43,3 +72,9 @@
|
|||||||
community.libvirt.virt:
|
community.libvirt.virt:
|
||||||
name: "{{ hostname }}"
|
name: "{{ hostname }}"
|
||||||
state: running
|
state: running
|
||||||
|
register: virtualization_libvirt_start_result
|
||||||
|
|
||||||
|
- name: Set VM created fact
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
virtualization_vm_created_in_run: true
|
||||||
|
when: virtualization_libvirt_start_result is defined and virtualization_libvirt_start_result.changed | bool
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
---
|
---
|
||||||
- name: Create Virtual Machine
|
- name: Create Virtual Machine
|
||||||
ansible.builtin.include_tasks: "{{ hypervisor }}.yml"
|
ansible.builtin.include_tasks: "{{ hypervisor_type }}.yml"
|
||||||
|
|||||||
@@ -2,38 +2,26 @@
|
|||||||
- name: Deploy VM on Proxmox
|
- name: Deploy VM on Proxmox
|
||||||
delegate_to: localhost
|
delegate_to: localhost
|
||||||
vars:
|
vars:
|
||||||
virtualization_dns_value: "{{ vm_dns if vm_dns is defined else '' }}"
|
virtualization_proxmox_scsi: >-
|
||||||
virtualization_dns_list_raw: >-
|
{%- set out = {} -%}
|
||||||
{{
|
{%- for disk in system_cfg.disks -%}
|
||||||
virtualization_dns_value
|
{%- set _ = out.update({ 'scsi' ~ loop.index0: hypervisor_cfg.storage ~ ':' ~ (disk.size | int) }) -%}
|
||||||
if virtualization_dns_value is iterable and virtualization_dns_value is not string
|
{%- endfor -%}
|
||||||
else virtualization_dns_value.split(',')
|
{{ out }}
|
||||||
}}
|
|
||||||
virtualization_dns_list: >-
|
|
||||||
{{ virtualization_dns_list_raw | map('trim') | reject('equalto', '') | list }}
|
|
||||||
virtualization_search_value: "{{ vm_dns_search if vm_dns_search is defined else '' }}"
|
|
||||||
virtualization_search_list_raw: >-
|
|
||||||
{{
|
|
||||||
virtualization_search_value
|
|
||||||
if virtualization_search_value is iterable and virtualization_search_value is not string
|
|
||||||
else virtualization_search_value.split(',')
|
|
||||||
}}
|
|
||||||
virtualization_search_list: >-
|
|
||||||
{{ virtualization_search_list_raw | map('trim') | reject('equalto', '') | list }}
|
|
||||||
community.proxmox.proxmox_kvm:
|
community.proxmox.proxmox_kvm:
|
||||||
api_host: "{{ hypervisor_url }}"
|
api_host: "{{ hypervisor_cfg.url }}"
|
||||||
api_user: "{{ hypervisor_username }}"
|
api_user: "{{ hypervisor_cfg.username }}"
|
||||||
api_password: "{{ hypervisor_password }}"
|
api_password: "{{ hypervisor_cfg.password }}"
|
||||||
ciuser: "{{ user_name }}"
|
ciuser: "{{ system_cfg.user.name }}"
|
||||||
cipassword: "{{ user_password }}"
|
cipassword: "{{ system_cfg.user.password }}"
|
||||||
ciupgrade: false
|
ciupgrade: false
|
||||||
node: "{{ hypervisor_node }}"
|
node: "{{ hypervisor_cfg.host }}"
|
||||||
vmid: "{{ vm_id }}"
|
vmid: "{{ system_cfg.id }}"
|
||||||
name: "{{ hostname }}"
|
name: "{{ hostname }}"
|
||||||
cpu: host
|
cpu: host
|
||||||
cores: "{{ vm_cpus }}"
|
cores: "{{ system_cfg.cpus }}"
|
||||||
memory: "{{ vm_memory }}"
|
memory: "{{ system_cfg.memory }}"
|
||||||
balloon: "{{ vm_ballo if vm_ballo is defined and vm_ballo | int > 0 else omit }}"
|
balloon: "{{ system_cfg.balloon if system_cfg.balloon is defined and system_cfg.balloon | int > 0 else omit }}"
|
||||||
numa_enabled: true
|
numa_enabled: true
|
||||||
hotplug: network,disk
|
hotplug: network,disk
|
||||||
update: "{{ virtualization_tpm2_enabled | bool }}"
|
update: "{{ virtualization_tpm2_enabled | bool }}"
|
||||||
@@ -42,45 +30,51 @@
|
|||||||
machine: "{{ 'q35' if virtualization_tpm2_enabled | bool else omit }}"
|
machine: "{{ 'q35' if virtualization_tpm2_enabled | bool else omit }}"
|
||||||
boot: ac
|
boot: ac
|
||||||
scsihw: virtio-scsi-single
|
scsihw: virtio-scsi-single
|
||||||
scsi:
|
scsi: "{{ virtualization_proxmox_scsi }}"
|
||||||
scsi0: "{{ hypervisor_storage }}:{{ vm_size }}"
|
|
||||||
efidisk0:
|
efidisk0:
|
||||||
efitype: 4m
|
efitype: 4m
|
||||||
format: raw
|
format: raw
|
||||||
pre_enrolled_keys: false
|
pre_enrolled_keys: false
|
||||||
storage: "{{ hypervisor_storage }}"
|
storage: "{{ hypervisor_cfg.storage }}"
|
||||||
tpmstate0: >-
|
tpmstate0: >-
|
||||||
{{
|
{{
|
||||||
{'storage': hypervisor_storage, 'version': '2.0'}
|
{'storage': hypervisor_cfg.storage, 'version': '2.0'}
|
||||||
if virtualization_tpm2_enabled | bool
|
if virtualization_tpm2_enabled | bool
|
||||||
else omit
|
else omit
|
||||||
}}
|
}}
|
||||||
ide:
|
ide:
|
||||||
ide0: "{{ boot_iso }},media=cdrom"
|
ide0: "{{ boot_iso }},media=cdrom"
|
||||||
ide1: "{{ rhel_iso + ',media=cdrom' if rhel_iso is defined and rhel_iso | length > 0 else omit }}"
|
ide1: "{{ rhel_iso + ',media=cdrom' if rhel_iso is defined and rhel_iso | length > 0 else omit }}"
|
||||||
ide2: "{{ hypervisor_storage }}:cloudinit"
|
ide2: "{{ hypervisor_cfg.storage }}:cloudinit"
|
||||||
net:
|
net:
|
||||||
net0: virtio,bridge={{ vm_nif }}{% if vlan_name is defined and vlan_name | length > 0 %},tag={{ vlan_name }}{% endif %}
|
net0: >-
|
||||||
|
virtio,bridge={{ system_cfg.network }}{% if system_cfg.vlan is defined and system_cfg.vlan | string | length > 0 %},tag={{ system_cfg.vlan }}{% endif %}
|
||||||
ipconfig:
|
ipconfig:
|
||||||
ipconfig0: >-
|
ipconfig0: >-
|
||||||
{{
|
{{
|
||||||
'ip=' ~ vm_ip ~ '/' ~ vm_nms
|
'ip=' ~ system_cfg.ip ~ '/' ~ system_cfg.prefix
|
||||||
~ (',gw=' ~ vm_gw if vm_gw is defined and vm_gw | length else '')
|
~ (',gw=' ~ system_cfg.gateway if system_cfg.gateway is defined and system_cfg.gateway | length else '')
|
||||||
if vm_ip is defined and vm_ip | length
|
if system_cfg.ip is defined and system_cfg.ip | string | length
|
||||||
else 'ip=dhcp'
|
else 'ip=dhcp'
|
||||||
}}
|
}}
|
||||||
nameservers: "{{ virtualization_dns_list if virtualization_dns_list | length else omit }}"
|
nameservers: "{{ system_cfg.dns.servers if system_cfg.dns.servers | length else omit }}"
|
||||||
searchdomains: "{{ virtualization_search_list if virtualization_search_list | length else omit }}"
|
searchdomains: "{{ system_cfg.dns.search if system_cfg.dns.search | length else omit }}"
|
||||||
onboot: true
|
onboot: true
|
||||||
state: present
|
state: present
|
||||||
|
|
||||||
- name: Start VM on Proxmox
|
- name: Start VM on Proxmox
|
||||||
delegate_to: localhost
|
delegate_to: localhost
|
||||||
community.proxmox.proxmox_kvm:
|
community.proxmox.proxmox_kvm:
|
||||||
api_host: "{{ hypervisor_url }}"
|
api_host: "{{ hypervisor_cfg.url }}"
|
||||||
api_user: "{{ hypervisor_username }}"
|
api_user: "{{ hypervisor_cfg.username }}"
|
||||||
api_password: "{{ hypervisor_password }}"
|
api_password: "{{ hypervisor_cfg.password }}"
|
||||||
node: "{{ hypervisor_node }}"
|
node: "{{ hypervisor_cfg.host }}"
|
||||||
name: "{{ hostname }}"
|
name: "{{ hostname }}"
|
||||||
vmid: "{{ vm_id }}"
|
vmid: "{{ system_cfg.id }}"
|
||||||
state: started
|
state: started
|
||||||
|
register: virtualization_proxmox_start_result
|
||||||
|
|
||||||
|
- name: Set VM created fact
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
virtualization_vm_created_in_run: true
|
||||||
|
when: virtualization_proxmox_start_result is defined and virtualization_proxmox_start_result.changed | bool
|
||||||
|
|||||||
@@ -1,26 +1,36 @@
|
|||||||
---
|
---
|
||||||
|
- name: Build vCenter disk list
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
virtualization_vmware_disks: "{{ virtualization_vmware_disks | default([]) + [virtualization_vmware_disk_cfg] }}"
|
||||||
|
vars:
|
||||||
|
virtualization_vmware_disk_cfg:
|
||||||
|
size_gb: "{{ item.size | int }}"
|
||||||
|
type: thin
|
||||||
|
datastore: "{{ hypervisor_cfg.storage }}"
|
||||||
|
loop: "{{ system_cfg.disks }}"
|
||||||
|
loop_control:
|
||||||
|
label: "{{ item | to_json }}"
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
- name: Create VM in vCenter
|
- name: Create VM in vCenter
|
||||||
delegate_to: localhost
|
delegate_to: localhost
|
||||||
community.vmware.vmware_guest:
|
community.vmware.vmware_guest:
|
||||||
hostname: "{{ hypervisor_url }}"
|
hostname: "{{ hypervisor_cfg.url }}"
|
||||||
username: "{{ hypervisor_username }}"
|
username: "{{ hypervisor_cfg.username }}"
|
||||||
password: "{{ hypervisor_password }}"
|
password: "{{ hypervisor_cfg.password }}"
|
||||||
validate_certs: false
|
validate_certs: "{{ hypervisor_cfg.certs | bool }}"
|
||||||
datacenter: "{{ hypervisor_datacenter }}"
|
datacenter: "{{ hypervisor_cfg.datacenter }}"
|
||||||
cluster: "{{ hypervisor_cluster }}"
|
cluster: "{{ hypervisor_cfg.cluster }}"
|
||||||
folder: "{{ vm_path if vm_path is defined and vm_path | length > 0 else omit }}"
|
folder: "{{ system_cfg.path if system_cfg.path | string | length > 0 else omit }}"
|
||||||
name: "{{ hostname }}"
|
name: "{{ hostname }}"
|
||||||
guest_id: otherLinux64Guest
|
guest_id: otherLinux64Guest
|
||||||
annotation: |
|
annotation: |
|
||||||
{{ note if note is defined else '' }}
|
{{ note if note is defined else '' }}
|
||||||
state: "{{ 'poweredoff' if virtualization_tpm2_enabled | bool else 'poweredon' }}"
|
state: "{{ 'poweredoff' if virtualization_tpm2_enabled | bool else 'poweredon' }}"
|
||||||
disk:
|
disk: "{{ virtualization_vmware_disks }}"
|
||||||
- size_gb: "{{ vm_size }}"
|
|
||||||
type: thin
|
|
||||||
datastore: "{{ hypervisor_storage }}"
|
|
||||||
hardware:
|
hardware:
|
||||||
memory_mb: "{{ vm_memory }}"
|
memory_mb: "{{ system_cfg.memory }}"
|
||||||
num_cpus: "{{ vm_cpus }}"
|
num_cpus: "{{ system_cfg.cpus }}"
|
||||||
boot_firmware: efi
|
boot_firmware: efi
|
||||||
secure_boot: false
|
secure_boot: false
|
||||||
cdrom: >-
|
cdrom: >-
|
||||||
@@ -44,20 +54,29 @@
|
|||||||
} ] if rhel_iso is defined and rhel_iso | length > 0 else [] )
|
} ] if rhel_iso is defined and rhel_iso | length > 0 else [] )
|
||||||
}}
|
}}
|
||||||
networks:
|
networks:
|
||||||
- name: "{{ vm_nif }}"
|
- name: "{{ system_cfg.network }}"
|
||||||
type: dhcp
|
type: dhcp
|
||||||
vlan: "{{ vlan_name if vlan_name is defined and vlan_name | length > 0 else omit }}"
|
vlan: "{{ system_cfg.vlan if system_cfg.vlan is defined and system_cfg.vlan | string | length > 0 else omit }}"
|
||||||
|
register: virtualization_vmware_create_result
|
||||||
|
|
||||||
|
- name: Set VM created fact when VM was powered on during creation
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
virtualization_vm_created_in_run: true
|
||||||
|
when:
|
||||||
|
- virtualization_vmware_create_result is defined
|
||||||
|
- not virtualization_tpm2_enabled | bool
|
||||||
|
- virtualization_vmware_create_result.changed | bool
|
||||||
|
|
||||||
- name: Ensure vTPM2 is enabled when required
|
- name: Ensure vTPM2 is enabled when required
|
||||||
when: virtualization_tpm2_enabled | bool
|
when: virtualization_tpm2_enabled | bool
|
||||||
delegate_to: localhost
|
delegate_to: localhost
|
||||||
community.vmware.vmware_guest_tpm:
|
community.vmware.vmware_guest_tpm:
|
||||||
hostname: "{{ hypervisor_url }}"
|
hostname: "{{ hypervisor_cfg.url }}"
|
||||||
username: "{{ hypervisor_username }}"
|
username: "{{ hypervisor_cfg.username }}"
|
||||||
password: "{{ hypervisor_password }}"
|
password: "{{ hypervisor_cfg.password }}"
|
||||||
validate_certs: false
|
validate_certs: "{{ hypervisor_cfg.certs | bool }}"
|
||||||
datacenter: "{{ hypervisor_datacenter }}"
|
datacenter: "{{ hypervisor_cfg.datacenter }}"
|
||||||
folder: "{{ vm_path if vm_path is defined and vm_path | length > 0 else omit }}"
|
folder: "{{ system_cfg.path if system_cfg.path | string | length > 0 else omit }}"
|
||||||
name: "{{ hostname }}"
|
name: "{{ hostname }}"
|
||||||
state: present
|
state: present
|
||||||
|
|
||||||
@@ -65,10 +84,19 @@
|
|||||||
when: virtualization_tpm2_enabled | bool
|
when: virtualization_tpm2_enabled | bool
|
||||||
delegate_to: localhost
|
delegate_to: localhost
|
||||||
vmware.vmware.vm_powerstate:
|
vmware.vmware.vm_powerstate:
|
||||||
hostname: "{{ hypervisor_url }}"
|
hostname: "{{ hypervisor_cfg.url }}"
|
||||||
username: "{{ hypervisor_username }}"
|
username: "{{ hypervisor_cfg.username }}"
|
||||||
password: "{{ hypervisor_password }}"
|
password: "{{ hypervisor_cfg.password }}"
|
||||||
validate_certs: false
|
validate_certs: "{{ hypervisor_cfg.certs | bool }}"
|
||||||
datacenter: "{{ hypervisor_datacenter }}"
|
datacenter: "{{ hypervisor_cfg.datacenter }}"
|
||||||
name: "{{ hostname }}"
|
name: "{{ hostname }}"
|
||||||
state: powered-on
|
state: powered-on
|
||||||
|
register: virtualization_vmware_start_result
|
||||||
|
|
||||||
|
- name: Set VM created fact when VM was started separately (TPM2 case)
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
virtualization_vm_created_in_run: true
|
||||||
|
when:
|
||||||
|
- virtualization_tpm2_enabled | bool
|
||||||
|
- virtualization_vmware_start_result is defined
|
||||||
|
- virtualization_vmware_start_result.changed | bool
|
||||||
|
|||||||
77
roles/virtualization/tasks/xen.yml
Normal file
77
roles/virtualization/tasks/xen.yml
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
---
|
||||||
|
- name: Deploy VM on Xen
|
||||||
|
block:
|
||||||
|
- name: Build disk definitions
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
virtualization_xen_disks: "{{ virtualization_xen_disks | default([]) + [virtualization_xen_disk_cfg] }}"
|
||||||
|
vars:
|
||||||
|
device_letter_map: "abcdefghijklmnopqrstuvwxyz"
|
||||||
|
device_letter: "{{ device_letter_map[ansible_loop.index0] }}"
|
||||||
|
virtualization_xen_disk_cfg: >-
|
||||||
|
{{
|
||||||
|
{
|
||||||
|
'path': (
|
||||||
|
virtualization_xen_disk_path ~ '/' ~ hostname ~ '.qcow2'
|
||||||
|
if ansible_loop.index0 == 0
|
||||||
|
else virtualization_xen_disk_path ~ '/' ~ hostname ~ '-disk' ~ ansible_loop.index0 ~ '.qcow2'
|
||||||
|
),
|
||||||
|
'target': 'xvd' ~ device_letter,
|
||||||
|
'size': (item.size | float)
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
loop: "{{ system_cfg.disks }}"
|
||||||
|
loop_control:
|
||||||
|
label: "{{ item | to_json }}"
|
||||||
|
extended: true
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: Create VM disks for Xen
|
||||||
|
delegate_to: localhost
|
||||||
|
ansible.builtin.command:
|
||||||
|
argv:
|
||||||
|
- qemu-img
|
||||||
|
- create
|
||||||
|
- -f
|
||||||
|
- qcow2
|
||||||
|
- "{{ item.path }}"
|
||||||
|
- "{{ item.size }}G"
|
||||||
|
creates: "{{ item.path }}"
|
||||||
|
loop: "{{ virtualization_xen_disks }}"
|
||||||
|
loop_control:
|
||||||
|
label: "{{ item.path }}"
|
||||||
|
|
||||||
|
- name: Render Xen VM configuration
|
||||||
|
delegate_to: localhost
|
||||||
|
vars:
|
||||||
|
xen_installer_media_enabled: true
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: xen.cfg.j2
|
||||||
|
dest: /tmp/xen-{{ hostname }}.cfg
|
||||||
|
mode: "0644"
|
||||||
|
|
||||||
|
- name: Create Xen VM
|
||||||
|
delegate_to: localhost
|
||||||
|
ansible.builtin.command:
|
||||||
|
argv:
|
||||||
|
- xl
|
||||||
|
- create
|
||||||
|
- /tmp/xen-{{ hostname }}.cfg
|
||||||
|
register: virtualization_xen_create_result
|
||||||
|
changed_when: virtualization_xen_create_result.rc == 0
|
||||||
|
|
||||||
|
- name: Ensure VM is running
|
||||||
|
delegate_to: localhost
|
||||||
|
ansible.builtin.command:
|
||||||
|
argv:
|
||||||
|
- xl
|
||||||
|
- list
|
||||||
|
register: virtualization_xen_list_result
|
||||||
|
changed_when: false
|
||||||
|
failed_when: false
|
||||||
|
|
||||||
|
- name: Set VM created fact
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
virtualization_vm_created_in_run: true
|
||||||
|
when:
|
||||||
|
- virtualization_xen_list_result is defined
|
||||||
|
- hostname in virtualization_xen_list_result.stdout
|
||||||
@@ -4,27 +4,23 @@ network:
|
|||||||
id0:
|
id0:
|
||||||
match:
|
match:
|
||||||
macaddress: "{{ virtualization_mac_address }}"
|
macaddress: "{{ virtualization_mac_address }}"
|
||||||
{% set has_static = vm_ip is defined and vm_ip | length %}
|
{% set has_static = system_cfg.ip is defined and system_cfg.ip | string | length %}
|
||||||
{% set dns_value = vm_dns if vm_dns is defined else '' %}
|
{% set dns_list = system_cfg.dns.servers | default([]) %}
|
||||||
{% set dns_list_raw = dns_value if dns_value is iterable and dns_value is not string else dns_value.split(',') %}
|
{% set search_list = system_cfg.dns.search | default([]) %}
|
||||||
{% set dns_list = dns_list_raw | map('trim') | reject('equalto', '') | list %}
|
|
||||||
{% set search_value = vm_dns_search if vm_dns_search is defined else '' %}
|
|
||||||
{% set search_list_raw = search_value if search_value is iterable and search_value is not string else search_value.split(',') %}
|
|
||||||
{% set search_list = search_list_raw | map('trim') | reject('equalto', '') | list %}
|
|
||||||
{% if has_static %}
|
{% if has_static %}
|
||||||
addresses:
|
addresses:
|
||||||
- "{{ vm_ip }}/{{ vm_nms }}"
|
- "{{ system_cfg.ip }}/{{ system_cfg.prefix }}"
|
||||||
{% if vm_gw is defined and vm_gw | length %}
|
{% if system_cfg.gateway is defined and system_cfg.gateway | string | length %}
|
||||||
gateway4: "{{ vm_gw }}"
|
gateway4: "{{ system_cfg.gateway }}"
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% else %}
|
{% else %}
|
||||||
dhcp4: true
|
dhcp4: true
|
||||||
{% if (vm_dns is defined and vm_dns | length) or (vm_dns_search is defined and vm_dns_search | length) %}
|
{% if dns_list | length or search_list | length %}
|
||||||
dhcp4-overrides:
|
dhcp4-overrides:
|
||||||
{% if vm_dns is defined and vm_dns | length %}
|
{% if dns_list | length %}
|
||||||
use-dns: false
|
use-dns: false
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if vm_dns_search is defined and vm_dns_search | length %}
|
{% if search_list | length %}
|
||||||
use-domains: false
|
use-domains: false
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ ssh_pwauth: true
|
|||||||
package_update: false
|
package_update: false
|
||||||
package_upgrade: false
|
package_upgrade: false
|
||||||
users:
|
users:
|
||||||
- name: "{{ user_name }}"
|
- name: "{{ system_cfg.user.name }}"
|
||||||
primary_group: "{{ user_name }}"
|
primary_group: "{{ system_cfg.user.name }}"
|
||||||
groups: users
|
groups: users
|
||||||
sudo: ALL=(ALL) NOPASSWD:ALL
|
sudo: ALL=(ALL) NOPASSWD:ALL
|
||||||
passwd: "{{ user_password | password_hash('sha512') }}"
|
passwd: "{{ system_cfg.user.password | password_hash('sha512') }}"
|
||||||
lock_passwd: False
|
lock_passwd: False
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<domain type='kvm'>
|
<domain type='kvm'>
|
||||||
<name>{{ hostname }}</name>
|
<name>{{ hostname }}</name>
|
||||||
<memory>{{ vm_memory | int * 1024 }}</memory>
|
<memory>{{ system_cfg.memory | int * 1024 }}</memory>
|
||||||
{% if vm_ballo is defined and vm_ballo | int > 0 %}<currentMemory>{{ vm_ballo | int * 1024 }}</currentMemory>{% endif %}
|
{% if system_cfg.balloon is defined and system_cfg.balloon | int > 0 %}<currentMemory>{{ system_cfg.balloon | int * 1024 }}</currentMemory>{% endif %}
|
||||||
<vcpu placement='static'>{{ vm_cpus }}</vcpu>
|
<vcpu placement='static'>{{ system_cfg.cpus }}</vcpu>
|
||||||
<os>
|
<os>
|
||||||
<type arch='x86_64' machine="pc-q35-8.0">hvm</type>
|
<type arch='x86_64' machine="pc-q35-8.0">hvm</type>
|
||||||
<bootmenu enable='no'/>
|
<bootmenu enable='no'/>
|
||||||
@@ -22,11 +22,13 @@
|
|||||||
<on_reboot>restart</on_reboot>
|
<on_reboot>restart</on_reboot>
|
||||||
<on_crash>destroy</on_crash>
|
<on_crash>destroy</on_crash>
|
||||||
<devices>
|
<devices>
|
||||||
|
{% for disk in virtualization_libvirt_disks | default([]) %}
|
||||||
<disk type='file' device='disk'>
|
<disk type='file' device='disk'>
|
||||||
<driver name='qemu' type='qcow2'/>
|
<driver name='qemu' type='{{ disk.format }}'/>
|
||||||
<source file='{{ virtualization_libvirt_disk_path }}'/>
|
<source file='{{ disk.path }}'/>
|
||||||
<target dev='vda' bus='virtio'/>
|
<target dev='{{ disk.target }}' bus='{{ disk.bus }}'/>
|
||||||
</disk>
|
</disk>
|
||||||
|
{% endfor %}
|
||||||
<disk type="file" device="cdrom">
|
<disk type="file" device="cdrom">
|
||||||
<driver name="qemu" type="raw"/>
|
<driver name="qemu" type="raw"/>
|
||||||
<source file="{{ boot_iso }}"/>
|
<source file="{{ boot_iso }}"/>
|
||||||
|
|||||||
17
templates/xen.cfg.j2
Normal file
17
templates/xen.cfg.j2
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
builder = "hvm"
|
||||||
|
name = "{{ hostname }}"
|
||||||
|
memory = "{{ system_cfg.memory }}"
|
||||||
|
vcpus = "{{ system_cfg.cpus }}"
|
||||||
|
disk = [
|
||||||
|
{%- for disk in virtualization_xen_disks | default([]) -%}
|
||||||
|
'file:{{ disk.path }},{{ disk.target }},w'{% if not loop.last or xen_installer_media_enabled | bool %}, {% endif %}
|
||||||
|
{%- endfor -%}
|
||||||
|
{%- if xen_installer_media_enabled | bool -%}
|
||||||
|
'{{ boot_iso }},,hdc,cdrom'{% if rhel_iso is defined and rhel_iso | length > 0 %}, '{{ rhel_iso }},,hdd,cdrom'{% endif %}
|
||||||
|
{%- endif -%}
|
||||||
|
]
|
||||||
|
vif = [ 'bridge={{ system_cfg.network }},model=e1000' ]
|
||||||
|
boot = "{{ 'dc' if xen_installer_media_enabled | bool else 'c' }}"
|
||||||
|
on_crash = "preserve"
|
||||||
|
on_poweroff = "destroy"
|
||||||
|
serial = "pty"
|
||||||
@@ -1,19 +1,61 @@
|
|||||||
---
|
---
|
||||||
hypervisor: "none"
|
# Example variables for baremetal installs.
|
||||||
install_type: "physical"
|
hypervisor:
|
||||||
install_drive: "/dev/sda"
|
type: "none"
|
||||||
|
|
||||||
|
system:
|
||||||
|
type: "physical"
|
||||||
os: "archlinux"
|
os: "archlinux"
|
||||||
filesystem: "btrfs"
|
filesystem: "btrfs" # btrfs|ext4|xfs
|
||||||
|
name: "{{ inventory_hostname }}"
|
||||||
cis: false
|
cpus: 8
|
||||||
selinux: true
|
memory: 16384
|
||||||
firewalld_enabled: true
|
ip: "{{ ansible_host | default('') }}"
|
||||||
|
prefix: 24
|
||||||
luks_enabled: true
|
gateway: "10.0.0.1"
|
||||||
luks_passphrase: "1234"
|
dns:
|
||||||
luks_mapper_name: "SYSTEM_DECRYPTED"
|
servers:
|
||||||
luks_auto_decrypt: true
|
- "1.1.1.1"
|
||||||
luks_auto_decrypt_method: "tpm2"
|
disks:
|
||||||
luks_tpm2_device: "auto"
|
- device: "/dev/sda"
|
||||||
luks_tpm2_pcrs: "7"
|
size: 120
|
||||||
|
- device: "/dev/sdb"
|
||||||
|
size: 500
|
||||||
|
mount:
|
||||||
|
path: /data
|
||||||
|
fstype: ext4
|
||||||
|
user:
|
||||||
|
name: "admin"
|
||||||
|
password: "CHANGE_ME"
|
||||||
|
key: "ssh-ed25519 AAAA..."
|
||||||
|
root:
|
||||||
|
password: "CHANGE_ME"
|
||||||
|
luks:
|
||||||
|
enabled: true
|
||||||
|
passphrase: "CHANGE_ME"
|
||||||
|
mapper: "SYSTEM_DECRYPTED"
|
||||||
|
auto: true
|
||||||
|
method: "tpm2"
|
||||||
|
tpm2:
|
||||||
|
device: "auto"
|
||||||
|
pcrs: "7"
|
||||||
|
features:
|
||||||
|
cis:
|
||||||
|
enabled: false
|
||||||
|
selinux:
|
||||||
|
enabled: true
|
||||||
|
firewall:
|
||||||
|
enabled: true
|
||||||
|
backend: "firewalld"
|
||||||
|
toolkit: "nftables"
|
||||||
|
ssh:
|
||||||
|
enabled: true
|
||||||
|
zstd:
|
||||||
|
enabled: true
|
||||||
|
swap:
|
||||||
|
enabled: true
|
||||||
|
banner:
|
||||||
|
motd: true
|
||||||
|
sudo: true
|
||||||
|
chroot:
|
||||||
|
tool: "arch-chroot"
|
||||||
|
|||||||
129
vars_example.yml
129
vars_example.yml
@@ -1,42 +1,93 @@
|
|||||||
---
|
---
|
||||||
# Set vm_ip for static addressing. Remove vm_ip to use DHCP.
|
# Example variables for virtual provisioning.
|
||||||
vm_ip: "{{ inventory_hostname }}"
|
custom_iso: false
|
||||||
|
|
||||||
install_type: "virtual"
|
hypervisor:
|
||||||
install_drive: "/dev/sda" # Use /dev/vda for virtio/libvirt.
|
type: "proxmox" # libvirt|proxmox|vmware|xen|none
|
||||||
custom_iso: false # Set true to skip ArchISO-specific validation and pacman setup.
|
url: "pve01.example.com"
|
||||||
cis: false # Set true to enable CIS hardening.
|
username: "root@pam"
|
||||||
selinux: true # Toggle SELinux where supported.
|
password: "CHANGE_ME"
|
||||||
firewalld_enabled: true # Toggle firewalld package and service.
|
host: "pve01"
|
||||||
|
storage: "local-lvm"
|
||||||
|
datacenter: "dc01"
|
||||||
|
cluster: "cluster01"
|
||||||
|
certs: false
|
||||||
|
ssh: true # VMware only; enables temporary SSH in installer
|
||||||
|
|
||||||
hypervisor_url: "pve01.example.com"
|
system:
|
||||||
hypervisor_username: "root@pam"
|
type: "virtual" # virtual|physical
|
||||||
hypervisor_password: "CHANGE_ME"
|
os: "archlinux"
|
||||||
hypervisor_node: "pve01"
|
version: ""
|
||||||
hypervisor_storage: "local-lvm"
|
filesystem: "btrfs" # btrfs|ext4|xfs
|
||||||
hypervisor_datacenter: "dc01"
|
name: "{{ inventory_hostname }}"
|
||||||
hypervisor_cluster: "cluster01"
|
id: 100
|
||||||
|
cpus: 4
|
||||||
# VMware (only needed when hypervisor: vmware)
|
memory: 8192
|
||||||
# vm_path: "/Folder" # Optional folder path segment in vCenter.
|
balloon: 0
|
||||||
vmware_ssh: true
|
network: "vmbr0"
|
||||||
|
ip: "{{ inventory_hostname }}"
|
||||||
# LUKS disk encryption (optional)
|
prefix: 24
|
||||||
# These map to partitioning_luks_* internally.
|
gateway: "10.0.0.1"
|
||||||
luks_enabled: false
|
dns:
|
||||||
luks_passphrase: "CHANGE_ME"
|
servers:
|
||||||
luks_mapper_name: "SYSTEM_DECRYPTED"
|
- "1.1.1.1"
|
||||||
luks_auto_decrypt: true
|
- "1.0.0.1"
|
||||||
luks_auto_decrypt_method: "tpm2"
|
search:
|
||||||
luks_tpm2_device: "auto"
|
- "example.com"
|
||||||
luks_tpm2_pcrs: "7"
|
path: "/Lab/Example"
|
||||||
luks_keyfile_size: 64
|
disks:
|
||||||
luks_options: "discard,tries=3"
|
- size: 80
|
||||||
luks_type: "luks2"
|
- size: 200
|
||||||
luks_cipher: "aes-xts-plain64"
|
mount:
|
||||||
luks_hash: "sha512"
|
path: /data
|
||||||
luks_iter_time: 4000
|
fstype: xfs
|
||||||
luks_key_size: 512
|
label: DATA
|
||||||
luks_pbkdf: "argon2id"
|
opts: defaults
|
||||||
luks_use_urandom: true
|
user:
|
||||||
luks_verify_passphrase: true
|
name: "ops"
|
||||||
|
password: "CHANGE_ME"
|
||||||
|
key: "ssh-ed25519 AAAA..."
|
||||||
|
root:
|
||||||
|
password: "CHANGE_ME"
|
||||||
|
luks:
|
||||||
|
enabled: false
|
||||||
|
passphrase: "CHANGE_ME"
|
||||||
|
mapper: "SYSTEM_DECRYPTED"
|
||||||
|
auto: true
|
||||||
|
method: "tpm2"
|
||||||
|
tpm2:
|
||||||
|
device: "auto"
|
||||||
|
pcrs: "7"
|
||||||
|
keysize: 64
|
||||||
|
options: "discard,tries=3"
|
||||||
|
type: "luks2"
|
||||||
|
cipher: "aes-xts-plain64"
|
||||||
|
hash: "sha512"
|
||||||
|
iter: 4000
|
||||||
|
bits: 512
|
||||||
|
pbkdf: "argon2id"
|
||||||
|
urandom: true
|
||||||
|
verify: true
|
||||||
|
packages:
|
||||||
|
- jq
|
||||||
|
- tmux
|
||||||
|
features:
|
||||||
|
cis:
|
||||||
|
enabled: false
|
||||||
|
selinux:
|
||||||
|
enabled: true
|
||||||
|
firewall:
|
||||||
|
enabled: true
|
||||||
|
backend: "firewalld" # firewalld|ufw
|
||||||
|
toolkit: "nftables" # nftables|iptables
|
||||||
|
ssh:
|
||||||
|
enabled: true
|
||||||
|
zstd:
|
||||||
|
enabled: true
|
||||||
|
swap:
|
||||||
|
enabled: true
|
||||||
|
banner:
|
||||||
|
motd: true
|
||||||
|
sudo: true
|
||||||
|
chroot:
|
||||||
|
tool: "arch-chroot" # arch-chroot|chroot|systemd-nspawn
|
||||||
|
|||||||
Reference in New Issue
Block a user