refactor(vars): add system/hypervisor dict inputs
This commit is contained in:
@@ -2,44 +2,59 @@
|
||||
all:
|
||||
vars:
|
||||
install_type: "virtual"
|
||||
hypervisor: "proxmox"
|
||||
hypervisor:
|
||||
type: "proxmox"
|
||||
url: "pve01.example.com"
|
||||
username: "root@pam"
|
||||
password: "CHANGE_ME"
|
||||
node: "pve01"
|
||||
storage: "local-lvm"
|
||||
install_drive: "/dev/sda"
|
||||
boot_iso: "local:iso/archlinux-x86_64.iso"
|
||||
vm_nif: "vmbr0"
|
||||
children:
|
||||
proxmox:
|
||||
hosts:
|
||||
app01.example.com:
|
||||
ansible_host: 10.0.0.10
|
||||
hostname: "app01.example.com"
|
||||
os: "archlinux"
|
||||
filesystem: "btrfs"
|
||||
vm_id: 100
|
||||
vm_cpus: 2
|
||||
vm_memory: 4096
|
||||
vm_size: 40
|
||||
vm_ip: 10.0.0.10
|
||||
vm_nms: 24
|
||||
vm_gw: 10.0.0.1
|
||||
vm_dns:
|
||||
- 1.1.1.1
|
||||
- 1.0.0.1
|
||||
system:
|
||||
name: "app01.example.com"
|
||||
id: 100
|
||||
cpus: 2
|
||||
memory_mb: 4096
|
||||
network: "vmbr0"
|
||||
ip: 10.0.0.10
|
||||
prefix: 24
|
||||
gateway: 10.0.0.1
|
||||
dns_servers:
|
||||
- 1.1.1.1
|
||||
- 1.0.0.1
|
||||
disks:
|
||||
- size: 40
|
||||
- size: 80
|
||||
mount: /data
|
||||
fstype: xfs
|
||||
extra_packages:
|
||||
- jq
|
||||
- tmux
|
||||
db01.example.com:
|
||||
ansible_host: 10.0.0.11
|
||||
hostname: "db01.example.com"
|
||||
os: "rhel9"
|
||||
os: "rhel"
|
||||
os_version: "9"
|
||||
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"
|
||||
system:
|
||||
name: "db01.example.com"
|
||||
id: 101
|
||||
cpus: 4
|
||||
memory_mb: 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
|
||||
rhel_iso: "local:iso/rhel-9.4-x86_64-dvd.iso"
|
||||
luks_enabled: true
|
||||
luks_passphrase: "CHANGE_ME"
|
||||
@@ -47,4 +62,4 @@ all:
|
||||
luks_keyfile_size: 128
|
||||
cis: true
|
||||
selinux: false
|
||||
firewalld_enabled: false
|
||||
firewall_enabled: false
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
all:
|
||||
vars:
|
||||
install_type: "virtual"
|
||||
hypervisor: "libvirt"
|
||||
hypervisor:
|
||||
type: "libvirt"
|
||||
install_drive: "/dev/vda"
|
||||
boot_iso: "/var/lib/libvirt/images/archlinux-x86_64.iso"
|
||||
children:
|
||||
@@ -10,47 +11,55 @@ all:
|
||||
hosts:
|
||||
web01.example.com:
|
||||
ansible_host: 192.168.122.10
|
||||
hostname: "web01.example.com"
|
||||
os: "debian12"
|
||||
os: "debian"
|
||||
os_version: "12"
|
||||
filesystem: "ext4"
|
||||
vm_cpus: 2
|
||||
vm_memory: 2048
|
||||
vm_size: 30
|
||||
vm_ip: 192.168.122.10
|
||||
vm_nms: 24
|
||||
vm_gw: 192.168.122.1
|
||||
vm_dns: 1.1.1.1
|
||||
system:
|
||||
name: "web01.example.com"
|
||||
cpus: 2
|
||||
memory_mb: 2048
|
||||
ip: 192.168.122.10
|
||||
prefix: 24
|
||||
gateway: 192.168.122.1
|
||||
dns_servers: 1.1.1.1
|
||||
disks:
|
||||
- size: 30
|
||||
extra_packages:
|
||||
- nginx
|
||||
- fail2ban
|
||||
vault01.example.com:
|
||||
ansible_host: 192.168.122.11
|
||||
hostname: "vault01.example.com"
|
||||
os: "ubuntu-lts"
|
||||
filesystem: "btrfs"
|
||||
vm_cpus: 2
|
||||
vm_memory: 4096
|
||||
vm_size: 40
|
||||
vm_ip: 192.168.122.11
|
||||
vm_nms: 24
|
||||
vm_gw: 192.168.122.1
|
||||
vm_dns_search: "example.com"
|
||||
system:
|
||||
name: "vault01.example.com"
|
||||
cpus: 2
|
||||
memory_mb: 4096
|
||||
ip: 192.168.122.11
|
||||
prefix: 24
|
||||
gateway: 192.168.122.1
|
||||
dns_search: "example.com"
|
||||
disks:
|
||||
- size: 40
|
||||
luks_enabled: true
|
||||
luks_passphrase: "CHANGE_ME"
|
||||
luks_auto_decrypt_method: "keyfile"
|
||||
firewalld_enabled: false
|
||||
firewall_enabled: false
|
||||
rhel9.example.com:
|
||||
ansible_host: 192.168.122.12
|
||||
hostname: "rhel9.example.com"
|
||||
os: "rhel9"
|
||||
os: "rhel"
|
||||
os_version: "9"
|
||||
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"
|
||||
system:
|
||||
name: "rhel9.example.com"
|
||||
cpus: 4
|
||||
memory_mb: 8192
|
||||
vlan: "100"
|
||||
ip: 192.168.122.12
|
||||
prefix: 24
|
||||
gateway: 192.168.122.1
|
||||
dns_servers: "1.1.1.1,1.0.0.1"
|
||||
path: "/srv/libvirt/images"
|
||||
disks:
|
||||
- size: 80
|
||||
rhel_iso: "/var/lib/libvirt/images/rhel-9.4-x86_64-dvd.iso"
|
||||
vlan_name: "100"
|
||||
|
||||
8
main.yml
8
main.yml
@@ -1,7 +1,7 @@
|
||||
---
|
||||
- name: Create and configure VMs
|
||||
hosts: all
|
||||
strategy: free # noqa: run-once[play]
|
||||
strategy: free # noqa: run-once[play]
|
||||
gather_facts: false
|
||||
become: true
|
||||
vars_prompt:
|
||||
@@ -29,6 +29,10 @@
|
||||
ansible.builtin.import_role:
|
||||
name: global_defaults
|
||||
|
||||
- name: Perform safety checks
|
||||
ansible.builtin.import_role:
|
||||
name: system_check
|
||||
|
||||
roles:
|
||||
- role: virtualization
|
||||
when: install_type == "virtual"
|
||||
@@ -62,7 +66,7 @@
|
||||
post_reboot_can_connect: >-
|
||||
{{
|
||||
(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 (
|
||||
install_type == 'physical'
|
||||
and (ansible_host | default('') | string | length) > 0
|
||||
|
||||
@@ -1,20 +1,35 @@
|
||||
---
|
||||
- name: Bootstrap AlmaLinux 9
|
||||
- name: Bootstrap AlmaLinux
|
||||
vars:
|
||||
bootstrap_alma_extra: >-
|
||||
bootstrap_almalinux_extra: >-
|
||||
{{
|
||||
lookup('vars', bootstrap_var_key)
|
||||
| reject('equalto', '')
|
||||
| join(' ')
|
||||
}}
|
||||
ansible.builtin.command: "{{ item }}"
|
||||
loop:
|
||||
- >-
|
||||
dnf --releasever=9 --best --repo=alma-baseos --installroot=/mnt
|
||||
--setopt=install_weak_deps=False groupinstall -y base core
|
||||
- ln -sf /run/NetworkManager/resolv.conf /mnt/etc/resolv.conf
|
||||
- >-
|
||||
{{ chroot_command }} /mnt dnf --releasever=9 --setopt=install_weak_deps=False
|
||||
install -y {{ bootstrap_alma_extra }}
|
||||
register: bootstrap_result
|
||||
changed_when: bootstrap_result.rc == 0
|
||||
block:
|
||||
- name: Install AlmaLinux base system
|
||||
ansible.builtin.command: >-
|
||||
dnf --releasever={{ os_version }} --best --repo=baseos --repo=appstream
|
||||
--installroot=/mnt --setopt=install_weak_deps=False
|
||||
groupinstall -y core
|
||||
register: bootstrap_almalinux_base_result
|
||||
changed_when: bootstrap_almalinux_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: 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,13 +3,27 @@
|
||||
vars:
|
||||
bootstrap_debian_release: >-
|
||||
{{
|
||||
'bullseye' if bootstrap_os_key == 'debian11'
|
||||
else 'bookworm' if bootstrap_os_key == 'debian12'
|
||||
'buster' if (os_version | string) == '10'
|
||||
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'
|
||||
}}
|
||||
bootstrap_debian_base_list: "{{ lookup('vars', bootstrap_var_key).base | default([]) }}"
|
||||
bootstrap_debian_extra_list: "{{ lookup('vars', bootstrap_var_key).extra | default([]) }}"
|
||||
bootstrap_debian_base: "{{ bootstrap_debian_base_list | reject('equalto', '') | join(',') }}"
|
||||
bootstrap_debian_version_packages: >-
|
||||
{{
|
||||
lookup('vars', bootstrap_var_key)
|
||||
| reject('equalto', '')
|
||||
| list
|
||||
}}
|
||||
bootstrap_debian_base_list: >-
|
||||
{{
|
||||
bootstrap_debian_base
|
||||
| reject('equalto', '')
|
||||
| list
|
||||
}}
|
||||
bootstrap_debian_extra_list: "{{ bootstrap_debian_version_packages | difference(bootstrap_debian_base_list) }}"
|
||||
bootstrap_debian_base: "{{ bootstrap_debian_base_list | join(',') }}"
|
||||
bootstrap_debian_extra: >-
|
||||
{{
|
||||
(
|
||||
@@ -18,12 +32,20 @@
|
||||
| reject('equalto', '')
|
||||
| join(' ')
|
||||
}}
|
||||
ansible.builtin.command: "{{ item }}"
|
||||
loop:
|
||||
- >-
|
||||
block:
|
||||
- name: Install Debian base system
|
||||
ansible.builtin.command: >-
|
||||
debootstrap --include={{ bootstrap_debian_base }}
|
||||
{{ bootstrap_debian_release }} /mnt http://deb.debian.org/debian/
|
||||
- "{{ chroot_command }} /mnt apt install -y {{ bootstrap_debian_extra }}"
|
||||
- "{{ chroot_command }} /mnt apt remove -y libcups2 libavahi-common3 libavahi-common-data"
|
||||
register: bootstrap_result
|
||||
changed_when: bootstrap_result.rc == 0
|
||||
register: bootstrap_debian_base_result
|
||||
changed_when: bootstrap_debian_base_result.rc == 0
|
||||
|
||||
- name: Install extra packages
|
||||
ansible.builtin.command: "{{ chroot_command }} apt install -y {{ bootstrap_debian_extra }}"
|
||||
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:
|
||||
bootstrap_fedora_extra: >-
|
||||
{{
|
||||
@@ -7,16 +7,29 @@
|
||||
| reject('equalto', '')
|
||||
| join(' ')
|
||||
}}
|
||||
ansible.builtin.command: "{{ item }}"
|
||||
loop:
|
||||
- >-
|
||||
dnf --releasever=43 --best --repo=fedora --repo=fedora-updates
|
||||
block:
|
||||
- name: Install Fedora base system
|
||||
ansible.builtin.command: >-
|
||||
dnf --releasever={{ os_version }} --best --repo=fedora --repo=fedora-updates
|
||||
--installroot=/mnt --setopt=install_weak_deps=False
|
||||
groupinstall -y critical-path-base core
|
||||
- ln -sf /run/NetworkManager/resolv.conf /mnt/etc/resolv.conf
|
||||
- >-
|
||||
{{ chroot_command }} /mnt dnf --releasever=43 --setopt=install_weak_deps=False
|
||||
register: bootstrap_fedora_base_result
|
||||
changed_when: bootstrap_fedora_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: Install extra packages
|
||||
ansible.builtin.command: >-
|
||||
{{ chroot_command }} dnf --releasever={{ os_version }} --setopt=install_weak_deps=False
|
||||
install -y {{ bootstrap_fedora_extra }}
|
||||
- "{{ chroot_command }} /mnt dnf reinstall -y kernel-core"
|
||||
register: bootstrap_result
|
||||
changed_when: bootstrap_result.rc == 0
|
||||
register: bootstrap_fedora_extra_result
|
||||
changed_when: bootstrap_fedora_extra_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
|
||||
vars:
|
||||
bootstrap_os_key: "{{ os | lower }}"
|
||||
bootstrap_var_key: "{{ 'bootstrap_' + (os | lower | replace('-', '_')) }}"
|
||||
bootstrap_os_key: "{{ (os_resolved | default(os)) | lower }}"
|
||||
bootstrap_var_key: "{{ 'bootstrap_' + ((os_resolved | default(os)) | lower | replace('-', '_')) }}"
|
||||
block:
|
||||
- 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
|
||||
|
||||
- name: Include Alpine bootstrap tasks
|
||||
when: bootstrap_os_key == 'alpine'
|
||||
ansible.builtin.include_tasks: alpine.yml
|
||||
|
||||
- name: Include ArchLinux bootstrap tasks
|
||||
when: bootstrap_os_key == 'archlinux'
|
||||
ansible.builtin.include_tasks: archlinux.yml
|
||||
|
||||
- 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
|
||||
|
||||
- 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
|
||||
|
||||
- name: Include openSUSE bootstrap tasks
|
||||
when: bootstrap_os_key == 'opensuse'
|
||||
ansible.builtin.include_tasks: opensuse.yml
|
||||
|
||||
- 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
|
||||
|
||||
- name: Include RHEL bootstrap tasks
|
||||
@@ -31,3 +39,7 @@
|
||||
- name: Include Ubuntu bootstrap tasks
|
||||
when: bootstrap_os_key in ['ubuntu', 'ubuntu-lts']
|
||||
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
|
||||
dest: /mnt/etc/resolv.conf
|
||||
state: link
|
||||
force: true
|
||||
|
||||
- name: Ensure chroot RHEL DVD directory exists
|
||||
ansible.builtin.file:
|
||||
@@ -34,7 +33,7 @@
|
||||
state: mounted
|
||||
|
||||
- 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
|
||||
changed_when: bootstrap_rpm_rebuild_result.rc == 0
|
||||
|
||||
@@ -55,7 +54,7 @@
|
||||
| join(' ')
|
||||
}}
|
||||
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 }}
|
||||
register: bootstrap_result
|
||||
changed_when: bootstrap_result.rc == 0
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
- name: Bootstrap RockyLinux 9
|
||||
- name: Bootstrap Rocky Linux
|
||||
vars:
|
||||
bootstrap_rocky_extra: >-
|
||||
{{
|
||||
@@ -7,15 +7,29 @@
|
||||
| reject('equalto', '')
|
||||
| join(' ')
|
||||
}}
|
||||
ansible.builtin.command: "{{ item }}"
|
||||
loop:
|
||||
- >-
|
||||
dnf --releasever=9 --best --repo=rocky-baseos --installroot=/mnt
|
||||
--setopt=install_weak_deps=False --setopt=optional_metadata_types=filelists
|
||||
groupinstall -y base core
|
||||
- ln -sf /run/NetworkManager/resolv.conf /mnt/etc/resolv.conf
|
||||
- >-
|
||||
{{ chroot_command }} /mnt dnf --releasever=9 --setopt=install_weak_deps=False
|
||||
block:
|
||||
- name: Install Rocky Linux base system
|
||||
ansible.builtin.command: >-
|
||||
dnf --releasever={{ os_version }} --best --repo=baseos --repo=appstream
|
||||
--installroot=/mnt --setopt=install_weak_deps=False
|
||||
groupinstall -y core
|
||||
register: bootstrap_rocky_base_result
|
||||
changed_when: bootstrap_rocky_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: Install extra packages
|
||||
ansible.builtin.command: >-
|
||||
{{ chroot_command }} dnf --releasever={{ os_version }} --setopt=install_weak_deps=False
|
||||
install -y {{ bootstrap_rocky_extra }}
|
||||
register: bootstrap_result
|
||||
changed_when: bootstrap_result.rc == 0
|
||||
register: bootstrap_rocky_extra_result
|
||||
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,38 @@
|
||||
vars:
|
||||
bootstrap_ubuntu_release: >-
|
||||
{{ 'plucky' if bootstrap_os_key == 'ubuntu' else 'noble' }}
|
||||
bootstrap_ubuntu_base_list: "{{ lookup('vars', bootstrap_var_key).base | default([]) }}"
|
||||
bootstrap_ubuntu_extra_list: "{{ lookup('vars', bootstrap_var_key).extra | default([]) }}"
|
||||
bootstrap_ubuntu_base: "{{ bootstrap_ubuntu_base_list | reject('equalto', '') | join(',') }}"
|
||||
bootstrap_ubuntu_extra: >-
|
||||
{{
|
||||
(
|
||||
bootstrap_ubuntu_extra_list
|
||||
)
|
||||
lookup('vars', bootstrap_var_key)
|
||||
| reject('equalto', '')
|
||||
| join(' ')
|
||||
}}
|
||||
ansible.builtin.command: "{{ item }}"
|
||||
loop:
|
||||
- >-
|
||||
debootstrap --include={{ bootstrap_ubuntu_base }}
|
||||
{{ bootstrap_ubuntu_release }} /mnt http://archive.ubuntu.com/ubuntu/
|
||||
- ln -sf /run/NetworkManager/resolv.conf /mnt/etc/resolv.conf
|
||||
- "{{ chroot_command }} /mnt sed -i '1s|$| universe|' /etc/apt/sources.list"
|
||||
- "{{ chroot_command }} /mnt apt update"
|
||||
- "{{ chroot_command }} /mnt apt install -y {{ bootstrap_ubuntu_extra }}"
|
||||
register: bootstrap_result
|
||||
changed_when: bootstrap_result.rc == 0
|
||||
block:
|
||||
- name: Install Ubuntu base system
|
||||
ansible.builtin.command: >-
|
||||
debootstrap --include=linux-image-generic
|
||||
{{ 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
|
||||
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,21 +1,20 @@
|
||||
---
|
||||
bootstrap_almalinux:
|
||||
bootstrap_rhel_base:
|
||||
- bind-utils
|
||||
- dbus-daemon
|
||||
- dhcp-client
|
||||
- efibootmgr
|
||||
- "{{ 'firewalld' if firewalld_enabled | bool else '' }}"
|
||||
- "{{ 'firewalld' if firewall_backend == 'firewalld' and firewall_enabled | bool else '' }}"
|
||||
- "{{ 'ufw' if firewall_backend == 'ufw' and firewall_enabled | bool else '' }}"
|
||||
- "{{ 'iptables' if firewall_toolkit == 'iptables' else '' }}"
|
||||
- "{{ 'nftables' if firewall_toolkit == 'nftables' else '' }}"
|
||||
- glibc-langpack-de
|
||||
- glibc-langpack-en
|
||||
- grub2
|
||||
- grub2-efi
|
||||
- lrzsz
|
||||
- lvm2
|
||||
- nc
|
||||
- nfs-utils
|
||||
- nfsv4-client-utils
|
||||
- mtr
|
||||
- ppp
|
||||
- ncurses-term
|
||||
- nfs-utils
|
||||
- policycoreutils-python-utils
|
||||
- shim
|
||||
- tmux
|
||||
- "{{ 'cryptsetup' if luks_enabled else '' }}"
|
||||
@@ -23,10 +22,162 @@ bootstrap_almalinux:
|
||||
- "{{ 'qemu-guest-agent' if hypervisor | lower in ['libvirt', 'proxmox'] else '' }}"
|
||||
- "{{ 'open-vm-tools' if hypervisor | lower == 'vmware' else '' }}"
|
||||
- vim
|
||||
- wget
|
||||
- zram-generator
|
||||
- zstd
|
||||
|
||||
bootstrap_rhel_versioned:
|
||||
- grub2
|
||||
- "{{ 'grub2-efi-x64' if os_version_major | default('') == '8' else 'grub2-efi' }}"
|
||||
- "{{ 'grub2-tools-extra' if os_version_major | default('') in ['8', '9'] else '' }}"
|
||||
- "{{ 'python39' if os_version_major | default('') == '8' else 'python' }}"
|
||||
- "{{ 'kernel' if os_version_major | default('') == '10' else '' }}"
|
||||
|
||||
bootstrap_rhel_common: "{{ bootstrap_rhel_base + bootstrap_rhel_versioned }}"
|
||||
|
||||
bootstrap_rhel8: "{{ bootstrap_rhel_common }}"
|
||||
bootstrap_rhel9: "{{ bootstrap_rhel_common }}"
|
||||
bootstrap_rhel10: "{{ bootstrap_rhel_common }}"
|
||||
|
||||
bootstrap_almalinux:
|
||||
"{{ bootstrap_rhel_base + ['grub2', 'grub2-efi', 'dbus-daemon', 'lrzsz', 'nfsv4-client-utils', 'nc', 'ppp'] }}"
|
||||
|
||||
bootstrap_rocky:
|
||||
"{{ bootstrap_rhel_base + ['grub2', 'grub2-efi', 'nfsv4-client-utils', 'nc', 'ppp', 'telnet', 'util-linux-core', 'wget'] }}"
|
||||
|
||||
bootstrap_almalinux8: "{{ bootstrap_almalinux }}"
|
||||
bootstrap_almalinux9: "{{ bootstrap_almalinux }}"
|
||||
bootstrap_almalinux10: "{{ bootstrap_almalinux }}"
|
||||
|
||||
bootstrap_rocky8: "{{ bootstrap_rocky }}"
|
||||
bootstrap_rocky9: "{{ bootstrap_rocky }}"
|
||||
bootstrap_rocky10: "{{ bootstrap_rocky }}"
|
||||
|
||||
bootstrap_fedora:
|
||||
- bat
|
||||
- bind-utils
|
||||
- btrfs-progs
|
||||
- cronie
|
||||
- dhcp-client
|
||||
- duf
|
||||
- efibootmgr
|
||||
- entr
|
||||
- "{{ 'firewalld' if firewall_backend == 'firewalld' and firewall_enabled | bool else '' }}"
|
||||
- "{{ 'ufw' if firewall_backend == 'ufw' and firewall_enabled | bool else '' }}"
|
||||
- "{{ 'iptables' if firewall_toolkit == 'iptables' else '' }}"
|
||||
- "{{ 'nftables' if firewall_toolkit == 'nftables' else '' }}"
|
||||
- fish
|
||||
- fzf
|
||||
- glibc-langpack-de
|
||||
- glibc-langpack-en
|
||||
- grub2
|
||||
- grub2-efi
|
||||
- htop
|
||||
- iperf3
|
||||
- logrotate
|
||||
- lrzsz
|
||||
- lvm2
|
||||
- nc
|
||||
- nfs-utils
|
||||
- nfsv4-client-utils
|
||||
- polkit
|
||||
- ppp
|
||||
- ripgrep
|
||||
- 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-default-editor
|
||||
- wget
|
||||
- zoxide
|
||||
- zram-generator
|
||||
- zstd
|
||||
|
||||
bootstrap_fedora40: "{{ bootstrap_fedora }}"
|
||||
bootstrap_fedora41: "{{ bootstrap_fedora }}"
|
||||
bootstrap_fedora42: "{{ bootstrap_fedora }}"
|
||||
bootstrap_fedora43: "{{ bootstrap_fedora }}"
|
||||
|
||||
bootstrap_debian_base:
|
||||
- btrfs-progs
|
||||
- cron
|
||||
- gnupg
|
||||
- grub-efi
|
||||
- grub-efi-amd64-signed
|
||||
- grub2-common
|
||||
- "{{ 'cryptsetup' if luks_enabled else '' }}"
|
||||
- "{{ 'cryptsetup-initramfs' if luks_enabled else '' }}"
|
||||
- locales
|
||||
- logrotate
|
||||
- lvm2
|
||||
- "{{ 'iptables' if firewall_toolkit == 'iptables' else '' }}"
|
||||
- "{{ 'nftables' if firewall_toolkit == 'nftables' else '' }}"
|
||||
- "{{ 'openssh-server' if ssh_enabled | bool else '' }}"
|
||||
- python3
|
||||
- xfsprogs
|
||||
|
||||
bootstrap_debian_extra:
|
||||
- apparmor-utils
|
||||
- bat
|
||||
- chrony
|
||||
- curl
|
||||
- duf
|
||||
- entr
|
||||
- "{{ 'firewalld' if firewall_backend == 'firewalld' and firewall_enabled | bool else '' }}"
|
||||
- "{{ 'ufw' if firewall_backend == 'ufw' and firewall_enabled | bool else '' }}"
|
||||
- fish
|
||||
- fzf
|
||||
- htop
|
||||
- jq
|
||||
- libpam-pwquality
|
||||
- lrzsz
|
||||
- mtr
|
||||
- ncdu
|
||||
- net-tools
|
||||
- network-manager
|
||||
- python-is-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_debian_versioned:
|
||||
- "{{ 'linux-image-amd64' if (os_version | string) in ['10', '11', '13', 'unstable'] else '' }}"
|
||||
- "{{ 'fastfetch' if (os_version | string) in ['12', '13', 'unstable'] else '' }}"
|
||||
- "{{ 'neofetch' if (os_version | string) == '12' else '' }}"
|
||||
|
||||
bootstrap_debian_common: "{{ bootstrap_debian_base + bootstrap_debian_extra + bootstrap_debian_versioned }}"
|
||||
|
||||
bootstrap_debian10: "{{ bootstrap_debian_common }}"
|
||||
bootstrap_debian11: "{{ bootstrap_debian_common }}"
|
||||
bootstrap_debian12: "{{ bootstrap_debian_common }}"
|
||||
bootstrap_debian13: "{{ bootstrap_debian_common }}"
|
||||
bootstrap_debianunstable: "{{ bootstrap_debian_common }}"
|
||||
|
||||
bootstrap_ubuntu:
|
||||
"{{
|
||||
bootstrap_debian_base + bootstrap_debian_extra +
|
||||
['bash-completion', 'dnsutils', 'eza', 'fdupes', 'fio', 'ncurses-term', 'traceroute', 'util-linux-extra', 'yq', 'zoxide']
|
||||
}}"
|
||||
|
||||
bootstrap_ubuntu_lts:
|
||||
"{{
|
||||
bootstrap_debian_base + bootstrap_debian_extra +
|
||||
['bash-completion', 'dnsutils', 'eza', 'fdupes', 'fio', 'ncurses-term', 'traceroute', 'util-linux-extra', 'yq', 'zoxide']
|
||||
}}"
|
||||
|
||||
bootstrap_archlinux:
|
||||
- base
|
||||
- btrfs-progs
|
||||
@@ -34,7 +185,10 @@ bootstrap_archlinux:
|
||||
- dhcpcd
|
||||
- efibootmgr
|
||||
- fastfetch
|
||||
- "{{ 'firewalld' if firewalld_enabled | bool else '' }}"
|
||||
- "{{ 'firewalld' if firewall_backend == 'firewalld' and firewall_enabled | bool else '' }}"
|
||||
- "{{ 'ufw' if firewall_backend == 'ufw' and firewall_enabled | bool else '' }}"
|
||||
- "{{ 'iptables' if firewall_toolkit == 'iptables' else '' }}"
|
||||
- "{{ 'iptables-nft' if firewall_toolkit == 'nftables' else '' }}"
|
||||
- fish
|
||||
- fzf
|
||||
- grub
|
||||
@@ -65,436 +219,39 @@ bootstrap_archlinux:
|
||||
- wireguard-tools
|
||||
- zram-generator
|
||||
|
||||
bootstrap_debian11:
|
||||
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:
|
||||
- bat
|
||||
- curl
|
||||
- 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:
|
||||
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-amd64
|
||||
- locales
|
||||
- logrotate
|
||||
- lvm2
|
||||
- xfsprogs
|
||||
|
||||
extra:
|
||||
- apparmor-utils
|
||||
- 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:
|
||||
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-amd64
|
||||
- locales
|
||||
- logrotate
|
||||
- lvm2
|
||||
- xfsprogs
|
||||
|
||||
extra:
|
||||
- apparmor-utils
|
||||
- bat
|
||||
- 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:
|
||||
- bat
|
||||
- bind-utils
|
||||
- btrfs-progs
|
||||
- cronie
|
||||
- dhcp-client
|
||||
- duf
|
||||
- efibootmgr
|
||||
- entr
|
||||
- "{{ 'firewalld' if firewalld_enabled | bool else '' }}"
|
||||
- fish
|
||||
- fzf
|
||||
- glibc-langpack-de
|
||||
- glibc-langpack-en
|
||||
- grub2
|
||||
- grub2-efi
|
||||
- htop
|
||||
- iperf3
|
||||
- logrotate
|
||||
- lrzsz
|
||||
- lvm2
|
||||
- nc
|
||||
- nfs-utils
|
||||
- nfsv4-client-utils
|
||||
- polkit
|
||||
- ppp
|
||||
- ripgrep
|
||||
- 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-default-editor
|
||||
- wget
|
||||
- zoxide
|
||||
- zram-generator
|
||||
- zstd
|
||||
|
||||
bootstrap_rhel8:
|
||||
- bind-utils
|
||||
- dhcp-client
|
||||
- efibootmgr
|
||||
- "{{ '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 '' }}"
|
||||
bootstrap_alpine:
|
||||
- alpine-base
|
||||
- vim
|
||||
- zstd
|
||||
|
||||
bootstrap_rhel9:
|
||||
- bind-utils
|
||||
- dhcp-client
|
||||
- efibootmgr
|
||||
- "{{ 'firewalld' if firewalld_enabled | bool else '' }}"
|
||||
- glibc-langpack-de
|
||||
- glibc-langpack-en
|
||||
- grub2
|
||||
- grub2-efi
|
||||
- grub2-tools-extra
|
||||
- lrzsz
|
||||
- lvm2
|
||||
- mtr
|
||||
- ncurses-term
|
||||
- nfs-utils
|
||||
- policycoreutils-python-utils
|
||||
- python
|
||||
- shim
|
||||
- tmux
|
||||
- "{{ 'cryptsetup' if luks_enabled else '' }}"
|
||||
- "{{ 'tpm2-tools' if luks_enabled else '' }}"
|
||||
- "{{ 'openssh' if ssh_enabled | bool 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:
|
||||
- bind-utils
|
||||
- efibootmgr
|
||||
- "{{ 'firewalld' if firewalld_enabled | bool else '' }}"
|
||||
- glibc-langpack-de
|
||||
- glibc-langpack-en
|
||||
- grub2
|
||||
- grub2-efi
|
||||
- kernel
|
||||
- lrzsz
|
||||
- lvm2
|
||||
- mtr
|
||||
- ncurses-term
|
||||
- nfs-utils
|
||||
- policycoreutils-python-utils
|
||||
- python
|
||||
- shim
|
||||
- tmux
|
||||
- "{{ 'firewalld' if firewall_backend == 'firewalld' and firewall_enabled | bool else '' }}"
|
||||
- "{{ 'ufw' if firewall_backend == 'ufw' and firewall_enabled | bool else '' }}"
|
||||
- "{{ 'iptables' if firewall_toolkit == 'iptables' else '' }}"
|
||||
- "{{ 'nftables' if firewall_toolkit == 'nftables' else '' }}"
|
||||
- "{{ 'cryptsetup' if luks_enabled else '' }}"
|
||||
- "{{ 'tpm2-tools' if luks_enabled else '' }}"
|
||||
|
||||
bootstrap_opensuse:
|
||||
- vim
|
||||
- "{{ 'openssh' if ssh_enabled | bool else '' }}"
|
||||
- "{{ 'qemu-guest-agent' if hypervisor | lower in ['libvirt', 'proxmox'] else '' }}"
|
||||
- "{{ 'open-vm-tools' if hypervisor | lower == 'vmware' else '' }}"
|
||||
- vim
|
||||
- zram-generator
|
||||
- zstd
|
||||
|
||||
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
|
||||
- "{{ 'firewalld' if firewall_backend == 'firewalld' and firewall_enabled | bool else '' }}"
|
||||
- "{{ 'ufw' if firewall_backend == 'ufw' and firewall_enabled | bool else '' }}"
|
||||
- "{{ 'iptables' if firewall_toolkit == 'iptables' else '' }}"
|
||||
- "{{ 'nftables' if firewall_toolkit == 'nftables' else '' }}"
|
||||
- "{{ 'cryptsetup' if luks_enabled else '' }}"
|
||||
- "{{ 'tpm2-tools' if luks_enabled else '' }}"
|
||||
|
||||
bootstrap_void:
|
||||
- vim
|
||||
- "{{ 'openssh' if ssh_enabled | bool else '' }}"
|
||||
- "{{ 'qemu-guest-agent' if hypervisor | lower in ['libvirt', 'proxmox'] else '' }}"
|
||||
- "{{ 'open-vm-tools' if hypervisor | lower == 'vmware' else '' }}"
|
||||
- util-linux-core
|
||||
- vim
|
||||
- wget
|
||||
- zram-generator
|
||||
- zstd
|
||||
|
||||
bootstrap_ubuntu:
|
||||
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
|
||||
- locales
|
||||
- lvm2
|
||||
- xfsprogs
|
||||
|
||||
extra:
|
||||
- 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:
|
||||
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
|
||||
- locales
|
||||
- lvm2
|
||||
- xfsprogs
|
||||
|
||||
extra:
|
||||
- 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
|
||||
- "{{ 'firewalld' if firewall_backend == 'firewalld' and firewall_enabled | bool else '' }}"
|
||||
- "{{ 'ufw' if firewall_backend == 'ufw' and firewall_enabled | bool else '' }}"
|
||||
- "{{ 'iptables' if firewall_toolkit == 'iptables' else '' }}"
|
||||
- "{{ 'nftables' if firewall_toolkit == 'nftables' else '' }}"
|
||||
- "{{ 'cryptsetup' if luks_enabled else '' }}"
|
||||
- "{{ 'tpm2-tools' if luks_enabled else '' }}"
|
||||
|
||||
@@ -10,12 +10,12 @@ cis_permission_targets: >-
|
||||
{ "path": "/mnt/etc/cron.d", "mode": "0700" },
|
||||
{ "path": "/mnt/etc/crontab", "mode": "0600" },
|
||||
{ "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/"
|
||||
+ ("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"
|
||||
},
|
||||
{ "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")
|
||||
}}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
---
|
||||
- name: Configure System Cryptography Policy
|
||||
when: os in ["almalinux", "rhel9", "rhel10", "rocky"]
|
||||
ansible.builtin.command: "{{ chroot_command }} /mnt /usr/bin/update-crypto-policies --set DEFAULT:NO-SHA1"
|
||||
when: os == "rhel" or os in ["almalinux", "rocky"]
|
||||
ansible.builtin.command: "{{ chroot_command }} /usr/bin/update-crypto-policies --set DEFAULT:NO-SHA1"
|
||||
register: cis_crypto_policy_result
|
||||
changed_when: "'Setting system-wide crypto-policies to' in cis_crypto_policy_result.stdout"
|
||||
|
||||
- name: Mask Systemd Services
|
||||
ansible.builtin.command: >
|
||||
{{ chroot_command }} /mnt systemctl mask nftables bluetooth rpcbind
|
||||
{{ chroot_command }} systemctl mask {{ 'nftables' if firewall_toolkit == 'iptables' else 'iptables' }} bluetooth rpcbind
|
||||
register: cis_mask_services_result
|
||||
changed_when: cis_mask_services_result.rc == 0
|
||||
|
||||
@@ -4,21 +4,21 @@
|
||||
path: "{{ item.path }}"
|
||||
line: "{{ item.content }}"
|
||||
loop:
|
||||
- {path: /mnt/etc/security/limits.conf, content: "* hard core 0"}
|
||||
- {path: /mnt/etc/security/pwquality.conf, content: minlen = 14}
|
||||
- {path: /mnt/etc/security/pwquality.conf, content: dcredit = -1}
|
||||
- {path: /mnt/etc/security/pwquality.conf, content: ucredit = -1}
|
||||
- {path: /mnt/etc/security/pwquality.conf, content: ocredit = -1}
|
||||
- {path: /mnt/etc/security/pwquality.conf, content: lcredit = -1}
|
||||
- {path: '/mnt/etc/{{ "bashrc" if is_rhel else "bash.bashrc" }}', content: umask 077}
|
||||
- {path: '/mnt/etc/{{ "bashrc" if is_rhel else "bash.bashrc" }}', content: export TMOUT=3000}
|
||||
- {path: '/mnt/{{ "usr/lib/systemd/journald.conf" if os == "fedora" else "etc/systemd/journald.conf" }}', content: Storage=persistent}
|
||||
- {path: /mnt/etc/sudoers, content: Defaults logfile="/var/log/sudo.log"}
|
||||
- {path: /mnt/etc/pam.d/su, content: auth required pam_wheel.so}
|
||||
- { path: /mnt/etc/security/limits.conf, content: "* hard core 0" }
|
||||
- { path: /mnt/etc/security/pwquality.conf, content: minlen = 14 }
|
||||
- { path: /mnt/etc/security/pwquality.conf, content: dcredit = -1 }
|
||||
- { path: /mnt/etc/security/pwquality.conf, content: ucredit = -1 }
|
||||
- { path: /mnt/etc/security/pwquality.conf, content: ocredit = -1 }
|
||||
- { path: /mnt/etc/security/pwquality.conf, content: lcredit = -1 }
|
||||
- { path: '/mnt/etc/{{ "bashrc" if is_rhel else "bash.bashrc" }}', content: umask 077 }
|
||||
- { path: '/mnt/etc/{{ "bashrc" if is_rhel else "bash.bashrc" }}', content: export TMOUT=3000 }
|
||||
- { path: '/mnt/{{ "usr/lib/systemd/journald.conf" if os == "fedora" else "etc/systemd/journald.conf" }}', content: Storage=persistent }
|
||||
- { path: /mnt/etc/sudoers, content: Defaults logfile="/var/log/sudo.log" }
|
||||
- { path: /mnt/etc/pam.d/su, content: auth required pam_wheel.so }
|
||||
- path: >-
|
||||
/mnt/etc/{{
|
||||
"pam.d/common-auth"
|
||||
if os in ["debian11", "debian12", "ubuntu", "ubuntu-lts"]
|
||||
if is_debian | bool
|
||||
else "authselect/system-auth"
|
||||
if os == "fedora"
|
||||
else "pam.d/system-auth"
|
||||
@@ -28,7 +28,7 @@
|
||||
- path: >-
|
||||
/mnt/etc/{{
|
||||
"pam.d/common-account"
|
||||
if os in ["debian11", "debian12", "ubuntu", "ubuntu-lts"]
|
||||
if is_debian | bool
|
||||
else "authselect/system-auth"
|
||||
if os == "fedora"
|
||||
else "pam.d/system-auth"
|
||||
@@ -37,10 +37,10 @@
|
||||
- path: >-
|
||||
/mnt/etc/pam.d/{{
|
||||
"common-password"
|
||||
if os in ["debian11", "debian12", "ubuntu", "ubuntu-lts"]
|
||||
if is_debian | bool
|
||||
else "passwd"
|
||||
}}
|
||||
content: >-
|
||||
password [success=1 default=ignore] pam_unix.so obscure sha512 remember=5
|
||||
- {path: /mnt/etc/hosts.deny, content: "ALL: ALL"}
|
||||
- {path: /mnt/etc/hosts.allow, content: "sshd: ALL"}
|
||||
- { path: /mnt/etc/hosts.deny, content: "ALL: ALL" }
|
||||
- { path: /mnt/etc/hosts.allow, content: "sshd: ALL" }
|
||||
|
||||
@@ -5,30 +5,30 @@
|
||||
regexp: ^\s*#?{{ item.option }}\s+.*$
|
||||
line: "{{ item.option }} {{ item.value }}"
|
||||
loop:
|
||||
- {option: LogLevel, value: VERBOSE}
|
||||
- {option: LoginGraceTime, value: "60"}
|
||||
- {option: PermitRootLogin, value: "no"}
|
||||
- {option: StrictModes, value: "yes"}
|
||||
- {option: MaxAuthTries, value: "4"}
|
||||
- {option: MaxSessions, value: "10"}
|
||||
- {option: MaxStartups, value: "10:30:60"}
|
||||
- {option: PubkeyAuthentication, value: "yes"}
|
||||
- {option: HostbasedAuthentication, value: "no"}
|
||||
- {option: IgnoreRhosts, value: "yes"}
|
||||
- {option: PasswordAuthentication, value: "no"}
|
||||
- {option: PermitEmptyPasswords, value: "no"}
|
||||
- {option: KerberosAuthentication, value: "no"}
|
||||
- {option: GSSAPIAuthentication, value: "no"}
|
||||
- {option: AllowAgentForwarding, value: "no"}
|
||||
- {option: AllowTcpForwarding, value: "no"}
|
||||
- {option: ChallengeResponseAuthentication, value: "no"}
|
||||
- {option: GatewayPorts, value: "no"}
|
||||
- {option: X11Forwarding, value: "no"}
|
||||
- {option: PermitUserEnvironment, value: "no"}
|
||||
- {option: ClientAliveInterval, value: "300"}
|
||||
- {option: ClientAliveCountMax, value: "1"}
|
||||
- {option: PermitTunnel, value: "no"}
|
||||
- {option: Banner, value: /etc/issue.net}
|
||||
- { option: LogLevel, value: VERBOSE }
|
||||
- { option: LoginGraceTime, value: "60" }
|
||||
- { option: PermitRootLogin, value: "no" }
|
||||
- { option: StrictModes, value: "yes" }
|
||||
- { option: MaxAuthTries, value: "4" }
|
||||
- { option: MaxSessions, value: "10" }
|
||||
- { option: MaxStartups, value: "10:30:60" }
|
||||
- { option: PubkeyAuthentication, value: "yes" }
|
||||
- { option: HostbasedAuthentication, value: "no" }
|
||||
- { option: IgnoreRhosts, value: "yes" }
|
||||
- { option: PasswordAuthentication, value: "no" }
|
||||
- { option: PermitEmptyPasswords, value: "no" }
|
||||
- { option: KerberosAuthentication, value: "no" }
|
||||
- { option: GSSAPIAuthentication, value: "no" }
|
||||
- { option: AllowAgentForwarding, value: "no" }
|
||||
- { option: AllowTcpForwarding, value: "no" }
|
||||
- { option: ChallengeResponseAuthentication, value: "no" }
|
||||
- { option: GatewayPorts, value: "no" }
|
||||
- { option: X11Forwarding, value: "no" }
|
||||
- { option: PermitUserEnvironment, value: "no" }
|
||||
- { option: ClientAliveInterval, value: "300" }
|
||||
- { option: ClientAliveCountMax, value: "1" }
|
||||
- { option: PermitTunnel, value: "no" }
|
||||
- { option: Banner, value: /etc/issue.net }
|
||||
|
||||
- name: Append CIS specific configurations to sshd_config
|
||||
ansible.builtin.blockinfile:
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
---
|
||||
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_image_dir, hostname ~ '-cloudinit.iso'] | ansible.builtin.path_join }}
|
||||
|
||||
@@ -102,3 +102,5 @@
|
||||
delegate_to: "{{ inventory_hostname }}"
|
||||
ansible.builtin.wait_for_connection:
|
||||
timeout: 300
|
||||
failed_when: false
|
||||
changed_when: false
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
api_user: "{{ hypervisor_username }}"
|
||||
api_password: "{{ hypervisor_password }}"
|
||||
name: "{{ hostname }}"
|
||||
vmid: "{{ vm_id }}"
|
||||
vmid: "{{ system_cfg.id }}"
|
||||
disk: "{{ item }}"
|
||||
state: absent
|
||||
loop:
|
||||
@@ -23,5 +23,5 @@
|
||||
api_user: "{{ hypervisor_username }}"
|
||||
api_password: "{{ hypervisor_password }}"
|
||||
node: "{{ hypervisor_node }}"
|
||||
vmid: "{{ vm_id }}"
|
||||
vmid: "{{ system_cfg.id }}"
|
||||
state: restarted
|
||||
|
||||
@@ -13,3 +13,196 @@
|
||||
|
||||
- name: Cleanup libvirt resources
|
||||
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 (
|
||||
install_type == 'physical'
|
||||
and (ansible_host | default('') | string | length) > 0
|
||||
)
|
||||
)
|
||||
) | bool
|
||||
}}
|
||||
changed_when: false
|
||||
|
||||
- name: Check VM accessibility after reboot
|
||||
when:
|
||||
- install_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 == "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 == "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 == "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 == "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 == "proxmox"
|
||||
- virtualization_vm_created_in_run | default(false) | bool
|
||||
delegate_to: localhost
|
||||
become: false
|
||||
community.proxmox.proxmox_kvm:
|
||||
api_host: "{{ hypervisor_url }}"
|
||||
api_user: "{{ hypervisor_username }}"
|
||||
api_password: "{{ hypervisor_password }}"
|
||||
node: "{{ hypervisor_node }}"
|
||||
name: "{{ hostname }}"
|
||||
vmid: "{{ system_cfg.id }}"
|
||||
state: stopped
|
||||
|
||||
- name: Delete VM for proxmox
|
||||
when:
|
||||
- hypervisor == "proxmox"
|
||||
- virtualization_vm_created_in_run | default(false) | bool
|
||||
delegate_to: localhost
|
||||
become: false
|
||||
community.proxmox.proxmox_kvm:
|
||||
api_host: "{{ hypervisor_url }}"
|
||||
api_user: "{{ hypervisor_username }}"
|
||||
api_password: "{{ hypervisor_password }}"
|
||||
node: "{{ hypervisor_node }}"
|
||||
name: "{{ hostname }}"
|
||||
vmid: "{{ system_cfg.id }}"
|
||||
state: absent
|
||||
unprivileged: false
|
||||
|
||||
- name: Remove VM for VMware
|
||||
when:
|
||||
- hypervisor == "vmware"
|
||||
- virtualization_vm_created_in_run | default(false) | bool
|
||||
delegate_to: localhost
|
||||
become: false
|
||||
community.vmware.vmware_guest:
|
||||
hostname: "{{ hypervisor_url }}"
|
||||
username: "{{ hypervisor_username }}"
|
||||
password: "{{ hypervisor_password }}"
|
||||
validate_certs: "{{ hypervisor_validate_certs }}"
|
||||
name: "{{ hostname }}"
|
||||
folder: "{{ system_cfg.path | default('/') }}"
|
||||
state: poweredoff
|
||||
|
||||
- name: Delete VM for VMware
|
||||
when:
|
||||
- hypervisor == "vmware"
|
||||
- virtualization_vm_created_in_run | default(false) | bool
|
||||
delegate_to: localhost
|
||||
become: false
|
||||
community.vmware.vmware_guest:
|
||||
hostname: "{{ hypervisor_url }}"
|
||||
username: "{{ hypervisor_username }}"
|
||||
password: "{{ hypervisor_password }}"
|
||||
validate_certs: "{{ hypervisor_validate_certs }}"
|
||||
name: "{{ hostname }}"
|
||||
folder: "{{ system_cfg.path | default('/') }}"
|
||||
state: absent
|
||||
|
||||
- name: Destroy Xen VM if running
|
||||
when:
|
||||
- hypervisor == "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 == "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 == "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.
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
hostname: "{{ hypervisor_url }}"
|
||||
username: "{{ hypervisor_username }}"
|
||||
password: "{{ hypervisor_password }}"
|
||||
validate_certs: false
|
||||
validate_certs: "{{ hypervisor_validate_certs }}"
|
||||
datacenter: "{{ hypervisor_datacenter }}"
|
||||
name: "{{ hostname }}"
|
||||
cdrom:
|
||||
@@ -34,7 +34,7 @@
|
||||
hostname: "{{ hypervisor_url }}"
|
||||
username: "{{ hypervisor_username }}"
|
||||
password: "{{ hypervisor_password }}"
|
||||
validate_certs: false
|
||||
validate_certs: "{{ hypervisor_validate_certs }}"
|
||||
datacenter: "{{ hypervisor_datacenter }}"
|
||||
name: "{{ hostname }}"
|
||||
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 == "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: "{{ motd_enabled | bool }}"
|
||||
configuration_sudo_banner_enabled: "{{ sudo_banner_enabled | bool }}"
|
||||
configuration_firewall_enabled: "{{ firewall_enabled | bool }}"
|
||||
configuration_luks_enabled: "{{ luks_enabled | bool }}"
|
||||
56
roles/configuration/tasks/banner.yml
Normal file
56
roles/configuration/tasks/banner.yml
Normal file
@@ -0,0 +1,56 @@
|
||||
---
|
||||
- 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: >-
|
||||
{{ "ubuntu" if os | lower in ["ubuntu", "ubuntu-lts"] else os }}
|
||||
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: >-
|
||||
/usr/sbin/efibootmgr -c -L '{{ os }}' -d "{{ install_drive }}" -p 1
|
||||
-l '\efi\EFI\{{ configuration_efi_vendor }}\shimx64.efi'
|
||||
@@ -18,7 +18,7 @@
|
||||
--bootloader-id={{ configuration_bootloader_id }}
|
||||
configuration_bootloader_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
|
||||
changed_when: configuration_bootloader_result.rc == 0
|
||||
|
||||
@@ -27,10 +27,11 @@
|
||||
ansible.builtin.lineinfile:
|
||||
path: /mnt/etc/mkinitcpio.conf
|
||||
regexp: "^(HOOKS=.*block)(?!.*lvm2)(.*)"
|
||||
line: '\1 lvm2\2'
|
||||
line: "\\1 lvm2\\2"
|
||||
backrefs: true
|
||||
|
||||
- name: Regenerate initramfs
|
||||
when: os | lower not in ["alpine", "void"]
|
||||
vars:
|
||||
configuration_initramfs_cmd: >-
|
||||
{{
|
||||
@@ -43,14 +44,14 @@
|
||||
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
|
||||
changed_when: configuration_initramfs_result.rc == 0
|
||||
|
||||
- name: Generate grub config
|
||||
vars:
|
||||
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: >-
|
||||
{{
|
||||
'/usr/sbin/grub2-mkconfig -o '
|
||||
@@ -59,6 +60,6 @@
|
||||
if is_rhel | bool
|
||||
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
|
||||
changed_when: configuration_grub_result.rc == 0
|
||||
|
||||
@@ -141,8 +141,8 @@
|
||||
- configuration_luks_keyfile_in_use
|
||||
ansible.builtin.lineinfile:
|
||||
path: /mnt/etc/cryptsetup-initramfs/conf-hook
|
||||
regexp: '^KEYFILE_PATTERN='
|
||||
line: 'KEYFILE_PATTERN=/etc/cryptsetup-keys.d/*.key'
|
||||
regexp: "^KEYFILE_PATTERN="
|
||||
line: "KEYFILE_PATTERN=/etc/cryptsetup-keys.d/*.key"
|
||||
create: true
|
||||
mode: "0644"
|
||||
|
||||
@@ -150,7 +150,7 @@
|
||||
when: os | lower == 'archlinux'
|
||||
ansible.builtin.lineinfile:
|
||||
path: /mnt/etc/mkinitcpio.conf
|
||||
regexp: '^HOOKS='
|
||||
regexp: "^HOOKS="
|
||||
line: >-
|
||||
HOOKS=(base systemd autodetect microcode modconf kms keyboard sd-vconsole
|
||||
block sd-encrypt lvm2 filesystems fsck)
|
||||
@@ -194,7 +194,7 @@
|
||||
when: os | lower == 'archlinux'
|
||||
ansible.builtin.lineinfile:
|
||||
path: /mnt/etc/mkinitcpio.conf
|
||||
regexp: '^FILES='
|
||||
regexp: "^FILES="
|
||||
line: >-
|
||||
FILES=({{
|
||||
configuration_mkinitcpio_files_list_new | join(' ')
|
||||
@@ -271,7 +271,7 @@
|
||||
- configuration_kernel_bls_entries.files | length > 0
|
||||
ansible.builtin.lineinfile:
|
||||
path: "{{ item.path }}"
|
||||
regexp: '^options '
|
||||
regexp: "^options "
|
||||
line: "options {{ configuration_kernel_cmdline_new }}"
|
||||
loop: "{{ configuration_kernel_bls_entries.files }}"
|
||||
loop_control:
|
||||
@@ -351,5 +351,5 @@
|
||||
when: not is_rhel | bool
|
||||
ansible.builtin.lineinfile:
|
||||
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 }}"'
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
+ [configuration_luks_device]
|
||||
}}
|
||||
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 }}"
|
||||
register: configuration_luks_tpm2_enroll_chroot
|
||||
changed_when: configuration_luks_tpm2_enroll_chroot.rc == 0
|
||||
|
||||
@@ -27,7 +27,8 @@
|
||||
|
||||
- name: Create zram config
|
||||
when:
|
||||
- os | lower not in ['debian11', 'rhel8']
|
||||
- (os != "debian" or (os_version | string) != "11") and os != "rhel"
|
||||
- os | lower not in ["alpine", "void"]
|
||||
- swap_enabled | bool
|
||||
ansible.builtin.copy:
|
||||
dest: /mnt/etc/systemd/zram-generator.conf
|
||||
@@ -62,7 +63,7 @@
|
||||
- /mnt/etc/issue.net
|
||||
|
||||
- name: Remove motd files
|
||||
when: os | lower in ["rhel8", "rhel9", "rhel10"]
|
||||
when: os == "rhel"
|
||||
ansible.builtin.file:
|
||||
path: "{{ item }}"
|
||||
state: absent
|
||||
|
||||
@@ -17,14 +17,14 @@
|
||||
mode: "0644"
|
||||
|
||||
- name: Remove deprecated attr2 and disable large extent
|
||||
when: os | lower in ["almalinux", "rhel8", "rhel9", "rhel10", "rocky"] and filesystem == "xfs"
|
||||
when: os in ["almalinux", "rocky", "rhel"] and filesystem == "xfs"
|
||||
ansible.builtin.replace:
|
||||
path: /mnt/etc/fstab
|
||||
regexp: "(xfs.*?)(attr2)"
|
||||
replace: '\1allocsize=64m'
|
||||
replace: "\\1allocsize=64m"
|
||||
|
||||
- name: Replace ISO UUID entry with /dev/sr0 in fstab
|
||||
when: os in ["rhel8", "rhel9", "rhel10"]
|
||||
when: os == "rhel"
|
||||
vars:
|
||||
configuration_fstab_dvd_line: >-
|
||||
{{
|
||||
@@ -34,12 +34,12 @@
|
||||
}}
|
||||
ansible.builtin.lineinfile:
|
||||
path: /mnt/etc/fstab
|
||||
regexp: '^.*\/dvd.*$'
|
||||
regexp: "^.*\\/dvd.*$"
|
||||
line: "{{ configuration_fstab_dvd_line }}"
|
||||
state: present
|
||||
|
||||
- name: Write image from RHEL ISO to the target machine
|
||||
when: os in ["rhel8", "rhel9", "rhel10"] and hypervisor == 'vmware'
|
||||
when: os == "rhel" and hypervisor == 'vmware'
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- dd
|
||||
@@ -57,9 +57,9 @@
|
||||
line: "{{ fstab_entry.line }}"
|
||||
insertafter: EOF
|
||||
loop:
|
||||
- {regexp: '^# TempFS$', line: '# TempFS'}
|
||||
- {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+/dev/shm\\s+', line: 'tmpfs /dev/shm tmpfs defaults,nosuid,nodev,noexec 0 0'}
|
||||
- { regexp: "^# TempFS$", line: "# TempFS" }
|
||||
- { 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+/dev/shm\\\\s+", line: "tmpfs /dev/shm tmpfs defaults,nosuid,nodev,noexec 0 0" }
|
||||
loop_control:
|
||||
loop_var: fstab_entry
|
||||
|
||||
@@ -106,7 +106,7 @@
|
||||
when: configuration_grub_bls_entries.files | length > 0
|
||||
ansible.builtin.lineinfile:
|
||||
path: "{{ item.path }}"
|
||||
regexp: '^options '
|
||||
regexp: "^options "
|
||||
line: "options {{ configuration_kernel_cmdline_base }}"
|
||||
loop: "{{ configuration_grub_bls_entries.files }}"
|
||||
loop_control:
|
||||
@@ -116,5 +116,5 @@
|
||||
when: partitioning_grub_enable_cryptodisk | bool
|
||||
ansible.builtin.lineinfile:
|
||||
path: /mnt/etc/default/grub
|
||||
regexp: '^GRUB_ENABLE_CRYPTODISK='
|
||||
regexp: "^GRUB_ENABLE_CRYPTODISK="
|
||||
line: GRUB_ENABLE_CRYPTODISK=y
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
---
|
||||
- name: Reload systemd in installer environment
|
||||
when: ansible_service_mgr == 'systemd'
|
||||
ansible.builtin.systemd:
|
||||
daemon_reload: true
|
||||
|
||||
@@ -19,14 +20,15 @@
|
||||
regexp: "{{ item.regex }}"
|
||||
line: "{{ item.line }}"
|
||||
loop:
|
||||
- {regex: en_US\.UTF-8 UTF-8, line: en_US.UTF-8 UTF-8}
|
||||
- { regex: en_US\.UTF-8 UTF-8, line: en_US.UTF-8 UTF-8 }
|
||||
|
||||
- name: Generate locales
|
||||
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
|
||||
changed_when: configuration_locale_result.rc == 0
|
||||
|
||||
|
||||
- name: Set hostname
|
||||
vars:
|
||||
configuration_hostname_fqdn: >-
|
||||
@@ -34,8 +36,8 @@
|
||||
hostname
|
||||
if '.' in hostname
|
||||
else (
|
||||
hostname + '.' + vm_dns_search
|
||||
if vm_dns_search is defined and vm_dns_search | length
|
||||
hostname + '.' + system_cfg.dns_search
|
||||
if system_cfg.dns_search is defined and system_cfg.dns_search | length
|
||||
else hostname
|
||||
)
|
||||
}}
|
||||
@@ -51,16 +53,22 @@
|
||||
hostname
|
||||
if '.' in hostname
|
||||
else (
|
||||
hostname + '.' + vm_dns_search
|
||||
if vm_dns_search is defined and vm_dns_search | length
|
||||
hostname + '.' + system_cfg.dns_search
|
||||
if system_cfg.dns_search is defined and system_cfg.dns_search | length
|
||||
else hostname
|
||||
)
|
||||
}}
|
||||
configuration_hostname_short: "{{ hostname.split('.')[0] }}"
|
||||
configuration_hostname_entries: >-
|
||||
{{ [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: >-
|
||||
{{ (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:
|
||||
path: /mnt/etc/hosts
|
||||
line: "{{ configuration_hosts_line }}"
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
- name: Include configuration tasks
|
||||
ansible.builtin.include_tasks: "{{ configuration_task }}"
|
||||
loop:
|
||||
- banner.yml
|
||||
- fstab.yml
|
||||
- locales.yml
|
||||
- services.yml
|
||||
|
||||
@@ -82,15 +82,100 @@
|
||||
- configuration_net_mac | length > 0
|
||||
fail_msg: Failed to detect the MAC address for network interface {{ configuration_net_inf }}.
|
||||
|
||||
- name: Copy NetworkManager keyfile
|
||||
ansible.builtin.template:
|
||||
src: network.j2
|
||||
dest: /mnt/etc/NetworkManager/system-connections/LAN.nmconnection
|
||||
mode: "0600"
|
||||
- name: Configure NetworkManager profile
|
||||
when: os | lower not in ["alpine", "void"]
|
||||
block:
|
||||
- name: Copy NetworkManager keyfile
|
||||
ansible.builtin.template:
|
||||
src: network.j2
|
||||
dest: /mnt/etc/NetworkManager/system-connections/LAN.nmconnection
|
||||
mode: "0600"
|
||||
|
||||
- name: Fix Ubuntu unmanaged devices
|
||||
when: os | lower in ["ubuntu", "ubuntu-lts"]
|
||||
ansible.builtin.file:
|
||||
path: /mnt/etc/NetworkManager/conf.d/10-globally-managed-devices.conf
|
||||
state: touch
|
||||
mode: "0644"
|
||||
- name: Fix Ubuntu unmanaged devices
|
||||
when: os | lower in ["ubuntu", "ubuntu-lts"]
|
||||
ansible.builtin.file:
|
||||
path: /mnt/etc/NetworkManager/conf.d/10-globally-managed-devices.conf
|
||||
state: touch
|
||||
mode: "0644"
|
||||
|
||||
- name: Configure Alpine networking
|
||||
when: os | lower == "alpine"
|
||||
vars:
|
||||
configuration_dns_value: "{{ system_cfg.dns_servers if system_cfg.dns_servers is defined else '' }}"
|
||||
configuration_dns_list_raw: >-
|
||||
{{
|
||||
configuration_dns_value
|
||||
if configuration_dns_value is iterable and configuration_dns_value is not string
|
||||
else configuration_dns_value.split(',')
|
||||
}}
|
||||
configuration_dns_list: >-
|
||||
{{ configuration_dns_list_raw | map('trim') | reject('equalto', '') | list }}
|
||||
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_value: "{{ system_cfg.dns_servers if system_cfg.dns_servers is defined else '' }}"
|
||||
configuration_dns_list_raw: >-
|
||||
{{
|
||||
configuration_dns_value
|
||||
if configuration_dns_value is iterable and configuration_dns_value is not string
|
||||
else configuration_dns_value.split(',')
|
||||
}}
|
||||
configuration_dns_list: >-
|
||||
{{ configuration_dns_list_raw | map('trim') | reject('equalto', '') | list }}
|
||||
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,9 +3,9 @@
|
||||
when: is_rhel | bool
|
||||
block:
|
||||
- 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 selinux | bool
|
||||
ansible.builtin.command: >
|
||||
{{ chroot_command }} /mnt /sbin/setfiles -v -F
|
||||
{{ chroot_command }} /sbin/setfiles -v -F
|
||||
-e /dev -e /proc -e /sys -e /run
|
||||
/etc/selinux/targeted/contexts/files/file_contexts /
|
||||
register: configuration_setfiles_result
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
---
|
||||
- name: Enable Systemd Services
|
||||
when: os | lower not in ['alpine', 'void']
|
||||
ansible.builtin.command: >
|
||||
{{ chroot_command }} /mnt systemctl enable NetworkManager
|
||||
{{ ' firewalld' if firewalld_enabled | bool else '' }}
|
||||
{{ chroot_command }} systemctl enable NetworkManager
|
||||
{{ ' firewalld' if firewall_backend == 'firewalld' and firewall_enabled | bool else '' }}
|
||||
{{ ' ufw' if firewall_backend == 'ufw' and firewall_enabled | bool else '' }}
|
||||
{{
|
||||
(' ssh' if os | lower in ['ubuntu', 'ubuntu-lts'] else
|
||||
(' sshd' if os | lower not in ['debian11', 'debian12', 'debian13'] else ''))
|
||||
(' ssh' if is_debian | bool else ' sshd')
|
||||
if ssh_enabled | bool else ''
|
||||
}}
|
||||
{{
|
||||
@@ -14,3 +15,65 @@
|
||||
}}
|
||||
register: configuration_enable_services_result
|
||||
changed_when: configuration_enable_services_result.rc == 0
|
||||
|
||||
- name: Enable OpenRC services
|
||||
when: os | lower == 'alpine'
|
||||
vars:
|
||||
configuration_openrc_services: >-
|
||||
{{
|
||||
['networking']
|
||||
+ (['sshd'] if ssh_enabled | bool else [])
|
||||
+ ([firewall_backend] if 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 ssh_enabled | bool else [])
|
||||
+ ([firewall_backend] if 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,11 +4,11 @@
|
||||
configuration_user_group: >-
|
||||
{{ "sudo" if is_debian | bool else "wheel" }}
|
||||
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 }}
|
||||
--password {{ user_password | password_hash('sha512') }} --shell /bin/bash
|
||||
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
|
||||
ansible.builtin.command: "{{ item }}"
|
||||
loop:
|
||||
|
||||
@@ -4,14 +4,14 @@ uuid={{ configuration_net_uuid }}
|
||||
type=ethernet
|
||||
|
||||
[ipv4]
|
||||
{% set dns_value = vm_dns if vm_dns is defined else '' %}
|
||||
{% set dns_value = system_cfg.dns_servers if system_cfg.dns_servers is defined else '' %}
|
||||
{% set dns_list_raw = dns_value if dns_value is iterable and dns_value is not string else dns_value.split(',') %}
|
||||
{% 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_value = system_cfg.dns_search if system_cfg.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 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 '' }}
|
||||
{% if system_cfg.ip is defined and system_cfg.ip | string | length %}
|
||||
address1={{ system_cfg.ip }}/{{ system_cfg.prefix }}{{ (',' ~ system_cfg.gateway) if (system_cfg.gateway is defined and system_cfg.gateway | string | length) else '' }}
|
||||
method=manual
|
||||
{% else %}
|
||||
method=auto
|
||||
|
||||
@@ -10,15 +10,73 @@
|
||||
- name: Gather facts
|
||||
ansible.builtin.setup:
|
||||
|
||||
- name: Check if host is booted from the Arch install media
|
||||
- name: Check for live environment markers
|
||||
ansible.builtin.stat:
|
||||
path: /run/archiso
|
||||
register: environment_archiso_stat
|
||||
path: "{{ item }}"
|
||||
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
|
||||
when:
|
||||
- not (custom_iso | bool)
|
||||
- not environment_archiso_stat.stat.exists
|
||||
- not environment_archiso_present | bool
|
||||
ansible.builtin.fail:
|
||||
msg: This host is not booted from the Arch install media!
|
||||
|
||||
@@ -40,9 +98,9 @@
|
||||
- name: Set IP-Address
|
||||
when:
|
||||
- hypervisor == "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: >-
|
||||
ip addr replace {{ vm_ip }}/{{ vm_nms }}
|
||||
ip addr replace {{ system_cfg.ip }}/{{ system_cfg.prefix }}
|
||||
dev {{ environment_interface_name }}
|
||||
register: environment_ip_result
|
||||
changed_when: environment_ip_result.rc == 0
|
||||
@@ -50,9 +108,9 @@
|
||||
- name: Set Default Gateway
|
||||
when:
|
||||
- hypervisor == "vmware"
|
||||
- vm_gw is defined and vm_gw | length > 0
|
||||
- vm_ip is defined and vm_ip | length > 0
|
||||
ansible.builtin.command: "ip route replace default via {{ vm_gw }}"
|
||||
- system_cfg.gateway is defined and system_cfg.gateway | string | length > 0
|
||||
- system_cfg.ip is defined and system_cfg.ip | string | length > 0
|
||||
ansible.builtin.command: "ip route replace default via {{ system_cfg.gateway }}"
|
||||
register: environment_gateway_result
|
||||
changed_when: environment_gateway_result.rc == 0
|
||||
|
||||
@@ -105,23 +163,23 @@
|
||||
- name: Setup Pacman
|
||||
when:
|
||||
- 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:
|
||||
update_cache: true
|
||||
force: true
|
||||
name: "{{ item.name }}"
|
||||
state: latest
|
||||
loop:
|
||||
- {name: glibc}
|
||||
- {name: dnf, os: [almalinux, fedora, rhel8, rhel9, rhel10, rocky]}
|
||||
- {name: debootstrap, os: [debian11, debian12, debian13, ubuntu, ubuntu-lts]}
|
||||
- {name: debian-archive-keyring, os: [debian11, debian12, debian13]}
|
||||
- {name: ubuntu-keyring, os: [ubuntu, ubuntu-lts]}
|
||||
- { name: glibc }
|
||||
- { name: dnf, os: [almalinux8, almalinux9, almalinux10, fedora40, fedora41, fedora42, fedora43, rhel8, rhel9, rhel10, rocky8, rocky9, rocky10] }
|
||||
- { name: debootstrap, os: [debian10, debian11, debian12, debian13, debianunstable, ubuntu, ubuntu-lts] }
|
||||
- { name: debian-archive-keyring, os: [debian10, debian11, debian12, debian13, debianunstable] }
|
||||
- { name: ubuntu-keyring, os: [ubuntu, ubuntu-lts] }
|
||||
retries: 4
|
||||
delay: 15
|
||||
|
||||
- name: Prepare /iso mount and repository for RHEL-based systems
|
||||
when: os | lower in ["rhel8", "rhel9", "rhel10"]
|
||||
when: os == "rhel"
|
||||
block:
|
||||
- name: Create /iso directory
|
||||
ansible.builtin.file:
|
||||
@@ -129,9 +187,19 @@
|
||||
state: directory
|
||||
mode: "0755"
|
||||
|
||||
- name: Select RHEL ISO device
|
||||
ansible.builtin.set_fact:
|
||||
environment_rhel_iso_device: >-
|
||||
{{
|
||||
'/dev/sr2'
|
||||
if hypervisor == 'libvirt'
|
||||
else '/dev/sr1'
|
||||
}}
|
||||
changed_when: false
|
||||
|
||||
- name: Mount RHEL ISO
|
||||
ansible.posix.mount:
|
||||
src: "{{ '/dev/sr1' if hypervisor == 'vmware' else '/dev/sr2' }}"
|
||||
src: "{{ environment_rhel_iso_device }}"
|
||||
path: /usr/local/install/redhat/dvd
|
||||
fstype: iso9660
|
||||
opts: "ro,loop"
|
||||
@@ -140,6 +208,16 @@
|
||||
- name: Configure RHEL Repos for installation
|
||||
when: is_rhel | bool
|
||||
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
|
||||
ansible.builtin.file:
|
||||
path: /etc/yum.repos.d
|
||||
@@ -148,8 +226,8 @@
|
||||
|
||||
- name: Create RHEL repository file
|
||||
ansible.builtin.template:
|
||||
src: "{{ os | lower }}.repo.j2"
|
||||
dest: /etc/yum.repos.d/{{ os | lower }}.repo
|
||||
src: "{{ environment_repo_template }}.repo.j2"
|
||||
dest: /etc/yum.repos.d/{{ environment_repo_template }}.repo
|
||||
mode: "0644"
|
||||
|
||||
- name: Check for third-party preparation tasks
|
||||
|
||||
@@ -1,18 +1,49 @@
|
||||
---
|
||||
hypervisor: "none"
|
||||
hypervisor_defaults:
|
||||
type: "none"
|
||||
url: ""
|
||||
username: ""
|
||||
password: ""
|
||||
node: ""
|
||||
storage: ""
|
||||
datacenter: ""
|
||||
cluster: ""
|
||||
validate_certs: false
|
||||
custom_iso: false
|
||||
cis: false
|
||||
selinux: true
|
||||
vmware_ssh: false
|
||||
firewalld_enabled: true
|
||||
firewall_enabled: true
|
||||
firewall_backend: "firewalld"
|
||||
firewall_toolkit: "nftables"
|
||||
ssh_enabled: true
|
||||
zstd_enabled: true
|
||||
swap_enabled: true
|
||||
chroot_command: "arch-chroot"
|
||||
chroot_tool: "arch-chroot"
|
||||
os_version: ""
|
||||
motd_enabled: true
|
||||
sudo_banner_enabled: true
|
||||
thirdparty_preparation_tasks_path: "dropins/preparation.yml"
|
||||
|
||||
cis_enabled: "{{ cis | bool }}"
|
||||
|
||||
system_defaults:
|
||||
name: ""
|
||||
id: ""
|
||||
cpus: 0
|
||||
memory_mb: 0
|
||||
balloon_mb: 0
|
||||
network: ""
|
||||
vlan: ""
|
||||
ip: ""
|
||||
prefix: ""
|
||||
gateway: ""
|
||||
dns_servers: []
|
||||
dns_search: []
|
||||
path: ""
|
||||
disks: []
|
||||
|
||||
luks_enabled: false
|
||||
luks_mapper_name: "SYSTEM_DECRYPTED"
|
||||
luks_auto_decrypt: true
|
||||
|
||||
42
roles/global_defaults/tasks/hypervisor.yml
Normal file
42
roles/global_defaults/tasks/hypervisor.yml
Normal file
@@ -0,0 +1,42 @@
|
||||
---
|
||||
- name: Validate hypervisor dict input
|
||||
when: hypervisor is mapping
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- hypervisor.type is defined
|
||||
- hypervisor.type | string | length > 0
|
||||
fail_msg: "hypervisor.type is required when hypervisor is a dictionary"
|
||||
quiet: true
|
||||
|
||||
- name: Normalize hypervisor configuration
|
||||
vars:
|
||||
hypervisor_input: "{{ hypervisor if hypervisor is mapping else {} }}"
|
||||
hypervisor_type_legacy: "{{ (hypervisor | default('none')) if hypervisor is string else '' }}"
|
||||
hypervisor_legacy_cfg:
|
||||
type: "{{ hypervisor_type_legacy }}"
|
||||
url: "{{ hypervisor_url | default('') }}"
|
||||
username: "{{ hypervisor_username | default('') }}"
|
||||
password: "{{ hypervisor_password | default('') }}"
|
||||
node: "{{ hypervisor_node | default('') }}"
|
||||
storage: "{{ hypervisor_storage | default('') }}"
|
||||
datacenter: "{{ hypervisor_datacenter | default('') }}"
|
||||
cluster: "{{ hypervisor_cluster | default('') }}"
|
||||
validate_certs: "{{ hypervisor_validate_certs | default(false) | bool }}"
|
||||
hypervisor_cfg_effective: >-
|
||||
{{
|
||||
hypervisor_defaults
|
||||
| combine(hypervisor_legacy_cfg, recursive=True)
|
||||
| combine(hypervisor_input, recursive=True)
|
||||
}}
|
||||
ansible.builtin.set_fact:
|
||||
hypervisor_cfg: "{{ hypervisor_cfg_effective }}"
|
||||
hypervisor: "{{ hypervisor_cfg_effective.type | string | lower }}"
|
||||
hypervisor_url: "{{ hypervisor_cfg_effective.url }}"
|
||||
hypervisor_username: "{{ hypervisor_cfg_effective.username }}"
|
||||
hypervisor_password: "{{ hypervisor_cfg_effective.password }}"
|
||||
hypervisor_node: "{{ hypervisor_cfg_effective.node }}"
|
||||
hypervisor_storage: "{{ hypervisor_cfg_effective.storage }}"
|
||||
hypervisor_datacenter: "{{ hypervisor_cfg_effective.datacenter }}"
|
||||
hypervisor_cluster: "{{ hypervisor_cfg_effective.cluster }}"
|
||||
hypervisor_validate_certs: "{{ hypervisor_cfg_effective.validate_certs | bool }}"
|
||||
changed_when: false
|
||||
@@ -4,96 +4,59 @@
|
||||
msg: Global defaults loaded.
|
||||
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
|
||||
ansible.builtin.assert:
|
||||
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.
|
||||
ansible.builtin.include_tasks: validation.yml
|
||||
|
||||
- name: Set OS family flags
|
||||
ansible.builtin.set_fact:
|
||||
is_rhel: "{{ os | lower in ['almalinux', 'fedora', 'rhel8', 'rhel9', 'rhel10', 'rocky'] }}"
|
||||
is_debian: "{{ os | lower in ['debian11', 'debian12', 'debian13', 'ubuntu', 'ubuntu-lts'] }}"
|
||||
is_rhel: "{{ os | lower in ['almalinux', 'fedora', 'rhel', 'rocky'] }}"
|
||||
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 chroot_tool == 'systemd-nspawn'
|
||||
else chroot_tool ~ ' /mnt'
|
||||
}}
|
||||
changed_when: false
|
||||
|
||||
- name: Set Python interpreter for RHEL-based installers
|
||||
when:
|
||||
- ansible_python_interpreter is not defined
|
||||
- os | lower in ["almalinux", "rhel8", "rhel9", "rhel10", "rocky"]
|
||||
- is_rhel | bool
|
||||
ansible.builtin.set_fact:
|
||||
ansible_python_interpreter: /usr/bin/python3
|
||||
changed_when: false
|
||||
@@ -107,8 +70,10 @@
|
||||
ansible_password: "{{ user_password }}"
|
||||
ansible_become_password: "{{ user_password }}"
|
||||
ansible_ssh_extra_args: "-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no"
|
||||
changed_when: false
|
||||
|
||||
- name: Set connection for VMware
|
||||
when: hypervisor == "vmware"
|
||||
ansible.builtin.set_fact:
|
||||
ansible_connection: vmware_tools
|
||||
changed_when: false
|
||||
|
||||
291
roles/global_defaults/tasks/system.yml
Normal file
291
roles/global_defaults/tasks/system.yml
Normal file
@@ -0,0 +1,291 @@
|
||||
---
|
||||
- name: Ensure system input is a dictionary
|
||||
ansible.builtin.set_fact:
|
||||
system: "{{ system | default({}) }}"
|
||||
changed_when: false
|
||||
|
||||
- name: Validate system input type
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- system is mapping
|
||||
fail_msg: "system must be a dictionary"
|
||||
quiet: true
|
||||
|
||||
- name: Normalize base system fields
|
||||
vars:
|
||||
system_name_effective: >-
|
||||
{{
|
||||
system.name
|
||||
if system.name is defined and (system.name | string | length) > 0
|
||||
else (
|
||||
hostname
|
||||
if hostname is defined and (hostname | string | length) > 0
|
||||
else inventory_hostname
|
||||
)
|
||||
}}
|
||||
system_id_effective: >-
|
||||
{{
|
||||
system.id
|
||||
if system.id is defined and (system.id | string | length) > 0
|
||||
else (vm_id | default(''))
|
||||
}}
|
||||
system_cpus_effective: >-
|
||||
{{
|
||||
system.cpus
|
||||
if system.cpus is defined and (system.cpus | int) > 0
|
||||
else (vm_cpus | default(0))
|
||||
}}
|
||||
system_memory_mb_effective: >-
|
||||
{{
|
||||
system.memory_mb
|
||||
if system.memory_mb is defined and (system.memory_mb | int) > 0
|
||||
else (vm_memory | default(0))
|
||||
}}
|
||||
system_balloon_mb_effective: >-
|
||||
{{
|
||||
system.balloon_mb
|
||||
if system.balloon_mb is defined and (system.balloon_mb | int) > 0
|
||||
else (vm_ballo | default(''))
|
||||
}}
|
||||
system_network_effective: >-
|
||||
{{
|
||||
system.network
|
||||
if system.network is defined and (system.network | string | length) > 0
|
||||
else (vm_nif | default(''))
|
||||
}}
|
||||
system_vlan_effective: >-
|
||||
{{
|
||||
system.vlan
|
||||
if system.vlan is defined and (system.vlan | string | length) > 0
|
||||
else (vlan_name | default(''))
|
||||
}}
|
||||
system_ip_effective: >-
|
||||
{{
|
||||
system.ip
|
||||
if system.ip is defined and (system.ip | string | length) > 0
|
||||
else (vm_ip | default(''))
|
||||
}}
|
||||
system_prefix_effective: >-
|
||||
{{
|
||||
system.prefix
|
||||
if system.prefix is defined and (system.prefix | int) > 0
|
||||
else (vm_nms | default(''))
|
||||
}}
|
||||
system_gateway_effective: >-
|
||||
{{
|
||||
system.gateway
|
||||
if system.gateway is defined and (system.gateway | string | length) > 0
|
||||
else (vm_gw | default(''))
|
||||
}}
|
||||
system_dns_servers_effective: >-
|
||||
{{
|
||||
system.dns_servers
|
||||
if system.dns_servers is defined
|
||||
else (vm_dns | default([]))
|
||||
}}
|
||||
system_dns_search_effective: >-
|
||||
{{
|
||||
system.dns_search
|
||||
if system.dns_search is defined
|
||||
else (vm_dns_search | default([]))
|
||||
}}
|
||||
system_path_effective: >-
|
||||
{{
|
||||
system.path
|
||||
if system.path is defined and (system.path | string | length) > 0
|
||||
else (
|
||||
system.hypervisor_path
|
||||
if system.hypervisor_path is defined and (system.hypervisor_path | string | length) > 0
|
||||
else (vm_path | default(''))
|
||||
)
|
||||
}}
|
||||
ansible.builtin.set_fact:
|
||||
hostname: "{{ system_name_effective }}"
|
||||
system_cfg: >-
|
||||
{{
|
||||
system_defaults
|
||||
| combine(system, recursive=True)
|
||||
| combine(
|
||||
{
|
||||
'name': system_name_effective,
|
||||
'id': system_id_effective,
|
||||
'cpus': system_cpus_effective,
|
||||
'memory_mb': system_memory_mb_effective,
|
||||
'balloon_mb': system_balloon_mb_effective,
|
||||
'network': system_network_effective,
|
||||
'vlan': system_vlan_effective,
|
||||
'ip': system_ip_effective,
|
||||
'prefix': system_prefix_effective,
|
||||
'gateway': system_gateway_effective,
|
||||
'dns_servers': system_dns_servers_effective,
|
||||
'dns_search': system_dns_search_effective,
|
||||
'path': system_path_effective
|
||||
},
|
||||
recursive=True
|
||||
)
|
||||
}}
|
||||
changed_when: false
|
||||
|
||||
- name: Normalize system disks input
|
||||
vars:
|
||||
system_disk_defaults:
|
||||
size: 0
|
||||
device: ""
|
||||
mount: ""
|
||||
fstype: ""
|
||||
label: ""
|
||||
opts: "defaults"
|
||||
system_disks_raw: >-
|
||||
{{
|
||||
system_cfg.disks
|
||||
if system_cfg.disks is defined
|
||||
else []
|
||||
}}
|
||||
system_disks_legacy: >-
|
||||
{{
|
||||
[ {'size': vm_size} ]
|
||||
if (system_disks_raw | length) == 0 and (vm_size is defined and (vm_size | float) > 0)
|
||||
else []
|
||||
}}
|
||||
system_disks_effective: >-
|
||||
{{
|
||||
system_disks_raw
|
||||
if (system_disks_raw | length) > 0
|
||||
else system_disks_legacy
|
||||
}}
|
||||
system_disk_device_prefix: >-
|
||||
{{
|
||||
'/dev/vd'
|
||||
if (install_type | default('')) == 'virtual' and (hypervisor | default('')) == 'libvirt'
|
||||
else (
|
||||
'/dev/xvd'
|
||||
if (install_type | default('')) == 'virtual' and (hypervisor | default('')) == 'xen'
|
||||
else (
|
||||
'/dev/sd'
|
||||
if (install_type | default('')) == 'virtual'
|
||||
and (hypervisor | default('')) in ['proxmox', 'vmware']
|
||||
else ''
|
||||
)
|
||||
)
|
||||
}}
|
||||
system_disk_letter_map: "abcdefghijklmnopqrstuvwxyz"
|
||||
block:
|
||||
- name: Validate system disks type
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- system_disks_effective is sequence
|
||||
fail_msg: "system.disks must be a list"
|
||||
quiet: true
|
||||
|
||||
- name: Validate system disk items
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- item is mapping
|
||||
fail_msg: "Each system disk entry must be a dictionary"
|
||||
quiet: true
|
||||
loop: "{{ system_disks_effective }}"
|
||||
loop_control:
|
||||
label: "{{ item | to_json }}"
|
||||
|
||||
- name: Validate system disk count
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- (system_disks_effective | length) <= 26
|
||||
fail_msg: "system.disks supports at most 26 entries."
|
||||
quiet: true
|
||||
|
||||
- name: Build normalized system disk configuration
|
||||
ansible.builtin.set_fact:
|
||||
system_disks_cfg: "{{ system_disks_cfg | default([]) + [system_disk_cfg] }}"
|
||||
vars:
|
||||
disk_idx: "{{ ansible_loop.index0 }}"
|
||||
disk_letter: "{{ system_disk_letter_map[disk_idx] }}"
|
||||
disk_device_default: >-
|
||||
{{
|
||||
(
|
||||
install_drive
|
||||
if disk_idx == 0 and install_drive is defined and (install_drive | string | length) > 0
|
||||
else (system_disk_device_prefix ~ disk_letter)
|
||||
)
|
||||
if (install_type | default('')) == 'virtual'
|
||||
else (
|
||||
install_drive
|
||||
if disk_idx == 0 and install_drive is defined and (install_drive | string | length) > 0
|
||||
else ''
|
||||
)
|
||||
}}
|
||||
system_disk_cfg_base: "{{ system_disk_defaults | combine(item, recursive=True) }}"
|
||||
system_disk_cfg_tmp: >-
|
||||
{{
|
||||
system_disk_cfg_base
|
||||
| combine(
|
||||
{
|
||||
'device': (
|
||||
system_disk_cfg_base.device
|
||||
if system_disk_cfg_base.device | string | length > 0
|
||||
else disk_device_default
|
||||
),
|
||||
'fstype': (
|
||||
system_disk_cfg_base.fstype
|
||||
if system_disk_cfg_base.fstype | string | length > 0
|
||||
else (
|
||||
'ext4'
|
||||
if system_disk_cfg_base.mount | string | length > 0
|
||||
else ''
|
||||
)
|
||||
)
|
||||
},
|
||||
recursive=True
|
||||
)
|
||||
}}
|
||||
system_disk_partition_device: >-
|
||||
{{
|
||||
system_disk_cfg_tmp.device
|
||||
~ ('p1' if (system_disk_cfg_tmp.device | regex_search('\\d$')) else '1')
|
||||
}}
|
||||
system_disk_cfg: >-
|
||||
{{
|
||||
system_disk_cfg_tmp
|
||||
| combine(
|
||||
{
|
||||
'partition': system_disk_partition_device
|
||||
},
|
||||
recursive=True
|
||||
)
|
||||
}}
|
||||
loop: "{{ system_disks_effective }}"
|
||||
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 | default([])}, recursive=True) }}"
|
||||
changed_when: false
|
||||
|
||||
- name: Set install_drive from system disk definition (if needed)
|
||||
when:
|
||||
- (install_drive is not defined) or (install_drive | string | length) == 0
|
||||
- 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
|
||||
|
||||
- name: Set legacy vm_* aliases (compat)
|
||||
ansible.builtin.set_fact:
|
||||
vm_id: "{{ system_cfg.id }}"
|
||||
vm_cpus: "{{ system_cfg.cpus }}"
|
||||
vm_memory: "{{ system_cfg.memory_mb }}"
|
||||
vm_ballo: "{{ system_cfg.balloon_mb }}"
|
||||
vm_nif: "{{ system_cfg.network }}"
|
||||
vlan_name: "{{ system_cfg.vlan }}"
|
||||
vm_ip: "{{ system_cfg.ip }}"
|
||||
vm_nms: "{{ system_cfg.prefix }}"
|
||||
vm_gw: "{{ system_cfg.gateway }}"
|
||||
vm_dns: "{{ system_cfg.dns_servers }}"
|
||||
vm_dns_search: "{{ system_cfg.dns_search }}"
|
||||
vm_path: "{{ system_cfg.path }}"
|
||||
vm_size: "{{ (system_cfg.disks | default([]) | first | default({})).size | default(0) }}"
|
||||
changed_when: false
|
||||
234
roles/global_defaults/tasks/validation.yml
Normal file
234
roles/global_defaults/tasks/validation.yml
Normal file
@@ -0,0 +1,234 @@
|
||||
---
|
||||
- name: Validate core variables
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- install_type is defined
|
||||
- install_type in ["virtual", "physical"]
|
||||
- hypervisor is defined
|
||||
- hypervisor in ["libvirt", "proxmox", "vmware", "xen", "none"]
|
||||
- filesystem is defined
|
||||
- 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 install_type/hypervisor relationship
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- install_type == "physical" or hypervisor in ["libvirt", "proxmox", "vmware", "xen"]
|
||||
fail_msg: "hypervisor must be one of: libvirt, proxmox, vmware, xen when install_type=virtual."
|
||||
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/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:
|
||||
- install_type == "virtual"
|
||||
- hypervisor == "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.node | 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,node,storage) and system.(id,network)."
|
||||
quiet: true
|
||||
|
||||
- name: Validate VMware hypervisor inputs
|
||||
when:
|
||||
- install_type == "virtual"
|
||||
- hypervisor == "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:
|
||||
- install_type == "virtual"
|
||||
- hypervisor == "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:
|
||||
- install_type == "physical" or (boot_iso is defined and (boot_iso | string | length) > 0)
|
||||
fail_msg: "boot_iso is required when install_type=virtual."
|
||||
quiet: true
|
||||
|
||||
- name: Validate firewall and feature flags
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- firewall_backend is defined
|
||||
- firewall_backend in ["firewalld", "ufw"]
|
||||
- firewall_toolkit is defined
|
||||
- firewall_toolkit in ["iptables", "nftables"]
|
||||
- firewall_enabled is defined
|
||||
- motd_enabled is defined
|
||||
- sudo_banner_enabled is defined
|
||||
- luks_enabled is defined
|
||||
- chroot_tool is defined
|
||||
- chroot_tool in ["arch-chroot", "chroot", "systemd-nspawn"]
|
||||
fail_msg: Invalid feature flags were specified, please check your inventory/vars.
|
||||
quiet: true
|
||||
|
||||
- name: Validate system configuration exists
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- system_cfg is defined
|
||||
- system_cfg is mapping
|
||||
fail_msg: "system configuration is missing. Define system: {...} or legacy vm_* variables."
|
||||
quiet: true
|
||||
|
||||
- name: Validate virtual system sizing
|
||||
when: install_type == "virtual"
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- system_cfg.cpus is defined and (system_cfg.cpus | int) > 0
|
||||
- system_cfg.memory_mb is defined and (system_cfg.memory_mb | 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
|
||||
- >-
|
||||
filesystem != "btrfs"
|
||||
or (
|
||||
(system_cfg.disks[0].size | float)
|
||||
>= (
|
||||
(
|
||||
(system_cfg.memory_mb | float / 1024 >= 16.0)
|
||||
| ternary(
|
||||
(system_cfg.memory_mb | float / 2048),
|
||||
[system_cfg.memory_mb | float / 1024, 4.0] | max
|
||||
)
|
||||
)
|
||||
+ 5.5
|
||||
)
|
||||
)
|
||||
fail_msg: "Invalid system sizing. Check system.cpus, system.memory_mb, and system.disks[0].size."
|
||||
quiet: true
|
||||
|
||||
- name: Validate all virtual disks have a positive size
|
||||
when: install_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 install_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 | default('') | string | trim) == ''
|
||||
fail_msg: "system.disks[0].mount 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('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 | default('') | string) | trim }}"
|
||||
disk_fstype: "{{ (item.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 install_type == "virtual" or (disk_device | length) > 0
|
||||
- disk_mount == "" or install_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
|
||||
@@ -51,7 +51,7 @@ partitioning_efi_mountpoint: >-
|
||||
if (partitioning_separate_boot | bool)
|
||||
else (
|
||||
'/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'
|
||||
)
|
||||
}}
|
||||
|
||||
@@ -47,20 +47,20 @@
|
||||
args:
|
||||
creates: /mnt/{{ '@' if item.subvol == 'root' else '@' + item.subvol }}
|
||||
loop:
|
||||
- {subvol: root}
|
||||
- {subvol: swap}
|
||||
- {subvol: home}
|
||||
- {subvol: var}
|
||||
- {subvol: pkg}
|
||||
- {subvol: var_log}
|
||||
- {subvol: var_log_audit}
|
||||
- { subvol: root }
|
||||
- { subvol: swap }
|
||||
- { subvol: home }
|
||||
- { subvol: var }
|
||||
- { subvol: pkg }
|
||||
- { subvol: var_log }
|
||||
- { subvol: var_log_audit }
|
||||
register: partitioning_btrfs_subvol_result
|
||||
|
||||
- name: Set quotas for subvolumes
|
||||
when: cis_enabled
|
||||
ansible.builtin.command: btrfs qgroup limit {{ item.quota }} /mnt/{{ '@' if item.subvol == 'root' else '@' + item.subvol }}
|
||||
loop:
|
||||
- {subvol: home, quota: 2G}
|
||||
- { subvol: home, quota: 2G }
|
||||
register: partitioning_btrfs_qgroup_result
|
||||
changed_when: false
|
||||
|
||||
|
||||
@@ -6,20 +6,22 @@
|
||||
fstype: ext4
|
||||
force: true
|
||||
loop:
|
||||
- {lv: root}
|
||||
- {lv: home}
|
||||
- {lv: var}
|
||||
- {lv: var_log}
|
||||
- {lv: var_log_audit}
|
||||
- { lv: root }
|
||||
- { lv: home }
|
||||
- { lv: var }
|
||||
- { lv: var_log }
|
||||
- { lv: var_log_audit }
|
||||
|
||||
- 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 (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 }}"
|
||||
loop:
|
||||
- {lv: root}
|
||||
- {lv: home}
|
||||
- {lv: var}
|
||||
- {lv: var_log}
|
||||
- {lv: var_log_audit}
|
||||
- { lv: root }
|
||||
- { lv: home }
|
||||
- { lv: var }
|
||||
- { lv: var_log }
|
||||
- { lv: var_log_audit }
|
||||
register: partitioning_ext4_tune_result
|
||||
changed_when: partitioning_ext4_tune_result.rc == 0
|
||||
|
||||
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')
|
||||
| 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.fstype is defined
|
||||
- item.fstype in ['btrfs', 'ext4', 'xfs']
|
||||
- item.mount is defined
|
||||
- item.mount | string | length > 0
|
||||
- item.mount.startswith('/')
|
||||
- item.mount != '/'
|
||||
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.label | default('') | string | length > 0) | ternary(item.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.fstype }}"
|
||||
opts: "{{ ('-L ' ~ item.label) if (item.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 }}"
|
||||
state: directory
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0755"
|
||||
loop: "{{ partitioning_extra_disks }}"
|
||||
loop_control:
|
||||
label: "{{ item.mount }}"
|
||||
|
||||
- name: Mount additional disks for fstab generation
|
||||
when: partitioning_extra_disks | length > 0
|
||||
ansible.posix.mount:
|
||||
path: "/mnt{{ item.mount }}"
|
||||
src: "{{ item.partition }}"
|
||||
fstype: "{{ item.fstype }}"
|
||||
opts: "{{ item.opts | default('defaults') }}"
|
||||
state: mounted
|
||||
loop: "{{ partitioning_extra_disks }}"
|
||||
loop_control:
|
||||
label: "{{ item.mount }}"
|
||||
@@ -403,9 +403,9 @@
|
||||
size: "{{ partitioning_lvm_swap_gb | string + 'G' }}"
|
||||
- lv: home
|
||||
size: "{{ partitioning_lvm_home_gb | string + 'G' }}"
|
||||
- {lv: var, size: "2G"}
|
||||
- {lv: var_log, size: "2G"}
|
||||
- {lv: var_log_audit, size: "1.5G"}
|
||||
- { lv: var, size: "2G" }
|
||||
- { lv: var_log, size: "2G" }
|
||||
- { lv: var_log_audit, size: "1.5G" }
|
||||
|
||||
- name: Create filesystems
|
||||
block:
|
||||
@@ -427,7 +427,7 @@
|
||||
when:
|
||||
- partitioning_separate_boot | bool
|
||||
- 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: >-
|
||||
tune2fs -O "^orphan_file,^metadata_csum_seed"
|
||||
"{{ install_drive }}{{ partitioning_boot_fs_partition_suffix }}"
|
||||
@@ -548,14 +548,14 @@
|
||||
- name: Mount filesystems and subvolumes
|
||||
when:
|
||||
- >-
|
||||
cis_enabled or (
|
||||
not cis_enabled and (
|
||||
(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'])
|
||||
)
|
||||
cis_enabled or (
|
||||
not cis_enabled and (
|
||||
(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'])
|
||||
)
|
||||
)
|
||||
- >-
|
||||
not (item.path in ['/swap', '/var/cache/pacman/pkg'] and filesystem != 'btrfs')
|
||||
not (item.path in ['/swap', '/var/cache/pacman/pkg'] and filesystem != 'btrfs')
|
||||
- swap_enabled | bool or item.path != '/swap'
|
||||
ansible.posix.mount:
|
||||
path: /mnt{{ item.path }}
|
||||
@@ -663,3 +663,6 @@
|
||||
ansible.builtin.command: "{{ partitioning_swap_cmd }}"
|
||||
register: partitioning_swap_activate_result
|
||||
changed_when: partitioning_swap_activate_result.rc == 0
|
||||
|
||||
- name: Mount additional disks
|
||||
ansible.builtin.include_tasks: extra_disks.yml
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
fstype: xfs
|
||||
force: true
|
||||
loop:
|
||||
- {lv: root}
|
||||
- {lv: home}
|
||||
- {lv: var}
|
||||
- {lv: var_log}
|
||||
- {lv: var_log_audit}
|
||||
- { lv: root }
|
||||
- { lv: home }
|
||||
- { lv: var }
|
||||
- { lv: var_log }
|
||||
- { lv: var_log_audit }
|
||||
|
||||
188
roles/system_check/tasks/main.yml
Normal file
188
roles/system_check/tasks/main.yml
Normal file
@@ -0,0 +1,188 @@
|
||||
---
|
||||
- name: Gather minimal facts for safety checks
|
||||
ansible.builtin.setup:
|
||||
gather_subset:
|
||||
- "!all"
|
||||
- "min"
|
||||
- "mounts"
|
||||
changed_when: false
|
||||
|
||||
- name: Production system protection check
|
||||
block:
|
||||
- name: Check for OS release information
|
||||
ansible.builtin.stat:
|
||||
path: /etc/os-release
|
||||
register: system_check_os_release_exists
|
||||
|
||||
- name: Check for live environment markers
|
||||
ansible.builtin.stat:
|
||||
path: "{{ item }}"
|
||||
loop:
|
||||
- /run/archiso
|
||||
- /run/live
|
||||
- /run/initramfs
|
||||
- /run/initramfs/live
|
||||
register: system_check_live_markers
|
||||
changed_when: false
|
||||
|
||||
- name: Determine root filesystem type
|
||||
ansible.builtin.set_fact:
|
||||
system_check_root_fstype: >-
|
||||
{{
|
||||
ansible_mounts
|
||||
| selectattr('mount', 'equalto', '/')
|
||||
| map(attribute='fstype')
|
||||
| list
|
||||
| first
|
||||
| default('')
|
||||
| lower
|
||||
}}
|
||||
changed_when: false
|
||||
|
||||
- name: Identify live environment indicators
|
||||
ansible.builtin.set_fact:
|
||||
system_check_is_live_environment: >-
|
||||
{{
|
||||
(not system_check_os_release_exists.stat.exists)
|
||||
or (
|
||||
system_check_live_markers.results
|
||||
| selectattr('stat.exists')
|
||||
| list
|
||||
| length
|
||||
> 0
|
||||
)
|
||||
or system_check_root_fstype in ['overlay', 'overlayfs', 'squashfs', 'aufs']
|
||||
or (ansible_hostname | default('') | lower is search('live'))
|
||||
}}
|
||||
changed_when: false
|
||||
|
||||
- name: Assert target is not a production system
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- system_check_is_live_environment | bool
|
||||
fail_msg: |
|
||||
PRODUCTION SYSTEM DETECTED - ABORTING
|
||||
|
||||
The target system appears to be a production environment with an already
|
||||
installed operating system. This playbook is designed to run ONLY on
|
||||
live installer environments (e.g., ArchLinux ISO, Debian netinst).
|
||||
|
||||
DO NOT proceed on production systems. This could result in data loss.
|
||||
|
||||
To use this playbook:
|
||||
1. Boot from a live installer ISO (ArchLinux, Debian, Ubuntu, etc.)
|
||||
2. Run playbook against live environment
|
||||
3. Target an empty disk for installation
|
||||
|
||||
If you are certain you want to proceed, you must verify you are running
|
||||
from a live environment, not an installed system.
|
||||
quiet: true
|
||||
|
||||
- name: VM existence protection check
|
||||
when: install_type == "virtual"
|
||||
block:
|
||||
- name: Check if VM already exists on libvirt
|
||||
when: hypervisor == "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 == "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 == "proxmox"
|
||||
delegate_to: localhost
|
||||
become: false
|
||||
community.proxmox.proxmox_vm_info:
|
||||
api_host: "{{ hypervisor_url }}"
|
||||
api_user: "{{ hypervisor_username }}"
|
||||
api_password: "{{ hypervisor_password }}"
|
||||
node: "{{ hypervisor_node }}"
|
||||
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 == "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 == "vmware"
|
||||
delegate_to: localhost
|
||||
community.vmware.vmware_guest_info:
|
||||
hostname: "{{ hypervisor_url }}"
|
||||
username: "{{ hypervisor_username }}"
|
||||
password: "{{ hypervisor_password }}"
|
||||
validate_certs: "{{ hypervisor_validate_certs }}"
|
||||
datacenter: "{{ hypervisor_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 == "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 == "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 == "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 == "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,15 @@
|
||||
---
|
||||
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_image_dir, hostname ~ '.qcow2'] | ansible.builtin.path_join }}
|
||||
virtualization_libvirt_cloudinit_path: >-
|
||||
{{ [virtualization_libvirt_image_dir, hostname ~ '-cloudinit.iso'] | ansible.builtin.path_join }}
|
||||
virtualization_mac_address: >-
|
||||
{{ '52:54:00' | community.general.random_mac(seed=hostname) }}
|
||||
virtualization_xen_disk_path: /var/lib/xen/images
|
||||
|
||||
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
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
@@ -7,19 +33,22 @@
|
||||
- create
|
||||
- -f
|
||||
- qcow2
|
||||
- "{{ virtualization_libvirt_disk_path }}"
|
||||
- "{{ vm_size }}G"
|
||||
creates: "{{ virtualization_libvirt_disk_path }}"
|
||||
- "{{ item.path }}"
|
||||
- "{{ item.size }}G"
|
||||
creates: "{{ item.path }}"
|
||||
loop: "{{ virtualization_libvirt_disks }}"
|
||||
loop_control:
|
||||
label: "{{ item.path }}"
|
||||
|
||||
- name: Render cloud config templates
|
||||
delegate_to: localhost
|
||||
ansible.builtin.template:
|
||||
src: "{{ item.src }}"
|
||||
dest: /tmp/{{ item.dest_prefix }}-{{ hostname }}.yml
|
||||
mode: '0644'
|
||||
mode: "0644"
|
||||
loop:
|
||||
- {src: cloud-user-data.yml.j2, dest_prefix: cloud-user-data}
|
||||
- {src: cloud-network-config.yml.j2, dest_prefix: cloud-network-config}
|
||||
- { src: cloud-user-data.yml.j2, dest_prefix: cloud-user-data }
|
||||
- { src: cloud-network-config.yml.j2, dest_prefix: cloud-network-config }
|
||||
|
||||
- name: Create cloud-init disk
|
||||
delegate_to: localhost
|
||||
@@ -43,3 +72,9 @@
|
||||
community.libvirt.virt:
|
||||
name: "{{ hostname }}"
|
||||
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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
- name: Deploy VM on Proxmox
|
||||
delegate_to: localhost
|
||||
vars:
|
||||
virtualization_dns_value: "{{ vm_dns if vm_dns is defined else '' }}"
|
||||
virtualization_dns_value: "{{ system_cfg.dns_servers if system_cfg.dns_servers is defined else '' }}"
|
||||
virtualization_dns_list_raw: >-
|
||||
{{
|
||||
virtualization_dns_value
|
||||
@@ -11,7 +11,7 @@
|
||||
}}
|
||||
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_value: "{{ system_cfg.dns_search if system_cfg.dns_search is defined else '' }}"
|
||||
virtualization_search_list_raw: >-
|
||||
{{
|
||||
virtualization_search_value
|
||||
@@ -20,6 +20,12 @@
|
||||
}}
|
||||
virtualization_search_list: >-
|
||||
{{ virtualization_search_list_raw | map('trim') | reject('equalto', '') | list }}
|
||||
virtualization_proxmox_scsi: >-
|
||||
{%- set out = {} -%}
|
||||
{%- for disk in system_cfg.disks -%}
|
||||
{%- set _ = out.update({ 'scsi' ~ loop.index0: hypervisor_storage ~ ':' ~ (disk.size | int) }) -%}
|
||||
{%- endfor -%}
|
||||
{{ out }}
|
||||
community.proxmox.proxmox_kvm:
|
||||
api_host: "{{ hypervisor_url }}"
|
||||
api_user: "{{ hypervisor_username }}"
|
||||
@@ -28,12 +34,12 @@
|
||||
cipassword: "{{ user_password }}"
|
||||
ciupgrade: false
|
||||
node: "{{ hypervisor_node }}"
|
||||
vmid: "{{ vm_id }}"
|
||||
vmid: "{{ system_cfg.id }}"
|
||||
name: "{{ hostname }}"
|
||||
cpu: host
|
||||
cores: "{{ vm_cpus }}"
|
||||
memory: "{{ vm_memory }}"
|
||||
balloon: "{{ vm_ballo if vm_ballo is defined and vm_ballo | int > 0 else omit }}"
|
||||
cores: "{{ system_cfg.cpus }}"
|
||||
memory: "{{ system_cfg.memory_mb }}"
|
||||
balloon: "{{ system_cfg.balloon_mb if system_cfg.balloon_mb is defined and system_cfg.balloon_mb | int > 0 else omit }}"
|
||||
numa_enabled: true
|
||||
hotplug: network,disk
|
||||
update: "{{ virtualization_tpm2_enabled | bool }}"
|
||||
@@ -42,8 +48,7 @@
|
||||
machine: "{{ 'q35' if virtualization_tpm2_enabled | bool else omit }}"
|
||||
boot: ac
|
||||
scsihw: virtio-scsi-single
|
||||
scsi:
|
||||
scsi0: "{{ hypervisor_storage }}:{{ vm_size }}"
|
||||
scsi: "{{ virtualization_proxmox_scsi }}"
|
||||
efidisk0:
|
||||
efitype: 4m
|
||||
format: raw
|
||||
@@ -60,13 +65,14 @@
|
||||
ide1: "{{ rhel_iso + ',media=cdrom' if rhel_iso is defined and rhel_iso | length > 0 else omit }}"
|
||||
ide2: "{{ hypervisor_storage }}:cloudinit"
|
||||
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:
|
||||
ipconfig0: >-
|
||||
{{
|
||||
'ip=' ~ vm_ip ~ '/' ~ vm_nms
|
||||
~ (',gw=' ~ vm_gw if vm_gw is defined and vm_gw | length else '')
|
||||
if vm_ip is defined and vm_ip | length
|
||||
'ip=' ~ system_cfg.ip ~ '/' ~ system_cfg.prefix
|
||||
~ (',gw=' ~ system_cfg.gateway if system_cfg.gateway is defined and system_cfg.gateway | length else '')
|
||||
if system_cfg.ip is defined and system_cfg.ip | string | length
|
||||
else 'ip=dhcp'
|
||||
}}
|
||||
nameservers: "{{ virtualization_dns_list if virtualization_dns_list | length else omit }}"
|
||||
@@ -82,5 +88,11 @@
|
||||
api_password: "{{ hypervisor_password }}"
|
||||
node: "{{ hypervisor_node }}"
|
||||
name: "{{ hostname }}"
|
||||
vmid: "{{ vm_id }}"
|
||||
vmid: "{{ system_cfg.id }}"
|
||||
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_storage }}"
|
||||
loop: "{{ system_cfg.disks }}"
|
||||
loop_control:
|
||||
label: "{{ item | to_json }}"
|
||||
changed_when: false
|
||||
|
||||
- name: Create VM in vCenter
|
||||
delegate_to: localhost
|
||||
community.vmware.vmware_guest:
|
||||
hostname: "{{ hypervisor_url }}"
|
||||
username: "{{ hypervisor_username }}"
|
||||
password: "{{ hypervisor_password }}"
|
||||
validate_certs: false
|
||||
validate_certs: "{{ hypervisor_validate_certs }}"
|
||||
datacenter: "{{ hypervisor_datacenter }}"
|
||||
cluster: "{{ hypervisor_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 }}"
|
||||
guest_id: otherLinux64Guest
|
||||
annotation: |
|
||||
{{ note if note is defined else '' }}
|
||||
state: "{{ 'poweredoff' if virtualization_tpm2_enabled | bool else 'poweredon' }}"
|
||||
disk:
|
||||
- size_gb: "{{ vm_size }}"
|
||||
type: thin
|
||||
datastore: "{{ hypervisor_storage }}"
|
||||
disk: "{{ virtualization_vmware_disks }}"
|
||||
hardware:
|
||||
memory_mb: "{{ vm_memory }}"
|
||||
num_cpus: "{{ vm_cpus }}"
|
||||
memory_mb: "{{ system_cfg.memory_mb }}"
|
||||
num_cpus: "{{ system_cfg.cpus }}"
|
||||
boot_firmware: efi
|
||||
secure_boot: false
|
||||
cdrom: >-
|
||||
@@ -44,9 +54,18 @@
|
||||
} ] if rhel_iso is defined and rhel_iso | length > 0 else [] )
|
||||
}}
|
||||
networks:
|
||||
- name: "{{ vm_nif }}"
|
||||
- name: "{{ system_cfg.network }}"
|
||||
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
|
||||
when: virtualization_tpm2_enabled | bool
|
||||
@@ -55,9 +74,9 @@
|
||||
hostname: "{{ hypervisor_url }}"
|
||||
username: "{{ hypervisor_username }}"
|
||||
password: "{{ hypervisor_password }}"
|
||||
validate_certs: false
|
||||
validate_certs: "{{ hypervisor_validate_certs }}"
|
||||
datacenter: "{{ hypervisor_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 }}"
|
||||
state: present
|
||||
|
||||
@@ -68,7 +87,16 @@
|
||||
hostname: "{{ hypervisor_url }}"
|
||||
username: "{{ hypervisor_username }}"
|
||||
password: "{{ hypervisor_password }}"
|
||||
validate_certs: false
|
||||
validate_certs: "{{ hypervisor_validate_certs }}"
|
||||
datacenter: "{{ hypervisor_datacenter }}"
|
||||
name: "{{ hostname }}"
|
||||
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,27 @@ network:
|
||||
id0:
|
||||
match:
|
||||
macaddress: "{{ virtualization_mac_address }}"
|
||||
{% set has_static = vm_ip is defined and vm_ip | length %}
|
||||
{% set dns_value = vm_dns if vm_dns is defined else '' %}
|
||||
{% set has_static = system_cfg.ip is defined and system_cfg.ip | string | length %}
|
||||
{% set dns_value = system_cfg.dns_servers if system_cfg.dns_servers is defined else '' %}
|
||||
{% set dns_list_raw = dns_value if dns_value is iterable and dns_value is not string else dns_value.split(',') %}
|
||||
{% 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_value = system_cfg.dns_search if system_cfg.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 %}
|
||||
addresses:
|
||||
- "{{ vm_ip }}/{{ vm_nms }}"
|
||||
{% if vm_gw is defined and vm_gw | length %}
|
||||
gateway4: "{{ vm_gw }}"
|
||||
- "{{ system_cfg.ip }}/{{ system_cfg.prefix }}"
|
||||
{% if system_cfg.gateway is defined and system_cfg.gateway | string | length %}
|
||||
gateway4: "{{ system_cfg.gateway }}"
|
||||
{% endif %}
|
||||
{% else %}
|
||||
dhcp4: true
|
||||
{% if (vm_dns is defined and vm_dns | length) or (vm_dns_search is defined and vm_dns_search | length) %}
|
||||
{% if (system_cfg.dns_servers is defined and system_cfg.dns_servers | length) or (system_cfg.dns_search is defined and system_cfg.dns_search | length) %}
|
||||
dhcp4-overrides:
|
||||
{% if vm_dns is defined and vm_dns | length %}
|
||||
{% if system_cfg.dns_servers is defined and system_cfg.dns_servers | length %}
|
||||
use-dns: false
|
||||
{% endif %}
|
||||
{% if vm_dns_search is defined and vm_dns_search | length %}
|
||||
{% if system_cfg.dns_search is defined and system_cfg.dns_search | length %}
|
||||
use-domains: false
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<domain type='kvm'>
|
||||
<name>{{ hostname }}</name>
|
||||
<memory>{{ vm_memory | int * 1024 }}</memory>
|
||||
{% if vm_ballo is defined and vm_ballo | int > 0 %}<currentMemory>{{ vm_ballo | int * 1024 }}</currentMemory>{% endif %}
|
||||
<vcpu placement='static'>{{ vm_cpus }}</vcpu>
|
||||
<memory>{{ system_cfg.memory_mb | int * 1024 }}</memory>
|
||||
{% if system_cfg.balloon_mb is defined and system_cfg.balloon_mb | int > 0 %}<currentMemory>{{ system_cfg.balloon_mb | int * 1024 }}</currentMemory>{% endif %}
|
||||
<vcpu placement='static'>{{ system_cfg.cpus }}</vcpu>
|
||||
<os>
|
||||
<type arch='x86_64' machine="pc-q35-8.0">hvm</type>
|
||||
<bootmenu enable='no'/>
|
||||
@@ -22,11 +22,13 @@
|
||||
<on_reboot>restart</on_reboot>
|
||||
<on_crash>destroy</on_crash>
|
||||
<devices>
|
||||
{% for disk in virtualization_libvirt_disks | default([]) %}
|
||||
<disk type='file' device='disk'>
|
||||
<driver name='qemu' type='qcow2'/>
|
||||
<source file='{{ virtualization_libvirt_disk_path }}'/>
|
||||
<target dev='vda' bus='virtio'/>
|
||||
<driver name='qemu' type='{{ disk.format }}'/>
|
||||
<source file='{{ disk.path }}'/>
|
||||
<target dev='{{ disk.target }}' bus='{{ disk.bus }}'/>
|
||||
</disk>
|
||||
{% endfor %}
|
||||
<disk type="file" device="cdrom">
|
||||
<driver name="qemu" type="raw"/>
|
||||
<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_mb }}"
|
||||
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,5 +1,6 @@
|
||||
---
|
||||
hypervisor: "none"
|
||||
hypervisor:
|
||||
type: "none"
|
||||
install_type: "physical"
|
||||
install_drive: "/dev/sda"
|
||||
|
||||
@@ -8,7 +9,7 @@ filesystem: "btrfs"
|
||||
|
||||
cis: false
|
||||
selinux: true
|
||||
firewalld_enabled: true
|
||||
firewall_enabled: true
|
||||
|
||||
luks_enabled: true
|
||||
luks_passphrase: "1234"
|
||||
|
||||
@@ -1,24 +1,32 @@
|
||||
---
|
||||
# Set vm_ip for static addressing. Remove vm_ip to use DHCP.
|
||||
vm_ip: "{{ inventory_hostname }}"
|
||||
# Set system.ip for static addressing. Remove system.ip to use DHCP.
|
||||
system:
|
||||
ip: "{{ inventory_hostname }}"
|
||||
|
||||
install_type: "virtual"
|
||||
install_drive: "/dev/sda" # Use /dev/vda for virtio/libvirt.
|
||||
custom_iso: false # Set true to skip ArchISO-specific validation and pacman setup.
|
||||
cis: false # Set true to enable CIS hardening.
|
||||
selinux: true # Toggle SELinux where supported.
|
||||
firewalld_enabled: true # Toggle firewalld package and service.
|
||||
firewall_enabled: true # Toggle firewall package and service.
|
||||
|
||||
hypervisor_url: "pve01.example.com"
|
||||
hypervisor_username: "root@pam"
|
||||
hypervisor_password: "CHANGE_ME"
|
||||
hypervisor_node: "pve01"
|
||||
hypervisor_storage: "local-lvm"
|
||||
hypervisor_datacenter: "dc01"
|
||||
hypervisor_cluster: "cluster01"
|
||||
hypervisor:
|
||||
type: "proxmox" # libvirt|proxmox|vmware|xen|none
|
||||
url: "pve01.example.com"
|
||||
username: "root@pam"
|
||||
password: "CHANGE_ME"
|
||||
node: "pve01"
|
||||
storage: "local-lvm"
|
||||
datacenter: "dc01"
|
||||
cluster: "cluster01"
|
||||
validate_certs: false
|
||||
|
||||
# Legacy (still supported): hypervisor_url, hypervisor_username, hypervisor_password, hypervisor_node, hypervisor_storage,
|
||||
# hypervisor_datacenter, hypervisor_cluster, hypervisor_validate_certs.
|
||||
|
||||
# VMware (only needed when hypervisor: vmware)
|
||||
# vm_path: "/Folder" # Optional folder path segment in vCenter.
|
||||
# system:
|
||||
# path: "/Folder" # Optional folder path segment in vCenter.
|
||||
vmware_ssh: true
|
||||
|
||||
# LUKS disk encryption (optional)
|
||||
|
||||
Reference in New Issue
Block a user