feat: Add VFIO binding script and update playbook for enhanced virtualization support

This commit is contained in:
2026-01-02 23:15:08 +01:00
parent 03d5b39a4b
commit 3c6647c215
13 changed files with 540 additions and 135 deletions
+1
View File
@@ -0,0 +1 @@
ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAHHOPBR9p9kq5Cqzpe4cr3jHnweaYrHPXv5sXNzt+sCXP54uc5rWUBhxW2OQVvQzJ47dEVhEKi4WSC7LcuKS2G5AQDzWXNiasHvYIYQU3F/EknVCZnsiXYqXphYkJA6rJCNRnISZCIC1mocq6PB7J08ONdRFCvjfUBuVRT8BNGXNmQ/zQ==
+31
View File
@@ -0,0 +1,31 @@
#!/bin/bash
DEV="$1"
VENDOR="$2"
DEVICE="$3"
if [ -z "$DEV" ] || [ -z "$VENDOR" ] || [ -z "$DEVICE" ]; then
echo "Usage: $0 <PCI_DEVICE_ID> <VENDOR_ID> <DEVICE_ID>"
echo "Example: $0 0000:3b:00.0 8086 1520"
exit 1
fi
# Wait until device exists
for i in {1..20}; do
[ -e /sys/bus/pci/devices/$DEV ] && break
sleep 0.5
done
# Unbind from current driver
logger -t vfio-bind "Binding device $DEV (vendor: $VENDOR, device: $DEVICE) to vfio-pci"
if [ -L /sys/bus/pci/devices/$DEV/driver ]; then
logger -t vfio-bind "Unbinding device $DEV from current driver"
echo "$DEV" > /sys/bus/pci/devices/$DEV/driver/unbind
fi
# Tell kernel to prefer vfio-pci
logger -t vfio-bind "Setting driver override to vfio-pci for device $DEV"
echo vfio-pci > /sys/bus/pci/devices/$DEV/driver_override
# Bind to vfio-pci
logger -t vfio-bind "Binding device $DEV to vfio-pci driver"
echo "$DEV" > /sys/bus/pci/drivers/vfio-pci/bind
+204 -106
View File
@@ -1,6 +1,24 @@
hostname: vh-01.lab.alexpires.me hostname: vh-01.lab.alexpires.me
ansible_user: "{{ lookup('env', 'ANSIBLE_USER') }}" ansible_user: "{{ lookup('env', 'ANSIBLE_USER') }}"
packages_blocklist:
- apport*
- autofs
- beep
- git
- pastebinit
- popularity-contest
- prelink
- rpcbind
- rsh*
- talk*
- telnet*
- tftp*
- whoopsie
- xinetd
- yp-tools
- ypbind
# Users # Users
login_users: login_users:
- username: "{{ ansible_user }}" - username: "{{ ansible_user }}"
@@ -36,7 +54,7 @@ ufw_enable: true
fw_allowed_ports: fw_allowed_ports:
- { rule: "allow", port: "22", proto: "tcp", from: "10.5.5.5/32" } # Wireguard VPN (Laptop) - { rule: "allow", port: "22", proto: "tcp", from: "10.5.5.5/32" } # Wireguard VPN (Laptop)
- { rule: "allow", port: "22", proto: "tcp", from: "10.19.4.0/24" } # local network - { rule: "allow", port: "22", proto: "tcp", from: "10.19.4.0/24" } # local network
- { rule: "allow", port: "9090", proto: "tcp" } - { rule: "allow", port: "9090", proto: "tcp", from: "10.19.4.0/24" } # local network
ufw_outgoing_traffic: ufw_outgoing_traffic:
- 22 # SSH - 22 # SSH
@@ -53,6 +71,14 @@ ipv4_sysctl_settings:
disable_ipv6: true disable_ipv6: true
# Network Bridge Configuration
bridge_name: "br0"
bridge_interface: "{{ ansible_default_ipv4.interface }}" # Auto-detect primary interface
bridge_ipv4_address: "10.19.4.254/24" # Adjust to your static IP
bridge_ipv4_gateway: "10.19.4.1"
bridge_ipv4_dns: "10.19.4.1,1.1.1.1"
bridge_ipv4_domain: "lab.alexpires.me"
# geoip will override hosts_allow and hosts_deny (so it's disabled - CIS hardening) # geoip will override hosts_allow and hosts_deny (so it's disabled - CIS hardening)
custom_hosts_acls: true custom_hosts_acls: true
@@ -63,31 +89,30 @@ hide_pid: 0
install_aide: false install_aide: false
# Unattended upgrades # Unattended upgrades
unattended_reboot: true unattended_reboot: false
unattended_reboot_time: "04:30" unattended_reboot_time: "04:30"
# Duo Security # Duo Security
duo_users: ["*", "!provision"] duo_users: ["*", "!provision"]
duo_api_hostname: api-7cda1654.duosecurity.com duo_api_hostname: api-7cda1654.duosecurity.com
# VMs reserved CPU (for gaming and AI) # VMs reserved CPU )
virt_vm_reserved_cpu: "1-5,7-11" virt_vm_reserved_cpu: "1-7,9-15"
virt_raw_block_devices: virt_raw_block_devices: []
- "nvme0n1"
- "nvme0n1p1" # Devices to unbind for VFIO passthrough (This are devices that will be unbound at boot with vfio-bind.sh)
- "nvme0n1p2" virt_vfio_devices:
- { dev: "0000:08:00.0", vendor: "1b73", device: "1100" } # Fresco Logic FL1100 USB 3.0 Host Controller
- { dev: "0000:05:00.0", vendor: "c0a9", device: "5415" } # Micron/Crucial Technology T500 NVMe PCIe SSD
virt_extra_grub_args: > virt_extra_grub_args: >
i915.modeset=1 i915.enable_gvt=1 i915.enable_fbc=0 rd.driver.blacklist=nouveau modprobe.blacklist=nouveau ipv6.disable=1 audit=1 audit_backlog_limit=8192
initcall_blacklist=simpledrm_platform_driver_init
rd.driver.blacklist=nouveau modprobe.blacklist=nouveau
virt_vfio_ids: virt_vfio_ids:
- 10de:2482 # NVIDIA Corporation GA104 [GeForce RTX 3070 Ti] - 10de:1430 # NVIDIA Corporation M2000 [Maxwell GM107GL]
- 10de:228b # NVIDIA Corporation GA106 High Definition Audio Controller - 10de:0fba # NVIDIA Corporation M2000 High Definition Audio Controller
- 10de:2504 # NVIDIA Corporation GA106 [GeForce RTX 3060 Lite Hash Rate]
- 10de:228e # NVIDIA Corporation GA106 High Definition Audio Controller
- 1b73:1100 # Fresco Logic FL1100 USB 3.0 Host Controller - 1b73:1100 # Fresco Logic FL1100 USB 3.0 Host Controller
- c0a9:5415 # Micron/Crucial Technology T500 NVMe PCIe SSD
virt_blacklist: virt_blacklist:
- noveau - noveau
@@ -96,15 +121,15 @@ virt_blacklist:
- mxm_wmi - mxm_wmi
virt_machines: virt_machines:
- name: windows-11 - name: win10pro
title: "Microsoft Windows 11" title: "Microsoft Windows 10 Pro"
uuid: "51d5d091-67cb-4113-bd8e-817e7317e1b4" uuid: "51d5d091-67cb-4113-bd8e-817e7317e1b4"
autostart: true autostart: false
memory: 25165824 memory: 16
cores: 4 cores: 5
threads: 2 threads: 2
physical_cpus: "2-8,3-9,4-10,5-11" physical_cpus: "3-11,4-12,5-13,6-14,7-15"
reserved_cpus: "0,6" reserved_cpus: "0,8"
enable_hyperv: true enable_hyperv: true
cdrom: true cdrom: true
console: false console: false
@@ -112,126 +137,199 @@ virt_machines:
secure_boot: true secure_boot: true
tpm: true tpm: true
tablet: true tablet: true
disk_file: "windows-11.qcow2" net_bridge: br0
disk_file: "win10pro.qcow2"
mac_address: "52:54:00:cd:dd:2d" mac_address: "52:54:00:cd:dd:2d"
block_devs: block_devs: []
- block_dev: "/dev/nvme0n1" guest_agent: true
target_dev: "sdb"
host_devs: host_devs:
# Intel MDev device for GVT-g # Micron/Crucial Technology T500 NVMe PCIe SSD
- type: "mdev" - type: "pci"
source: source:
uuid: "5abeb24f-d6f4-4666-b495-303f15b05723" address:
domain: "0x0000"
bus: "0x05"
slot: "0x00"
function: "0x0"
address: address:
{ type: "pci"
type: "pci", domain: "0x0000"
domain: "0x0000", bus: "0x11"
bus: "0x07", slot: "0x00"
slot: "0x00", function: "0x0"
function: "0x0",
}
# Fresco Logic FL1100 USB 3.0 Host Controller # Fresco Logic FL1100 USB 3.0 Host Controller
- type: "pci" - type: "pci"
source: source:
address: address:
domain: "0x0000" domain: "0x0000"
bus: "0x06" bus: "0x08"
slot: "0x00" slot: "0x00"
function: "0x0" function: "0x0"
address: address:
{ type: "pci"
type: "pci", domain: "0x0000"
domain: "0x0000", bus: "0x10"
bus: "0x10", slot: "0x00"
slot: "0x00", function: "0x0"
function: "0x0", # NVIDIA Corporation M2000 [Maxwell GM107GL]
}
# NVIDIA Corporation GA104 [GeForce RTX 3070 Ti]
- type: "pci" - type: "pci"
source: source:
address: address:
domain: "0x0000" domain: "0x0000"
bus: "0x01" bus: "0x03"
slot: "0x00" slot: "0x00"
function: "0x0" function: "0x0"
address: address:
{ type: "pci"
type: "pci", domain: "0x0000"
domain: "0x0000", bus: "0x0b"
bus: "0x0b", slot: "0x00"
slot: "0x00", function: "0x0"
function: "0x0", # NVIDIA Corporation M2000 High Definition Audio Controller
}
# NVIDIA Corporation GA106 High Definition Audio Controller
- type: "pci" - type: "pci"
source: source:
address: address:
domain: "0x0000" domain: "0x0000"
bus: "0x01" bus: "0x03"
slot: "0x00" slot: "0x00"
function: "0x1" function: "0x1"
address: address:
{ type: "pci"
type: "pci", domain: "0x0000"
domain: "0x0000", bus: "0x0f"
bus: "0x0f", slot: "0x00"
slot: "0x00", function: "0x0"
function: "0x0",
}
- name: fedora-headless - name: win11home
title: "Fedora CUDA headless" title: "Microsoft Windows 11 Home"
uuid: "51d5d091-67cb-4113-bd8e-817e7317e1b5"
autostart: false
memory: 16
cores: 5
threads: 2
physical_cpus: "3-11,4-12,5-13,6-14,7-15"
reserved_cpus: "0,8"
enable_hyperv: true
cdrom: true
console: false
audio: true
secure_boot: true
tpm: true
tablet: true
net_bridge: br0
disk_file: "win11home.qcow2"
mac_address: "52:54:00:cd:dd:2e"
block_devs: []
guest_agent: true
host_devs:
# Micron/Crucial Technology T500 NVMe PCIe SSD
- type: "pci"
source:
address:
domain: "0x0000"
bus: "0x05"
slot: "0x00"
function: "0x0"
address:
type: "pci"
domain: "0x0000"
bus: "0x11"
slot: "0x00"
function: "0x0"
# Fresco Logic FL1100 USB 3.0 Host Controller
- type: "pci"
source:
address:
domain: "0x0000"
bus: "0x08"
slot: "0x00"
function: "0x0"
address:
type: "pci"
domain: "0x0000"
bus: "0x10"
slot: "0x00"
function: "0x0"
# NVIDIA Corporation M2000 [Maxwell GM107GL]
- type: "pci"
source:
address:
domain: "0x0000"
bus: "0x03"
slot: "0x00"
function: "0x0"
address:
type: "pci"
domain: "0x0000"
bus: "0x0b"
slot: "0x00"
function: "0x0"
# NVIDIA Corporation M2000 High Definition Audio Controller
- type: "pci"
source:
address:
domain: "0x0000"
bus: "0x03"
slot: "0x00"
function: "0x1"
address:
type: "pci"
domain: "0x0000"
bus: "0x0f"
slot: "0x00"
function: "0x0"
- name: dev-01
title: "Lab Kubernetes VM"
uuid: "55feda16-51ae-446e-9c83-4c0eee1e5e00" uuid: "55feda16-51ae-446e-9c83-4c0eee1e5e00"
cloud_image_url: "http://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img"
cloud_image_sha256: "2b5f90ffe8180def601c021c874e55d8303e8bcbfc66fee2b94414f43ac5eb1f"
disk_size: 80G
cloud_init: true
autostart: true autostart: true
memory: 33554432 memory: 8
cores: 1 cores: 1
threads: 2 threads: 2
physical_cpus: "1-7" physical_cpus: "2-10"
reserved_cpus: "0,6" reserved_cpus: "0,8"
cdrom: false cdrom: true
console: true console: true
audio: false audio: false
secure_boot: false secure_boot: true
tpm: true tpm: true
disk_file: "fedora-headless.qcow2" net_bridge: br0
disk_file: "dev-01.qcow2"
mac_address: "52:54:00:ae:f3:d0" mac_address: "52:54:00:ae:f3:d0"
block_devs: block_devs: []
- block_dev: "/dev/nvme0n1" host_devs: []
target_dev: "sdb" guest_agent: true
host_devs: virtio_fs:
# NVIDIA Corporation GA106 [GeForce RTX 3060 Lite Hash Rate] - source: "/mnt/srv"
- type: "pci" target: "srv"
source: - source: "/mnt/storage"
address: target: "storage"
domain: "0x0000" user_data: |
bus: "0x03" #cloud-config
slot: "0x00" hostname: dev-01
function: "0x0" fqdn: dev-01.lab.alexpires.me
address: manage_etc_hosts: true
{ users:
type: "pci", - name: provision
domain: "0x0000", sudo: ALL=(ALL) NOPASSWD:ALL
bus: "0x09", shell: /bin/bash
slot: "0x00", lock_passwd: true
function: "0x0", ssh_authorized_keys:
} - {{ lookup('file', 'keys/localnetwork.pub') | trim }}
# NVIDIA Corporation GA106 High Definition Audio Controller ssh_pwauth: false
- type: "pci" disable_root: true
source: package_upgrade: true
address: packages:
domain: "0x0000" - qemu-guest-agent
bus: "0x03" runcmd:
slot: "0x00" - systemctl enable qemu-guest-agent
function: "0x1" - systemctl start qemu-guest-agent
address:
{
type: "pci",
domain: "0x0000",
bus: "0x0a",
slot: "0x00",
function: "0x0",
}
# Let's Encrypt / Certbot
cloudns_auth_id: "{{ lookup('env', 'CLOUDNS_AUTH_ID') }}" cloudns_auth_id: "{{ lookup('env', 'CLOUDNS_AUTH_ID') }}"
cloudns_auth_password: "{{ lookup('env', 'CLOUDNS_PASSWORD') }}" cloudns_auth_password: "{{ lookup('env', 'CLOUDNS_PASSWORD') }}"
cloudns_nameserver: "109.201.133.111" cloudns_nameserver: "109.201.133.111"
+243 -1
View File
@@ -10,6 +10,21 @@
default_hugepagesz=1G hugepagesz=1G hugepages=8 mitigations=off loglevel=3 {{ virt_extra_grub_args | default("") | trim}} default_hugepagesz=1G hugepagesz=1G hugepages=8 mitigations=off loglevel=3 {{ virt_extra_grub_args | default("") | trim}}
tasks: tasks:
- name: Ensure the system is Fedora
ansible.builtin.assert:
that:
- ansible_facts['distribution'] == "Fedora"
fail_msg: "This playbook only supports Fedora hosts."
- name: Install python3-libdnf5 so Ansible DNF module works
become: true
ansible.builtin.shell:
cmd: |
dnf install -y python3-libdnf5
touch /etc/.python3_libdnf5_installed
args:
creates: /etc/.python3_libdnf5_installed
- name: Install required packages - name: Install required packages
ansible.builtin.dnf: ansible.builtin.dnf:
name: name:
@@ -22,8 +37,115 @@
- tuned - tuned
- python3-lxml - python3-lxml
- python3-libvirt - python3-libvirt
- tuned
- cloud-utils
- qemu-img
state: present state: present
# ===== BRIDGE CONFIGURATION TASKS =====
- name: Detect current network interface
ansible.builtin.set_fact:
primary_interface: "{{ bridge_interface }}"
when: bridge_interface is defined
- name: Check if bridge already exists
ansible.builtin.command: nmcli -t -f NAME,TYPE connection show
register: nmcli_connections
changed_when: false
failed_when: false
- name: Set bridge existence fact
ansible.builtin.set_fact:
bridge_exists: "{{ (bridge_name in nmcli_connections.stdout) and ('bridge' in nmcli_connections.stdout) }}"
- name: Get current interface connection name
ansible.builtin.shell:
cmd: |
set -o pipefail
nmcli -t -f NAME,DEVICE connection show --active | grep ":{{ primary_interface }}$" | cut -d: -f1 | head -n1
executable: /bin/bash
register: current_connection_name
changed_when: false
when: not bridge_exists
- name: Create bridge connection with static IPv4
ansible.builtin.command: >
nmcli connection add
type bridge
con-name {{ bridge_name }}
ifname {{ bridge_name }}
ipv4.method manual
ipv4.addresses {{ bridge_ipv4_address }}
ipv4.gateway {{ bridge_ipv4_gateway }}
ipv4.dns "{{ bridge_ipv4_dns }}"
ipv4.dns-search {{ bridge_ipv4_domain }}
ipv6.method disabled
connection.autoconnect yes
bridge.stp no
when: not bridge_exists
changed_when: true
register: bridge_created
- name: Create bridge slave connection for physical interface
ansible.builtin.command: >
nmcli connection add
type ethernet
con-name {{ bridge_name }}-slave
ifname {{ primary_interface }}
master {{ bridge_name }}
slave-type bridge
when: not bridge_exists and bridge_created is succeeded
changed_when: true
register: slave_created
- name: Deactivate old interface connection and activate bridge
become: true
ansible.builtin.command: >
nmcli connection down "{{ current_connection_name.stdout }}"
nmcli connection up {{ bridge_name }}
when:
- not bridge_exists
- slave_created is succeeded
- current_connection_name.stdout | length > 0
register: bridge_activated
changed_when: true
failed_when: false
async: 10
poll: 0
- name: Wait for network connectivity to restore # noqa: no-handler
ansible.builtin.wait_for:
host: "{{ bridge_ipv4_address.split('/')[0] }}"
port: 22
timeout: 30
delegate_to: localhost
when: bridge_activated is changed
- name: Switch ansible to connect via bridge IP # noqa: no-handler
ansible.builtin.set_fact:
ansible_host: "{{ bridge_ipv4_address.split('/')[0] }}"
when: bridge_activated is changed
- name: Verify bridge is active # noqa: no-handler
ansible.builtin.command: ip addr show {{ bridge_name }}
register: bridge_status
changed_when: false
failed_when: "'state UP' not in bridge_status.stdout"
when: bridge_activated is changed
- name: Display bridge configuration
ansible.builtin.debug: # noqa: no-handler
msg:
- "Bridge {{ bridge_name }} is configured and active"
- "IP Address: {{ bridge_ipv4_address }}"
- "Gateway: {{ bridge_ipv4_gateway }}"
- "DNS: {{ bridge_ipv4_dns }}"
- "Physical interface: {{ primary_interface }}"
when: bridge_activated is changed
# ===== END BRIDGE CONFIGURATION =====
- name: Enable and start libvirtd - name: Enable and start libvirtd
ansible.builtin.systemd: ansible.builtin.systemd:
name: libvirtd name: libvirtd
@@ -38,12 +160,47 @@
backrefs: true backrefs: true
notify: Rebuild GRUB config notify: Rebuild GRUB config
- name: Copy vfio-bind script
ansible.builtin.copy:
src: vfio-bind.sh
dest: /usr/local/bin/vfio-bind.sh
mode: '0755'
- name: Create systemd service for vfio-bind
ansible.builtin.copy:
dest: "/etc/systemd/system/vfio-{{ item.vendor }}-{{ item.device }}-bind.service"
content: |
[Unit]
Description=Bind PCI device {{ item.vendor }}:{{ item.device }} to VFIO driver
After=systemd-udev-settle.service
Wants=systemd-udev-settle.service
Before=libvirtd.service
[Service]
Type=oneshot
ExecStart=/usr/local/bin/vfio-bind.sh "{{ item.dev }}" "{{ item.vendor }}" "{{ item.device }}"
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
mode: '0644'
loop: "{{ virt_vfio_devices }}"
- name: Enable and start VFIO bind services
ansible.builtin.systemd:
name: "vfio-{{ item.vendor }}-{{ item.device }}-bind.service"
enabled: true
state: started
daemon_reload: true
loop: "{{ virt_vfio_devices }}"
- name: Add VFIO PCI device IDs to modprobe - name: Add VFIO PCI device IDs to modprobe
ansible.builtin.copy: ansible.builtin.copy:
dest: /etc/modprobe.d/vfio.conf dest: /etc/modprobe.d/vfio.conf
content: | content: |
options vfio-pci ids={{ virt_vfio_ids | join(',') }} options vfio-pci ids={{ virt_vfio_ids | join(',') }}
install snd_hda_codec_hdmi /bin/false install snd_hda_codec_hdmi /bin/false
softdep xhci_hcd pre: vfio-pci
mode: '0644' mode: '0644'
- name: Blacklist Nouveau and other drivers - name: Blacklist Nouveau and other drivers
@@ -110,6 +267,91 @@
- Reload udev rules - Reload udev rules
- Trigger udev to apply changes - Trigger udev to apply changes
- name: Download and resize cloud image for VM
block:
- name: Check if local image already exists
vars:
vm: "{{ item }}"
ansible.builtin.stat:
path: "/var/lib/libvirt/images/{{ vm.disk_file }}"
get_checksum: false
register: cloud_image_stat
loop: "{{ virt_machines }}"
- name: Download cloud image if not present
vars:
id: "{{ item }}"
loop: "{{ range(virt_machines | length) }}"
ansible.builtin.get_url:
url: "{{ virt_machines[id].cloud_image_url }}"
dest: "/var/lib/libvirt/images/{{ virt_machines[id].disk_file }}"
mode: '0644'
checksum: "sha256:{{ virt_machines[id].cloud_image_sha256 }}"
when:
- not cloud_image_stat.results[id].stat.exists
- virt_machines[id].cloud_image_url is defined
- virt_machines[id].cloud_image_sha256 is defined
- name: Resize cloud image
vars:
id: "{{ item }}"
loop: "{{ range(virt_machines | length) }}"
ansible.builtin.command: >
qemu-img resize /var/lib/libvirt/images/{{ virt_machines[id].disk_file }} {{ virt_machines[id].disk_size | default('20G') }}
when:
- not cloud_image_stat.results[id].stat.exists
- virt_machines[id].disk_size is defined
changed_when: false
- name: Create cloud-init ISO for VM
block:
- name: Create temporary cloud-init directory
vars:
vm: "{{ item }}"
loop: "{{ virt_machines }}"
ansible.builtin.file:
path: "/var/lib/libvirt/images/{{ vm.name }}-cloudinit"
state: directory
mode: '0755'
when: vm.user_data is defined
- name: Create user-data file
vars:
vm: "{{ item }}"
loop: "{{ virt_machines }}"
ansible.builtin.copy:
dest: "/var/lib/libvirt/images/{{ vm.name }}-cloudinit/user-data"
content: |
{{ vm.user_data }}
mode: '0644'
when: vm.user_data is defined
register: user_data_created
- name: Create meta-data file
vars:
vm: "{{ item }}"
loop: "{{ virt_machines }}"
ansible.builtin.copy:
dest: "/var/lib/libvirt/images/{{ vm.name }}-cloudinit/meta-data"
content: |
instance-id: {{ vm.name }}-{{ vm.uuid }}
local-hostname: {{ vm.name }}
mode: '0644'
when: vm.user_data is defined
- name: Create cloud-init ISO image
vars:
vm: "{{ item }}"
loop: "{{ virt_machines }}"
ansible.builtin.command: >
cloud-localds
/var/lib/libvirt/images/{{ vm.name }}-cloudinit.img
/var/lib/libvirt/images/{{ vm.name }}-cloudinit/user-data
/var/lib/libvirt/images/{{ vm.name }}-cloudinit/meta-data
args:
creates: "/var/lib/libvirt/images/{{ vm.name }}-cloudinit.img"
when: vm.user_data is defined
- name: Create or update virtual machine - name: Create or update virtual machine
vars: vars:
vm: "{{ item }}" vm: "{{ item }}"
@@ -117,7 +359,6 @@
community.libvirt.virt: community.libvirt.virt:
autostart: "{{ vm.autostart | default(false) }}" autostart: "{{ vm.autostart | default(false) }}"
name: "{{ vm.name }}" name: "{{ vm.name }}"
state: running
command: define command: define
xml: "{{ lookup('template', 'domain.xml.j2') }}" xml: "{{ lookup('template', 'domain.xml.j2') }}"
@@ -128,6 +369,7 @@
community.libvirt.virt: community.libvirt.virt:
name: "{{ vm.name }}" name: "{{ vm.name }}"
state: running state: running
when: vm.autostart | default(false)
- name: Notify user to reboot for changes - name: Notify user to reboot for changes
ansible.builtin.debug: ansible.builtin.debug:
+9
View File
@@ -135,6 +135,14 @@
- password-auth - password-auth
- pam - pam
- name: Check if sssd-shadowutils exists
ansible.builtin.stat:
path: /etc/pam.d/sssd-shadowutils
register: sssd_shadowutils
tags:
- sssd-shadowutils
- pam
- name: Remove nullok from sssd-shadowutils - name: Remove nullok from sssd-shadowutils
become: true become: true
ansible.builtin.replace: ansible.builtin.replace:
@@ -143,6 +151,7 @@
mode: "0644" mode: "0644"
owner: root owner: root
group: root group: root
when: sssd_shadowutils.stat.exists
tags: tags:
- sssd-shadowutils - sssd-shadowutils
- pam - pam
+1 -1
View File
@@ -12,7 +12,7 @@
- name: Set ssh version as fact - name: Set ssh version as fact
ansible.builtin.set_fact: ansible.builtin.set_fact:
ssh_installed_version: "{{ ssh_version.stderr | regex_search('^OpenSSH_([0-9+].[0-9]+)', '\\1') | join('.') | float }}" # noqa jinja[spacing] ssh_installed_version: "{{ ssh_version.stderr | regex_search('^OpenSSH_([0-9]+.[0-9]+).', '\\1') | join('.') | float }}" # noqa jinja[spacing]
when: ssh_version.stderr != "" when: ssh_version.stderr != ""
tags: tags:
- roles::cis::sshd - roles::cis::sshd
+2 -2
View File
@@ -17,8 +17,8 @@
- name: CertManager | LetsEncrypt DNS-01 issuer - name: CertManager | LetsEncrypt DNS-01 issuer
ansible.builtin.include_tasks: issuers/dns-01.yml ansible.builtin.include_tasks: issuers/dns-01.yml
when: microk8s_certmgr_letsencrypt_dns01 is true when: microk8s_certmgr_letsencrypt_dns01
- name: CertManager | LetsEncrypt HTTP-01 issuer - name: CertManager | LetsEncrypt HTTP-01 issuer
ansible.builtin.include_tasks: issuers/http-01.yml ansible.builtin.include_tasks: issuers/http-01.yml
when: microk8s_certmgr_letsencrypt_http01 is true when: microk8s_certmgr_letsencrypt_http01
@@ -32,4 +32,8 @@
state: present state: present
kubeconfig: "{{ k8s_kubeconfig }}" kubeconfig: "{{ k8s_kubeconfig }}"
src: "{{ k8s_etc }}/k8s-certmanager-cloudns.yaml" src: "{{ k8s_etc }}/k8s-certmanager-cloudns.yaml"
wait: true
- name: CertManager | Sleep to allow webhook to be ready
ansible.builtin.pause:
seconds: 15
when: microk8s_certmgr_letsencrypt_dns01
-5
View File
@@ -61,11 +61,6 @@
- k8s::install - k8s::install
- k8s::kubectl - k8s::kubectl
- name: Setup LoadBalancer
ansible.builtin.include_tasks: loadbalancer.yml
tags:
- k8s::loadbalancer
- name: Setup CertManager - name: Setup CertManager
ansible.builtin.include_tasks: certmanager.yml ansible.builtin.include_tasks: certmanager.yml
tags: tags:
+41 -12
View File
@@ -2,8 +2,8 @@
<name>{{ vm.name }}</name> <name>{{ vm.name }}</name>
<uuid>{{ vm.uuid }}</uuid> <uuid>{{ vm.uuid }}</uuid>
<title>{{ vm.title }}</title> <title>{{ vm.title }}</title>
<memory unit='KiB'>{{ vm.memory }}</memory> <memory unit='GiB'>{{ vm.memory }}</memory>
<currentMemory unit='KiB'>{{ vm.memory }}</currentMemory> <currentMemory unit='GiB'>{{ vm.memory }}</currentMemory>
<memoryBacking> <memoryBacking>
<hugepages/> <hugepages/>
<source type='memfd'/> <source type='memfd'/>
@@ -23,9 +23,9 @@
<emulatorpin cpuset='{{ vm.reserved_cpus }}'/> <emulatorpin cpuset='{{ vm.reserved_cpus }}'/>
</cputune> </cputune>
<os> <os>
<type arch='x86_64' machine='pc-q35-7.0'>hvm</type> <type arch='x86_64' machine='pc-q35-8.2'>hvm</type>
<loader readonly='yes' secure='{% if vm.secure_boot %}yes{% else %}no{% endif %}' type='pflash'>/usr/share/edk2/ovmf/OVMF_CODE{% if vm.secure_boot %}.secboot{% endif %}.fd</loader> <loader readonly='yes' secure='{% if vm.secure_boot %}yes{% else %}no{% endif %}' type='pflash' format='qcow2'>/usr/share/edk2/ovmf/OVMF_CODE_4M{% if vm.secure_boot %}.secboot{% endif %}.qcow2</loader>
<nvram template='/usr/share/edk2/ovmf/OVMF_VARS.secboot.fd'>/var/lib/libvirt/qemu/nvram/{{ vm.name }}_VARS.fd</nvram> <nvram template='/usr/share/edk2/ovmf/OVMF_VARS_4M.secboot.qcow2' templateFormat='qcow2' format='qcow2'>/var/lib/libvirt/qemu/nvram/{{ vm.name }}_VARS.fd.qcow2</nvram>
<boot dev='hd'/> <boot dev='hd'/>
<bootmenu enable='no'/> <bootmenu enable='no'/>
</os> </os>
@@ -44,7 +44,12 @@
{% endif %} {% endif %}
<smm state='on'/> <smm state='on'/>
</features> </features>
{% if vm.cpu is defined %}
<cpu mode='custom' match='exact' check='none'>
<model fallback='allow'>{{ vm.cpu }}</model>
{% else %}
<cpu mode='host-passthrough' check='none' migratable='on'> <cpu mode='host-passthrough' check='none' migratable='on'>
{% endif %}
<topology sockets='1' dies='1' cores='{{ vm.cores }}' threads='{{ vm.threads }}'/> <topology sockets='1' dies='1' cores='{{ vm.cores }}' threads='{{ vm.threads }}'/>
</cpu> </cpu>
<clock offset='localtime'> <clock offset='localtime'>
@@ -81,6 +86,16 @@
<target dev='{{ block_dev.target_dev }}' bus='virtio'/> <target dev='{{ block_dev.target_dev }}' bus='virtio'/>
</disk> </disk>
{% endfor %} {% endfor %}
{% if vm.cloud_init is defined %}
{% if vm.cloud_init | default(false) %}
<disk type='file' device='disk'>
<driver name='qemu' type='raw'/>
<source file='/var/lib/libvirt/images/{{ vm.name }}-cloudinit.img'/>
<target dev='hdb' bus='virtio'/>
<readonly/>
</disk>
{% endif %}
{% endif %}
{% if vm.cdrom %} {% if vm.cdrom %}
<disk type='file' device='cdrom'> <disk type='file' device='cdrom'>
<driver name='qemu' type='raw'/> <driver name='qemu' type='raw'/>
@@ -187,15 +202,15 @@
<address type='usb' bus='0' port='1'/> <address type='usb' bus='0' port='1'/>
</controller> </controller>
{% endif %} {% endif %}
{% endif %} {% endif %}
{% if vm.virtio_fs is defined %} {% if vm.virtio_fs is defined %}
{% if vm.virtio_fs | default(false) %} {% for fs in vm.virtio_fs %}
<filesystem type='mount' accessmode='passthrough'> <filesystem type='mount' accessmode='passthrough'>
<driver type='virtiofs'/> <driver type='virtiofs' queue='1024'/>
<source dir='{{ vm.virtio_fs.source }}'/> <source dir='{{ fs.source }}'/>
<target dir='{{ vm.virtio_fs.target }}'/> <target dir='{{ fs.target }}'/>
</filesystem> </filesystem>
{% endif %} {% endfor %}
{% endif %} {% endif %}
<interface type='bridge'> <interface type='bridge'>
<mac address='{{ vm.mac_address }}'/> <mac address='{{ vm.mac_address }}'/>
@@ -221,7 +236,7 @@
<input type='mouse' bus='ps2'/> <input type='mouse' bus='ps2'/>
<input type='keyboard' bus='ps2'/> <input type='keyboard' bus='ps2'/>
{% if vm.tpm %} {% if vm.tpm %}
<tpm model='tpm-tis'> <tpm model='tpm-crb'>
<backend type='emulator' version='2.0'/> <backend type='emulator' version='2.0'/>
</tpm> </tpm>
{% endif %} {% endif %}
@@ -248,8 +263,22 @@
{% endif %} {% endif %}
</hostdev> </hostdev>
{% endfor %} {% endfor %}
{% if vm.guest_agent is defined %}
{% if vm.guest_agent | default(false) %}
<channel type='unix'>
<source mode='bind' path='/var/lib/libvirt/qemu/{{ vm.name }}.agent'/>
<target type='virtio' name='org.qemu.guest_agent.0' state='connected'/>
</channel>
{% endif %}
{% endif %}
{% if vm.mem_balloon is defined %}
{% if vm.mem_balloon | default(false) %}
<memballoon model='virtio'> <memballoon model='virtio'>
<address type='pci' domain='0x0000' bus='0x04' slot='0x00' function='0x0'/> <address type='pci' domain='0x0000' bus='0x04' slot='0x00' function='0x0'/>
</memballoon> </memballoon>
{% endif %}
{% else %}
<memballoon model='none'/>
{% endif %}
</devices> </devices>
</domain> </domain>
-4
View File
@@ -103,12 +103,8 @@ gpu-01.lab.alexpires.me
gpu-01.lab.alexpires.me gpu-01.lab.alexpires.me
[windows] [windows]
game-01.lab.alexpires.me
hpz440.lab.alexpires.me hpz440.lab.alexpires.me
[windows_game]
game-01.lab.alexpires.me
[prometheus_linux] [prometheus_linux]
prod-01.alexpires.me prod-01.alexpires.me
dev-01.lab.alexpires.me dev-01.lab.alexpires.me
+2 -2
View File
@@ -14,7 +14,7 @@ locals {
samba_shares = [ samba_shares = [
{ {
name = "Storage" name = "Storage"
path = "/srv/storage" path = "/mnt/storage"
comment = "Main Storage" comment = "Main Storage"
} }
] ]
@@ -231,7 +231,7 @@ locals {
} }
# mstream # mstream
mstream_music_folder = "/srv/storage/Music" mstream_music_folder = "/mnt/storage/Music"
mstream_fqdn = "music.${local.lab_domain}" mstream_fqdn = "music.${local.lab_domain}"
} }
+1 -1
View File
@@ -364,7 +364,7 @@ resource "kubernetes_deployment" "proxy" {
container { container {
name = "proxy" name = "proxy"
image = "nginx:${var.tag}" image = "nginx:${var.tag}"
image_pull_policy = "Always" image_pull_policy = "IfNotPresent"
resources { resources {
requests = { requests = {