Playbook flow and environment prep

This commit is contained in:
2025-12-25 20:47:37 +01:00
parent 7953c2c285
commit a71d27c29d
2 changed files with 209 additions and 120 deletions

133
main.yml
View File

@@ -1,7 +1,7 @@
--- ---
- name: Create and configure VMs - name: Create and configure VMs
hosts: all hosts: all
strategy: free strategy: free # noqa: run-once[play]
gather_facts: false gather_facts: false
become: true become: true
vars_prompt: vars_prompt:
@@ -26,36 +26,65 @@
confirm: true confirm: true
vars_files: vars.yml vars_files: vars.yml
pre_tasks: pre_tasks:
- name: Set ansible_python_interpreter - name: Validate variables
when: os | lower in ["almalinux", "rhel8", "rhel9", "rhel10", "rocky"] ansible.builtin.assert:
that:
- install_type in ["virtual", "physical"]
- hypervisor in ["libvirt", "proxmox", "vmware", "none"]
- filesystem in ["btrfs", "ext4", "xfs"]
- install_drive is defined
- install_type == "physical" or vm_size is defined
- install_type == "physical" or vm_memory is defined
- os in ["archlinux", "almalinux", "debian11", "debian12", "debian13", "fedora", "rhel8", "rhel9", "rhel10", "rocky", "ubuntu", "ubuntu-lts"]
- os not in ["rhel8", "rhel9", "rhel10"] or rhel_iso is defined
- >-
install_type == "physical"
or (
(filesystem == "btrfs" and (vm_size | default(0) | int) >= 10)
or (filesystem != "btrfs" and (vm_size | default(0) | int) >= 20)
)
- >-
install_type == "physical"
or (
(vm_size | default(0) | float)
>= (
(vm_memory | default(0) | float / 1024 >= 16.0)
| ternary(
(vm_memory | default(0) | float / 2048),
[vm_memory | default(0) | float / 1024, 4.0] | max
)
+ 16
)
)
fail_msg: Invalid input specified, please try again.
- name: Normalize optional flags
ansible.builtin.set_fact:
cis: "{{ cis | default(false) | bool }}"
custom_iso: "{{ custom_iso | default(false) | bool }}"
is_rhel: "{{ os | default('') | lower in ['almalinux', 'fedora', 'rhel8', 'rhel9', 'rhel10', 'rocky'] }}"
is_debian: "{{ os | default('') | lower in ['debian11', 'debian12', 'debian13', 'ubuntu', 'ubuntu-lts'] }}"
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"]
ansible.builtin.set_fact: ansible.builtin.set_fact:
ansible_python_interpreter: /usr/bin/python3 ansible_python_interpreter: /usr/bin/python3
changed_when: false
- name: Set default variables - name: Set SSH access
ansible.builtin.set_fact: when:
cis: false - install_type == "virtual"
- hypervisor != "vmware"
- name: Set SSH Access
when: hypervisor != "vmware"
ansible.builtin.set_fact: ansible.builtin.set_fact:
ansible_user: "{{ user_name }}" ansible_user: "{{ user_name }}"
ansible_password: "{{ user_password }}" ansible_password: "{{ user_password }}"
ansible_become_password: "{{ user_password }}" ansible_become_password: "{{ user_password }}"
ansible_ssh_extra_args: "-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no" ansible_ssh_extra_args: "-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no"
- name: Validate variables - name: Set connection for VMware
ansible.builtin.assert:
that:
- hypervisor in ["libvirt", "proxmox", "vmware", "none"]
- filesystem in ["btrfs", "ext4", "xfs"]
- install_drive is defined
- os in ["archlinux", "almalinux", "debian11", "debian12", "debian13", "fedora", "rhel8", "rhel9", "rhel10", "rocky", "ubuntu", "ubuntu-lts"]
- os not in ["rhel8", "rhel9", "rhel10"] or rhel_iso is defined
- (filesystem == "btrfs" and (vm_size | int) >= 10) or (filesystem != "btrfs" and (vm_size | int) >= 20)
- (vm_size | float) >= ((vm_memory | float / 1024 >= 16.0) | ternary((vm_memory | float / 2048), [vm_memory | float / 1024, 4.0] | max) + 16)
fail_msg: Invalid input specified, please try again.
- name: Set connection
when: hypervisor == "vmware" when: hypervisor == "vmware"
ansible.builtin.set_fact: ansible.builtin.set_fact:
ansible_connection: vmware_tools ansible_connection: vmware_tools
@@ -73,31 +102,65 @@
- role: partitioning - role: partitioning
vars: vars:
boot_partition_suffix: 1 partitioning_boot_partition_suffix: 1
main_partition_suffix: 2 partitioning_main_partition_suffix: 2
- role: bootstrap - role: bootstrap
- role: configuration - role: configuration
- role: cis - role: cis
when: cis | bool when: cis | default(false) | bool
- role: cleanup - role: cleanup
when: install_type == "virtual" when: install_type in ["virtual", "physical"]
vars: become: false
ansible_connection: local
tasks: post_tasks:
- name: Set final SSH Credentials - name: Set post-reboot connection flags
when: hypervisor != 'vmware' or (hypervisor == 'vmware' and vmware_ssh | bool) ansible.builtin.set_fact:
post_reboot_can_connect: >-
{{
(ansible_connection | default('ssh')) != 'ssh'
or ((vm_ip | default('') | string | length) > 0)
or (
install_type == 'physical'
and (ansible_host | default('') | string | length) > 0
)
}}
changed_when: false
- name: Set final SSH credentials for post-reboot tasks
when:
- post_reboot_can_connect | default(false) | bool
ansible.builtin.set_fact: ansible.builtin.set_fact:
ansible_user: "{{ user_name }}" ansible_user: "{{ user_name }}"
ansible_password: "{{ user_password }}" ansible_password: "{{ user_password }}"
ansible_become_password: "{{ user_password }}" ansible_become_password: "{{ user_password }}"
ansible_ssh_extra_args: "-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no" ansible_ssh_extra_args: "-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no"
- name: Check if VM is back and running - name: Install post-reboot extra packages
when: not (hypervisor == 'vmware' and cis | bool) when:
ansible.builtin.wait_for_connection: - extra_packages is defined
timeout: 300 - post_reboot_can_connect | default(false) | bool
block:
- name: Normalize extra package list
ansible.builtin.set_fact:
post_install_extra_packages: >-
{{
(
extra_packages
if (extra_packages is iterable and extra_packages is not string)
else (extra_packages | default('') | string).split(',')
)
| map('trim')
| reject('equalto', '')
| list
}}
changed_when: false
- name: Install extra packages
when: post_install_extra_packages | length > 0
ansible.builtin.package:
name: "{{ post_install_extra_packages }}"
state: present

View File

@@ -1,10 +1,10 @@
--- ---
- name: Configre work environment - name: Configure work environment
become: true become: "{{ hypervisor != 'vmware' }}"
block: block:
- name: Wait for connection - name: Wait for connection
ansible.builtin.wait_for_connection: ansible.builtin.wait_for_connection:
timeout: 60 timeout: 180
delay: 5 delay: 5
- name: Gather facts - name: Gather facts
@@ -13,118 +13,144 @@
- name: Check if host is booted from the Arch install media - name: Check if host is booted from the Arch install media
ansible.builtin.stat: ansible.builtin.stat:
path: /run/archiso path: /run/archiso
register: archiso_stat register: environment_archiso_stat
- name: Abort if the host is not booted from the Arch install media - name: Abort if the host is not booted from the Arch install media
when:
- not (custom_iso | default(false) | bool)
- not environment_archiso_stat.stat.exists
ansible.builtin.fail: ansible.builtin.fail:
msg: This host is not booted from the Arch install media! msg: This host is not booted from the Arch install media!
when: not archiso_stat.stat.exists
- name: Register Network Interface - name: Select primary Network Interface
when: hypervisor == "vmware" when: hypervisor == "vmware"
ansible.builtin.shell: "set -o pipefail && ip l | awk -F': ' '!/lo/{print $2; exit}'" ansible.builtin.set_fact:
changed_when: interface_name.rc == 0 environment_interface_name: >-
register: interface_name {{
(
(ansible_facts.interfaces | default(ansible_facts['ansible_interfaces'] | default([])))
| reject('equalto', 'lo')
| list
| first
)
| default('')
}}
changed_when: false
- name: Set IP-Address - name: Set IP-Address
when: hypervisor == "vmware" when:
ansible.builtin.command: "ip addr replace {{ ansible_host }}/{{ vm_nms | default(24) }} dev {{ interface_name.stdout }}" - hypervisor == "vmware"
changed_when: result.rc == 0 - vm_ip is defined
register: result - vm_ip | length
ansible.builtin.command: >-
ip addr replace {{ vm_ip }}/{{ vm_nms | default(24) }}
dev {{ environment_interface_name }}
register: environment_ip_result
changed_when: environment_ip_result.rc == 0
- name: Set Default Gateway - name: Set Default Gateway
when: hypervisor == "vmware" when:
- hypervisor == "vmware"
- vm_gw is defined
- vm_gw | length
- vm_ip is defined
- vm_ip | length
ansible.builtin.command: "ip route replace default via {{ vm_gw }}" ansible.builtin.command: "ip route replace default via {{ vm_gw }}"
changed_when: result.rc == 0 register: environment_gateway_result
register: result changed_when: environment_gateway_result.rc == 0
- name: Synchronize clock via NTP - name: Synchronize clock via NTP
ansible.builtin.command: timedatectl set-ntp true ansible.builtin.command: timedatectl set-ntp true
changed_when: result.rc == 0 register: environment_ntp_result
register: result changed_when: false
- name: Configure SSH for root login - name: Configure SSH for root login
when: hypervisor == "vmware" and (vmware_ssh is defined and vmware_ssh | bool) when: hypervisor == "vmware" and (vmware_ssh is defined and vmware_ssh | bool)
block: block:
- name: Allow empty passwords temporarily - name: Allow login
ansible.builtin.replace: ansible.builtin.replace:
path: /etc/ssh/sshd_config path: /etc/ssh/sshd_config
regexp: "^#?PermitEmptyPasswords.*" regexp: "{{ item.regexp }}"
replace: "PermitEmptyPasswords yes" replace: "{{ item.replace }}"
loop:
- name: Allow root login - regexp: "^#?PermitEmptyPasswords.*"
ansible.builtin.replace: replace: "PermitEmptyPasswords yes"
path: /etc/ssh/sshd_config - regexp: "^#?PermitRootLogin.*"
regexp: "^#?PermitRootLogin.*" replace: "PermitRootLogin yes"
replace: "PermitRootLogin yes"
- name: Reload SSH service to apply changes - name: Reload SSH service to apply changes
ansible.builtin.service: ansible.builtin.service:
name: sshd name: sshd
state: reloaded state: reloaded
- name: Set connection back to SSH - name: Set SSH connection for VMware
ansible.builtin.set_fact: ansible.builtin.set_fact:
ansible_connection: ssh ansible_connection: ssh
ansible_user: "root" ansible_user: root
ansible_password: ""
ansible_become_password: ""
ansible_ssh_extra_args: "-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no"
- name: Speed-up Bootstrap process - name: Prepare installer environment
ansible.builtin.lineinfile:
path: /etc/pacman.conf
regexp: ^#ParallelDownloads =
line: ParallelDownloads = 20
- name: Wait for Pacman
ansible.builtin.wait_for:
timeout: 15
- name: Setup Pacman
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] }
when: "'os' not in item or os in item.os"
retries: 4
delay: 15
- name: Prepare /iso mount and repository for RHEL-based systems
when: os | lower in ["rhel8", "rhel9", "rhel10"]
block: block:
- name: Create /iso directory - name: Speed-up Bootstrap process
ansible.builtin.file: when: not (custom_iso | default(false) | bool)
path: /usr/local/install/redhat/dvd ansible.builtin.lineinfile:
state: directory path: /etc/pacman.conf
mode: "0755" regexp: ^#ParallelDownloads =
line: ParallelDownloads = 20
- name: Mount RHEL ISO - name: Wait for pacman lock to be released
ansible.posix.mount: when: not (custom_iso | default(false) | bool)
src: "{{ '/dev/sr1' if hypervisor == 'vmware' else '/dev/sr2' }}" ansible.builtin.wait_for:
path: /usr/local/install/redhat/dvd path: /var/lib/pacman/db.lck
fstype: iso9660 state: absent
opts: "ro,loop" timeout: 120
state: mounted changed_when: false
- name: Configure RHEL Repos for installation - name: Setup Pacman
when: os | lower in ["almalinux", "fedora", "rhel8", "rhel9", "rhel10", "rocky"] when:
block: - not (custom_iso | default(false) | bool)
- name: Create directories for repository files and RPM GPG keys - "'os' not in item or os in item.os"
ansible.builtin.file: community.general.pacman:
path: /etc/yum.repos.d update_cache: true
state: directory force: true
mode: "0755" 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]}
retries: 4
delay: 15
- name: Create RHEL repository file - name: Prepare /iso mount and repository for RHEL-based systems
ansible.builtin.template: when: os | lower in ["rhel8", "rhel9", "rhel10"]
src: "{{ os | lower }}.repo.j2" block:
dest: /etc/yum.repos.d/{{ os | lower }}.repo - name: Create /iso directory
mode: "0644" ansible.builtin.file:
path: /usr/local/install/redhat/dvd
state: directory
mode: "0755"
- name: Mount RHEL ISO
ansible.posix.mount:
src: "{{ '/dev/sr1' if hypervisor == 'vmware' else '/dev/sr2' }}"
path: /usr/local/install/redhat/dvd
fstype: iso9660
opts: "ro,loop"
state: mounted
- name: Configure RHEL Repos for installation
when: is_rhel | default(false)
block:
- name: Create directories for repository files and RPM GPG keys
ansible.builtin.file:
path: /etc/yum.repos.d
state: directory
mode: "0755"
- name: Create RHEL repository file
ansible.builtin.template:
src: "{{ os | lower }}.repo.j2"
dest: /etc/yum.repos.d/{{ os | lower }}.repo
mode: "0644"