Files
homelab/plays/create-ha-dev-vm.yml
T

153 lines
4.5 KiB
YAML

---
- name: Create Home Assistant Dev VM
hosts: pve_cluster
become: true
run_once: true
vars:
vm_name: homeassistant-dev
haos_version: "13.2"
haos_url: "https://github.com/home-assistant/operating-system/releases/download/{{ haos_version }}/haos_ova-{{ haos_version }}.qcow2.xz"
storage_pool: cpool
bridge: v40srv
tasks:
- name: Get next free VM ID
command: pvesh get /cluster/nextid
register: next_id_out
changed_when: false
- name: Set VM ID variable
set_fact:
vm_id: "{{ next_id_out.stdout | trim }}"
- name: Display selected Node and VM ID
debug:
msg: "Creating VM {{ vm_id }} on node {{ inventory_hostname }}"
- name: Install required packages
apt:
name: xz-utils
state: present
update_cache: true
- name: Download HAOS image
get_url:
url: "{{ haos_url }}"
dest: "/tmp/haos_ova-{{ haos_version }}.qcow2.xz"
mode: '0644'
- name: Extract HAOS image
command: "unxz -k -f /tmp/haos_ova-{{ haos_version }}.qcow2.xz"
args:
creates: "/tmp/haos_ova-{{ haos_version }}.qcow2"
- name: Create VM
command: >
qm create {{ vm_id }}
--name {{ vm_name }}
--memory 4096
--cores 2
--net0 virtio,bridge={{ bridge }}
--bios ovmf
--machine q35
--cpu host
--ostype l26
--scsihw virtio-scsi-pci
--agent enabled=1
- name: Import Disk
command: "qm importdisk {{ vm_id }} /tmp/haos_ova-{{ haos_version }}.qcow2 {{ storage_pool }}"
register: import_disk_result
- name: Attach Disk
command: "qm set {{ vm_id }} --scsi0 {{ storage_pool }}:vm-{{ vm_id }}-disk-0"
- name: Add EFI Disk
command: "qm set {{ vm_id }} --efidisk0 {{ storage_pool }}:0"
- name: Set Boot Order
command: "qm set {{ vm_id }} --boot order=scsi0"
- name: Start VM
command: "qm start {{ vm_id }}"
- name: Wait for QEMU Guest Agent
command: "qm agent {{ vm_id }} ping"
register: agent_ping
until: agent_ping.rc == 0
retries: 60
delay: 5
changed_when: false
- name: Get Network Interfaces
command: "qm guest cmd {{ vm_id }} network-get-interfaces"
register: network_interfaces_out
changed_when: false
until: network_interfaces_out.stdout | from_json | selectattr('name', '!=', 'lo') | selectattr('ip-addresses', 'defined') | map(attribute='ip-addresses') | flatten | selectattr('ip-address-type', 'equalto', 'ipv4') | list | length > 0
retries: 30
delay: 5
- name: Parse IP Address
set_fact:
vm_ip: "{{ (network_interfaces_out.stdout | from_json | selectattr('name', '!=', 'lo') | selectattr('ip-addresses', 'defined') | map(attribute='ip-addresses') | flatten | selectattr('ip-address-type', 'equalto', 'ipv4') | map(attribute='ip-address') | first) }}"
- name: Display VM IP
debug:
msg: "VM IP is {{ vm_ip }}"
- name: Cleanup downloaded files
file:
path: "{{ item }}"
state: absent
loop:
- "/tmp/haos_ova-{{ haos_version }}.qcow2.xz"
- "/tmp/haos_ova-{{ haos_version }}.qcow2"
- name: Configure Caddy Reverse Proxy
delegate_to: caddy.srv.renner.uno
block:
- name: Add Caddy Configuration
blockinfile:
path: /etc/caddy/Caddyfile
marker: "# {mark} ANSIBLE MANAGED BLOCK {{ vm_name }}"
block: |
{{ vm_name }}.renner.uno {
import cloudflare
import custom_error
reverse_proxy http://{{ vm_ip }}:8123
}
notify: Reload Caddy
- name: Configure DNS Resolution
delegate_to: bind1.srv.renner.uno
vars:
dns_zone_file: /etc/bind/zones/db.nerdcave.eu
block:
- name: Add CNAME Record
lineinfile:
path: "{{ dns_zone_file }}"
line: "{{ vm_name }} IN CNAME caddy.srv.renner.uno."
insertbefore: "^;.*"
regexp: "^{{ vm_name }} IN CNAME"
notify: Reload Bind
- name: Increment Zone Serial
shell: |
sed -i -r 's/([0-9]{10})(\s+;\s+Serial)/echo $((\1 + 1))\2/e' {{ dns_zone_file }}
args:
executable: /bin/bash
handlers:
- name: Reload Caddy
delegate_to: caddy.srv.renner.uno
service:
name: caddy
state: reloaded
- name: Reload Bind
delegate_to: bind1.srv.renner.uno
service:
name: bind9
state: reloaded