Files
ansible-upi-bare-metal/deploy-lab.yml
T
2026-08-21 17:12:46 -07:00

287 lines
10 KiB
YAML

---
# ==============================================================================
# PLAY 1: Download RHCOS PXE Boot Artifacts
# ==============================================================================
- name: Phase 1 - Download RHCOS PXE Boot Artifacts
hosts: localhost
connection: local
gather_facts: false
vars:
boot_artifacts_dir: "{{ playbook_dir }}/boot-artifacts"
ocp_stable_release_url: "https://mirror.openshift.com/pub/openshift-v4/x86_64/clients/ocp/stable/release.txt"
rhcos_base_mirror: "https://mirror.openshift.com/pub/openshift-v4/x86_64/dependencies/rhcos"
tasks:
- name: Fetch latest stable release metadata
ansible.builtin.uri:
url: "{{ ocp_stable_release_url }}"
return_content: true
register: stable_release_info
- name: Extract major.minor version
ansible.builtin.set_fact:
ocp_major_minor: "{{ stable_release_info.content | regex_search('Name:\\s+([0-9]+\\.[0-9]+)', '\\1') | first }}"
- name: Set dynamic mirror URL
ansible.builtin.set_fact:
rhcos_base_url: "{{ rhcos_base_mirror }}/{{ ocp_major_minor }}/latest"
- name: Fetch sha256sums metadata into memory
ansible.builtin.uri:
url: "{{ rhcos_base_url }}/sha256sum.txt"
return_content: true
register: sha256_info
- name: Parse artifact filenames from in-memory checksums
ansible.builtin.set_fact:
rhcos_kernel_file: "{{ sha256_info.content | regex_search('rhcos-[^\\s]+live-kernel[^\\s]*') }}"
rhcos_initramfs_file: "{{ sha256_info.content | regex_search('rhcos-[^\\s]+live-initramfs[^\\s]*') }}"
rhcos_rootfs_file: "{{ sha256_info.content | regex_search('rhcos-[^\\s]+live-rootfs[^\\s]*') }}"
- name: Ensure target boot-artifacts directory exists
ansible.builtin.file:
path: "{{ boot_artifacts_dir }}"
state: directory
mode: '0755'
- name: Download only the 3 RHCOS PXE boot artifacts
ansible.builtin.get_url:
url: "{{ rhcos_base_url }}/{{ item }}"
dest: "{{ boot_artifacts_dir }}/{{ item }}"
mode: '0644'
loop:
- "{{ rhcos_kernel_file }}"
- "{{ rhcos_initramfs_file }}"
- "{{ rhcos_rootfs_file }}"
# ==============================================================================
# PLAY 2: Generate OpenShift Ignitions and MAC-Specific GRUB PXE Configs
# ==============================================================================
- name: Phase 2 - Generate Ignition Configs and GRUB PXE Files
hosts: localhost
connection: local
gather_facts: false
vars:
# Cluster Parameters
cluster_name: "ocp"
base_domain: "lab.cudanet.org"
# Directory Paths
work_dir: "{{ playbook_dir }}/ocp-install"
templates_dir: "{{ playbook_dir }}/templates"
vault_dir: "{{ playbook_dir }}/vault_vars"
boot_artifacts_dir: "{{ playbook_dir }}/boot-artifacts"
# PXE HTTP Endpoints
pxe_base_url: "https://opnsense.lab.cudanet.org/pxeboot/lab"
pxe_url_path: "images/lab"
# OpenShift Installer URL
ocp_installer_url: "https://mirror.openshift.com/pub/openshift-v4/x86_64/clients/ocp/stable/openshift-install-linux.tar.gz"
ocp_stable_release_url: "https://mirror.openshift.com/pub/openshift-v4/x86_64/clients/ocp/stable/release.txt"
rhcos_base_mirror: "https://mirror.openshift.com/pub/openshift-v4/x86_64/dependencies/rhcos"
vars_files:
- "{{ vault_dir }}/pull-secret.yml"
- "{{ vault_dir }}/ssh-key.yml"
tasks:
- name: Ensure working directory exists
ansible.builtin.file:
path: "{{ work_dir }}"
state: directory
mode: '0755'
- name: Download and unarchive openshift-install binary directly
ansible.builtin.unarchive:
src: "{{ ocp_installer_url }}"
dest: "{{ work_dir }}"
remote_src: true
creates: "{{ work_dir }}/openshift-install"
- name: Generate install-config.yaml from Jinja2 template
ansible.builtin.template:
src: "{{ templates_dir }}/install-config.yaml.j2"
dest: "{{ work_dir }}/install-config.yaml"
mode: '0600'
- name: Backup install-config.yaml before consumption
ansible.builtin.copy:
src: "{{ work_dir }}/install-config.yaml"
dest: "{{ work_dir }}/install-config.yaml.bak"
mode: '0600'
force: true
- name: Generate OpenShift ignition configs
ansible.builtin.command:
cmd: "./openshift-install create ignition-configs --dir=."
chdir: "{{ work_dir }}"
creates: "{{ work_dir }}/bootstrap.ign"
- name: Find generated ignition files
ansible.builtin.find:
paths: "{{ work_dir }}"
patterns: "*.ign"
register: found_ignition_files
- name: Move ignition configs to ./boot-artifacts directory
ansible.builtin.copy:
src: "{{ item.path }}"
dest: "{{ boot_artifacts_dir }}/{{ item.path | basename }}"
remote_src: true
mode: '0644'
loop: "{{ found_ignition_files.files }}"
- name: Clean up original ignition files from work directory
ansible.builtin.file:
path: "{{ item.path }}"
state: absent
loop: "{{ found_ignition_files.files }}"
- name: Fetch latest release metadata for GRUB variable parsing
ansible.builtin.uri:
url: "{{ ocp_stable_release_url }}"
return_content: true
register: stable_release_info
- name: Extract OpenShift version facts
ansible.builtin.set_fact:
ocp_latest_version: "{{ stable_release_info.content | regex_search('Name:\\s+([0-9]+\\.[0-9]+\\.[0-9]+)', '\\1') | first }}"
ocp_major_minor: "{{ stable_release_info.content | regex_search('Name:\\s+([0-9]+\\.[0-9]+)', '\\1') | first }}"
- name: Fetch sha256sums metadata into memory
ansible.builtin.uri:
url: "{{ rhcos_base_mirror }}/{{ ocp_major_minor }}/latest/sha256sum.txt"
return_content: true
register: sha256_info
- name: Parse artifact filenames for GRUB rendering
ansible.builtin.set_fact:
rhcos_kernel_file: "{{ sha256_info.content | regex_search('rhcos-[^\\s]+live-kernel[^\\s]*') }}"
rhcos_initramfs_file: "{{ sha256_info.content | regex_search('rhcos-[^\\s]+live-initramfs[^\\s]*') }}"
rhcos_rootfs_file: "{{ sha256_info.content | regex_search('rhcos-[^\\s]+live-rootfs[^\\s]*') }}"
- name: Generate GRUB PXE configs for each MAC address
ansible.builtin.template:
src: "{{ templates_dir }}/grub.cfg.j2"
dest: "{{ boot_artifacts_dir }}/grub.cfg-{{ node.mac }}"
mode: '0644'
loop:
- { mac: "01-52-54-00-bc-74-35", role: "bootstrap" }
- { mac: "01-98-b7-85-25-30-f5", role: "control-plane", disk_path: "pci-0000:02:00.0-nvme-1" }
- { mac: "01-98-b7-85-25-2c-a7", role: "control-plane", disk_path: "pci-0000:02:00.0-nvme-1" }
- { mac: "01-98-b7-85-25-2c-25", role: "control-plane", disk_path: "pci-0000:02:00.0-nvme-1" }
- { mac: "01-98-b7-85-25-2c-ab", role: "compute-node", disk_path: "pci-0000:02:00.0-nvme-1" }
- { mac: "01-98-b7-85-25-34-2b", role: "compute-node", disk_path: "pci-0000:03:00.0-nvme-1" }
- { mac: "01-98-b7-85-25-30-b7", role: "compute-node", disk_path: "pci-0000:02:00.0-nvme-1" }
loop_control:
loop_var: node
# ==============================================================================
# PLAY 3: Setup Local Temporary Private Key
# ==============================================================================
- name: Phase 3a - Write Private SSH Key for OPNSense Access
hosts: localhost
connection: local
gather_facts: false
vars:
vault_dir: "{{ playbook_dir }}/vault_vars"
vars_files:
- "{{ vault_dir }}/ssh-key.yml"
tasks:
- name: Write vaulted private key to temporary file
ansible.builtin.copy:
content: "{{ vault_ssh_private_key }}"
dest: "/tmp/opnsense_ssh_key"
mode: '0600'
# ==============================================================================
# PLAY 4: Deploy Boot Artifacts to OPNSense PXE Server
# ==============================================================================
- name: Phase 3b - Deploy PXE Boot Artifacts to OPNSense
hosts: opnsense.lab.cudanet.org
remote_user: root
gather_facts: false
vars:
local_artifacts_dir: "{{ playbook_dir }}/boot-artifacts"
tftp_root_dir: "/usr/local/tftp"
tftp_images_dir: "/usr/local/tftp/images/lab"
www_lab_dir: "/usr/local/www/pxeboot/lab"
ansible_python_interpreter: "/usr/local/bin/python3"
ansible_ssh_private_key_file: "/tmp/opnsense_ssh_key"
tasks:
- name: Ensure target directories exist on OPNSense
ansible.builtin.file:
path: "{{ item }}"
state: directory
mode: '0755'
loop:
- "{{ tftp_root_dir }}"
- "{{ tftp_images_dir }}"
- "{{ www_lab_dir }}"
- name: Deploy GRUB configs to TFTP root
ansible.builtin.copy:
src: "{{ item }}"
dest: "{{ tftp_root_dir }}/{{ item | basename }}"
mode: '0644'
with_fileglob:
- "{{ local_artifacts_dir }}/grub.cfg-*"
- name: Deploy Ignition files to WWW directory
ansible.builtin.copy:
src: "{{ item }}"
dest: "{{ www_lab_dir }}/{{ item | basename }}"
mode: '0644'
with_fileglob:
- "{{ local_artifacts_dir }}/*.ign"
- name: Deploy RHCOS Live RootFS to WWW directory
ansible.builtin.copy:
src: "{{ item }}"
dest: "{{ www_lab_dir }}/{{ item | basename }}"
mode: '0644'
with_fileglob:
- "{{ local_artifacts_dir }}/*live-rootfs*"
- name: Deploy RHCOS Live Kernel to TFTP images directory
ansible.builtin.copy:
src: "{{ item }}"
dest: "{{ tftp_images_dir }}/{{ item | basename }}"
mode: '0644'
with_fileglob:
- "{{ local_artifacts_dir }}/*live-kernel*"
- name: Deploy RHCOS Live Initramfs to TFTP images directory
ansible.builtin.copy:
src: "{{ item }}"
dest: "{{ tftp_images_dir }}/{{ item | basename }}"
mode: '0644'
with_fileglob:
- "{{ local_artifacts_dir }}/*live-initramfs*"
# ==============================================================================
# PLAY 5: Cleanup Local Temporary Private Key
# ==============================================================================
- name: Phase 3c - Cleanup Private SSH Key File
hosts: localhost
connection: local
gather_facts: false
tasks:
- name: Remove temporary private SSH key file
ansible.builtin.file:
path: "/tmp/opnsense_ssh_key"
state: absent