Add RHEL8 and RHEL9 support

This commit is contained in:
Sandwich 2024-10-30 00:29:46 +01:00
parent f8ba5c41db
commit 147430b36e
16 changed files with 176 additions and 60 deletions

View File

@ -6,8 +6,9 @@ An Ansible playbook for automating system bootstrap processes in an Infrastructu
Most of the roles are adaptable for use with systems beyond ArchLinux, requiring only that the target system can install a necessary package manager, such as `dnf` for RHEL-based systems. Additionally, a replacement for the `arch-chroot` command may be required for these systems.
**NOTE**:
- RHEL Systems are not currently supported due to restricted access to their repositories.
A workaround could involve using an ISO as a local repository or setting up a proxy repository to facilitate access.
- For RHEL 8 and RHEL 9, repository access requires the `rhel_iso` variable. This variable specifies a local ISO or proxy repository.
- RHEL systems do not support `btrfs`. Use `ext4` or `xfs` as alternatives.
- For RHEL 8, `xfs` may cause installation issues; `ext4` is recommended.
# Supported Distributions
@ -20,11 +21,12 @@ This playbook supports multiple Linux distributions with specific versions tailo
| debian11 | Debian 11 (Bullseye) |
| debian12 | Debian 12 (Bookworm) |
| fedora | Fedora 41 |
| rhel8 | Red Hat Enterprise Linux 8 |
| rhel9 | Red Hat Enterprise Linux 9 |
| rocky | Rocky Linux 9.x |
| ubuntu | Ubuntu 24.10 (Oracular Oriole) |
| ubuntu-lts | Ubuntu 24.04 LTS (Noble Numbat) |
# Documentation
## Table of Contents
@ -48,6 +50,7 @@ Global variables apply across your Ansible project and are loaded from `vars.yml
| Variable | Description | Example Value |
|-----------------------|--------------------------------------------------------------------|-----------------------------------------|
| `boot_iso` | Path to the boot ISO image. | `local-btrfs:iso/archlinux-x86_64.iso` |
| `rhel_iso` | Path to the RHEL ISO file, required for RHEL 8 and RHEL 9. |`local-btrfs:iso/rhel-9.4-x86_64-dvd.iso`|
| `hypervisor` | Type of hypervisor. | `libvirt`, `proxmox`, `vmware`, `none` |
| `hypervisor_cluster` | Name of the hypervisor cluster. | `default-cluster` |
| `hypervisor_node` | Hypervisor node name. | `node01` |

View File

@ -17,8 +17,8 @@ all:
192.168.122.11:
hostname: database
vm_id: 101
os: archlinux
filesystem: btrfs
os: rhel9
filesystem: xfs
vm_memory: "6144"
vm_ballo: "3072"
vm_cpus: "4"
@ -26,3 +26,4 @@ all:
vm_nif: vmbr1
vm_gw: 192.168.122.1
vm_dns: 1.1.1.1
rhel_iso: "local-btrfs:iso/rhel-9.4-x86_64-dvd.iso"

View File

@ -47,7 +47,8 @@
that:
- hypervisor in ["libvirt", "proxmox", "vmware", "none"]
- filesystem in ["btrfs", "ext4", "xfs"]
- os in ["archlinux", "almalinux", "debian11", "debian12", "fedora", "rocky", "ubuntu", "ubuntu-lts"]
- os in ["archlinux", "almalinux", "debian11", "debian12", "fedora", "rhel8", "rhel9", "rocky", "ubuntu", "ubuntu-lts"]
- os not in ["rhel8", "rhel9"] or rhel_iso is defined
fail_msg: Invalid input specified, please try again
- name: Set connection

View File

@ -64,16 +64,43 @@
changed_when: result.rc == 0
register: result
with_items:
- dnf --releasever=9 --best --repo=rocky-baseos --installroot=/mnt --setopt=install_weak_deps=False groupinstall -y base core
- 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/systemd/resolve/resolv.conf /mnt/etc/resolv.conf
- arch-chroot /mnt dnf --releasever=9 --setopt=install_weak_deps=False install -y {{ role_packages.rocky | join(' ') }}
- name: Bootstrap RHEL System
when: os | lower in ['rhel8', 'rhel9']
ansible.builtin.command: "{{ item }}"
changed_when: result.rc == 0
register: result
with_items:
- dnf --releasever={{ '8' if os == 'rhel8' else '9' }} --installroot=/mnt --setopt=install_weak_deps=False groupinstall -y base core
- ln -sf /run/systemd/resolve/resolv.conf /mnt/etc/resolv.conf
- arch-chroot /mnt dnf --releasever={{ '8' if os == 'rhel8' else '9' }} --setopt=install_weak_deps=False install -y {{ role_packages[os] | join(' ') }}
block:
- name: Install base packages in chroot environment
ansible.builtin.command: >-
dnf --releasever={{ '8' if os == 'rhel8' else '9' }} --repo={{ os | lower }}-baseos
--installroot=/mnt
--setopt=install_weak_deps=False --setopt=optional_metadata_types=filelists
groupinstall -y base core
changed_when: result.rc == 0
register: result
- name: Prepare chroot environment
ansible.builtin.shell: |
ln -sf /run/systemd/resolve/resolv.conf /mnt/etc/resolv.conf
mkdir -p /mnt/usr/local/install/redhat/dvd
mount --bind /usr/local/install/redhat/dvd /mnt/usr/local/install/redhat/dvd
arch-chroot /mnt rpm --rebuilddb
changed_when: result.rc == 0
register: result
- name: Copy RHEL repo file into chroot environment
ansible.builtin.copy:
src: /etc/yum.repos.d/{{ os | lower }}.repo
dest: /mnt/etc/yum.repos.d/{{ os | lower }}.repo
mode: '0644'
remote_src: true
- name: Install additional packages in chroot
ansible.builtin.command: >-
arch-chroot /mnt dnf --releasever={{ '8' if os == 'rhel8' else '9' }}
--setopt=install_weak_deps=False install -y {{ role_packages[os] | join(' ') }}
changed_when: result.rc == 0
register: result

View File

@ -172,7 +172,7 @@ rhel8:
- dhcp-client
- efibootmgr
- grub2
- grub2-efi
- grub2-efi-x64
- lrzsz
- lvm2
- nfs-utils

View File

@ -91,8 +91,8 @@
- { 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 os in ["almalinux", "fedora", "rocky"] else "bash.bashrc" }}', content: umask 077 }
- { path: '/mnt/etc/{{ "bashrc" if os in ["almalinux", "fedora", "rocky"] else "bash.bashrc" }}', content: export TMOUT=3000 }
- { path: '/mnt/etc/{{ "bashrc" if os in ["almalinux", "fedora", "rhel8", "rhel9", "rocky"] else "bash.bashrc" }}', content: umask 077 }
- { path: '/mnt/etc/{{ "bashrc" if os in ["almalinux", "fedora", "rhel8", "rhel9", "rocky"] 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 }
@ -112,18 +112,21 @@
owner: "{{ item.owner | default(omit) }}"
group: "{{ item.group | default(omit) }}"
mode: "{{ item.mode }}"
loop:
- { path: /mnt/etc/ssh/sshd_config, mode: "0600" }
- { path: /mnt/etc/cron.hourly, mode: "0700" }
- { path: /mnt/etc/cron.daily, mode: "0700" }
- { path: /mnt/etc/cron.weekly, mode: "0700" }
- { path: /mnt/etc/cron.monthly, mode: "0700" }
- { 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: "754" }
- { path: '/mnt/usr/bin/{{ "fusermount3" if os in ["archlinux", "debian12", "fedora", "rocky", "almalinux"] else "fusermount" }}', mode: "755" }
- { path: '/mnt/usr/bin/{{ "write.ul" if os == "debian11" else "write" }}', mode: "755" }
loop: >
{{ [
{ "path": "/mnt/etc/ssh/sshd_config", "mode": "0600" },
{ "path": "/mnt/etc/cron.hourly", "mode": "0700" },
{ "path": "/mnt/etc/cron.daily", "mode": "0700" },
{ "path": "/mnt/etc/cron.weekly", "mode": "0700" },
{ "path": "/mnt/etc/cron.monthly", "mode": "0700" },
{ "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"] else None,
{ "path": "/mnt/usr/bin/" + ("fusermount3" if os in ["almalinux", "archlinux", "debian12", "fedora", "rhel9", "rocky"]
else "fusermount"), "mode": "755" },
{ "path": "/mnt/usr/bin/" + ("write.ul" if os == "debian11" else "write"), "mode": "755" }
] | reject("none") }}
- name: Adjust SSHD config
ansible.builtin.lineinfile:

View File

@ -15,7 +15,7 @@
state: absent
loop:
- ide0
- ide1
- ide2
- name: Remove CD-ROM from VM in vCenter
when: hypervisor == "vmware"
@ -30,7 +30,7 @@
name: "{{ hostname }}"
cdrom:
- controller_number: 0
unit_number: 0
unit_number: 1
controller_type: sata
type: iso
iso_path: "{{ boot_iso }}"
@ -63,7 +63,7 @@
- name: Remove CD-ROM devices
when: cdrom_devices.stdout_lines | length > 0
ansible.builtin.command: virsh --connect qemu:///system detach-disk {{ hostname }} {{ item }} --persistent
with_items: "{{ cdrom_devices.stdout_lines }}"
with_items: "{{ cdrom_devices.stdout_lines | select('ne', 'sdc') | list }}"
changed_when: result.rc == 0
register: result

View File

@ -6,6 +6,22 @@
changed_when: result.rc == 0
register: result
- name: Remove depricated attr2 and disable large extent
when: os in ["almalinux", "rhel8", "rhel9", "rocky"] and filesystem == "xfs"
ansible.builtin.replace:
path: /mnt/etc/fstab
regexp: '(xfs.*?)(attr2)'
replace: '\1allocsize=64m'
- name: Replace ISO UUID entry with /dev/sr0 in fstab
when: os in ["rhel8", "rhel9"]
ansible.builtin.lineinfile:
path: /mnt/etc/fstab
regexp: '^.*\/dvd.*$'
line: "{{ '/dev/loop0' if hypervisor == 'vmware' else '/dev/sr0' }} /usr/local/install/redhat/dvd iso9660 ro,relatime,nojoliet,check=s,map=n 0 0"
state: present
backrefs: true
- name: Append TempFS to fstab
ansible.builtin.lineinfile:
path: /mnt/etc/fstab
@ -74,12 +90,18 @@
replace: PasswordAuthentication yes
- name: Enable Systemd Services
block:
- name: Enable sshd
when: os | lower == "archlinux"
ansible.builtin.command: arch-chroot /mnt systemctl enable sshd logrotate systemd-resolved systemd-timesyncd systemd-networkd NetworkManager
changed_when: result.rc == 0
register: result
ansible.builtin.command: >
arch-chroot /mnt systemctl enable NetworkManager
{{
' ssh' if os | lower in ['ubuntu', 'ubuntu-lts'] else
(' sshd' if os | lower not in ['debian11', 'debian12'] else '')
}}
{{
'logrotate systemd-resolved systemd-timesyncd systemd-networkd'
if os | lower == 'archlinux' else ''
}}
changed_when: result.rc == 0
register: result
- name: Configure grub
when: os | lower not in ['almalinux', 'fedora', 'rhel8', 'rhel9', 'rocky']
@ -101,7 +123,8 @@
- name: Install Bootloader
ansible.builtin.command: arch-chroot /mnt
{% if os | lower not in ["archlinux", "debian11", "debian12", "ubuntu", "ubuntu-lts"] %} /usr/sbin/efibootmgr
-c -L '{{ os }}' -d "{{ install_drive }}" -p 1 -l '\efi\EFI\{{ os }}\shimx64.efi'
-c -L '{{ os }}' -d "{{ install_drive }}" -p 1
-l '\efi\EFI\{% if os | lower in ["rhel8", "rhel9"] %}redhat{% else %}{{ os | lower }}{% endif %}\shimx64.efi'
{% else %}/usr/sbin/grub-install --target=x86_64-efi --efi-directory={{ "/boot/efi" if os | lower in ["ubuntu", "ubuntu-lts"] else "/boot" }}
--bootloader-id={{ "ubuntu" if os | lower in ["ubuntu", "ubuntu-lts"] else os }}
{% endif %}
@ -110,10 +133,10 @@
- name: Generate grub config
ansible.builtin.command: arch-chroot /mnt
{% if os | lower not in ["archlinux", "debian11", "debian12", "ubuntu", "ubuntu-lts"] %} /usr/sbin/grub2-mkconfig
-o /boot/efi/EFI/{{ os }}/grub.cfg
{% else %}/usr/sbin/grub-mkconfig -o
{{ "/boot/efi/EFI/ubuntu/grub.cfg" if os | lower in ["ubuntu", "ubuntu-lts"] else "/boot/grub/grub.cfg" }}
{% if os | lower not in ["archlinux", "debian11", "debian12", "ubuntu", "ubuntu-lts"] %}
/usr/sbin/grub2-mkconfig -o /boot/efi/EFI/{% if os | lower in ["rhel8", "rhel9"] %}redhat{% else %}{{ os | lower }}{% endif %}/grub.cfg
{% else %}
/usr/sbin/grub-mkconfig -o {{ "/boot/efi/EFI/ubuntu/grub.cfg" if os | lower in ["ubuntu", "ubuntu-lts"] else "/boot/grub/grub.cfg" }}
{% endif %}
changed_when: result.rc == 0
register: result
@ -214,7 +237,7 @@
block:
- name: Relabel the filesystem
when: os | lower in ['almalinux', 'rhel8', 'rhel9', 'rocky']
ansible.builtin.command: touch /mnt/.autorelabel
ansible.builtin.command: "arch-chroot /mnt /sbin/fixfiles onboot"
changed_when: result.rc == 0
register: result

View File

@ -69,8 +69,25 @@
retries: 4
delay: 15
- name: Prepare /iso mount and repository for RHEL-based systems
when: os | lower in ["rhel8", "rhel9"]
block:
- name: Create /iso directory
ansible.builtin.file:
path: /usr/local/install/redhat/dvd
state: directory
mode: '0755'
- name: Mount RHEL ISO
ansible.posix.mount:
src: /dev/sr2
path: /usr/local/install/redhat/dvd
fstype: iso9660
opts: "ro,loop"
state: mounted
- name: Configure RHEL Repos for installation
when: os | lower in ["almalinux", "fedora", "rocky"]
when: os | lower in ["almalinux", "fedora", "rhel8", "rhel9", "rocky"]
block:
- name: Create directories for repository files and RPM GPG keys
ansible.builtin.file:

View File

@ -55,7 +55,7 @@
community.general.filesystem:
dev: "{{ install_drive }}{{ boot_partition_suffix }}"
fstype: vfat
opts: -F32
opts: -F32 -n BOOT
force: true
- name: Create filesystem
@ -136,7 +136,7 @@
- name: Mount boot filesystem
ansible.posix.mount:
path: "{{ '/mnt/boot/efi' if os | lower in ['ubuntu', 'ubuntu-lts'] else '/mnt/boot' }}"
path: "{{ '/mnt/boot/efi' if os | lower in ['rhel8', 'ubuntu', 'ubuntu-lts'] else '/mnt/boot' }}"
src: UUID={{ boot_uuid.stdout }}
fstype: vfat
state: mounted

View File

@ -8,20 +8,20 @@
ciuser: "{{ user_name }}"
cipassword: "{{ user_password }}"
ciupgrade: false
node: "{{ hypervisor_node }}" # Proxmox node name
vmid: "{{ vm_id }}" # Unique ID for the VM
name: "{{ hostname }}" # Name of the VM
node: "{{ hypervisor_node }}"
vmid: "{{ vm_id }}"
name: "{{ hostname }}"
cpu: host
cores: "{{ vm_cpus }}" # Number of CPU cores
memory: "{{ vm_memory }}" # Memory size in MB
balloon: "{{ vm_ballo | default(omit) }}" # Minimum Memory size in MB
cores: "{{ vm_cpus }}"
memory: "{{ vm_memory }}"
balloon: "{{ vm_ballo | default(omit) }}"
numa_enabled: true
hotplug: network,disk
bios: ovmf
boot: ac
scsihw: virtio-scsi-single
scsi:
scsi0: "{{ hypervisor_storage }}:{{ vm_size }}" # Disk configuration
scsi0: "{{ hypervisor_storage }}:{{ vm_size }}"
efidisk0:
efitype: 4m
format: raw
@ -29,14 +29,15 @@
storage: "{{ hypervisor_storage }}"
ide:
ide0: "{{ boot_iso }},media=cdrom"
ide1: "{{ hypervisor_storage }}:cloudinit"
ide1: "{{ rhel_iso | default(omit) }},media=cdrom"
ide2: "{{ hypervisor_storage }}:cloudinit"
net:
net0: virtio,bridge={{ vm_nif }}{% if vlan_name is defined and vlan_name %},tag={{ vlan_name }}{% endif %}
ipconfig:
ipconfig0: ip={{ vm_ip }},gw={{ vm_gw }}
nameservers: "{{ vm_dns }}"
onboot: true # Start the VM on boot
state: present # Ensure the VM is present
onboot: true
state: present
- name: Start VM on Proxmox
delegate_to: localhost
@ -47,4 +48,4 @@
node: "{{ hypervisor_node }}"
name: "{{ hostname }}"
vmid: "{{ vm_id }}"
state: started # Ensure the VM is present
state: started

View File

@ -26,6 +26,12 @@
controller_type: sata
state: present
type: iso
iso_path: "{{ rhel_iso | default(omit) }}"
- controller_number: 0
unit_number: 1
controller_type: sata
state: present
type: iso
iso_path: "{{ boot_iso }}"
networks:
- vlan: "{{ vlan_name }}"

View File

@ -37,6 +37,13 @@
<source file="{{ vm_path | default('/var/lib/libvirt/images/') }}{{ hostname }}-cloudinit.iso"/>
<target dev="sdb" bus="sata"/>
</disk>
{% if rhel_iso is defined %}
<disk type="file" device="cdrom">
<driver name="qemu" type="raw"/>
<source file="{{ rhel_iso }}"/>
<target dev="sdc" bus="sata"/>
</disk>
{% endif %}
<interface type='network'>
<mac address="{{ mac_address_output.stdout }}"/>
<source network='default'/>

13
templates/rhel8.repo.j2 Normal file
View File

@ -0,0 +1,13 @@
[rhel8-baseos]
name=RHEL 8 BaseOS
baseurl=file:///usr/local/install/redhat/dvd/BaseOS
enabled=1
gpgcheck=0
gpgkey=file:///usr/local/install/redhat/dvd/RPM-GPG-KEY-redhat-release
[rhel8-appstream]
name=RHEL 8 AppStream
baseurl=file:///usr/local/install/redhat/dvd/AppStream
enabled=1
gpgcheck=0
gpgkey=file:///usr/local/install/redhat/dvd/RPM-GPG-KEY-redhat-release

13
templates/rhel9.repo.j2 Normal file
View File

@ -0,0 +1,13 @@
[rhel9-baseos]
name=RHEL 9 BaseOS
baseurl=file:///usr/local/install/redhat/dvd/BaseOS
enabled=1
gpgcheck=0
gpgkey=file:///usr/local/install/redhat/dvd/RPM-GPG-KEY-redhat-release
[rhel9-appstream]
name=RHEL 9 AppStream
baseurl=file:///usr/local/install/redhat/dvd/AppStream
enabled=1
gpgcheck=0
gpgkey=file:///usr/local/install/redhat/dvd/RPM-GPG-KEY-redhat-release

View File

@ -13,3 +13,4 @@ hypervisor_password: "SomePassword"
hypervisor_node: "NodeName"
hypervisor_storage: "local-btrfs"
boot_iso: "local-btrfs:iso/archlinux-x86_64.iso"
rhel_iso: "local-btrfs:rhel-9.4-x86_64-dvd.iso"