Part of my 2024 goal was to make my homelab easier to manage: spinning up virtual machines, rolling out updates, generally managing things should take less work. That includes managing the inventory of homelab machines, a mix of bare metal, virtual machines, or containers on a Proxmox cluster.
Things start with a source of truth, what I hope to use Netbox. Netbox contains APIs for managing inventories of IP addresses and prefixes, machines, virtual machines, etc.
But before I store/update all the devices in Netbox, I need to determine if they are physical or virtual, since each requires using different Ansible modules when inserting the objects into Netbox.
Enter Ansible facts, a dictionary of information gleaned from each host upon running Ansible.
There are a few ansible facts available to determine the physical or virtual-ness of a host:
- ansible_virtualization_role
- ansible_virtualization_tech_guest
- ansible_virtualization_tech_host
- ansible_virtualization_type
The below table are the combinations I’ve found that, when all true, determine the machine type.
Machine Type | ansible_virtualization_role | ansible_virtualization_tech_guest | ansible_virtualization_tech_host | ansible_virtualization_type |
---|---|---|---|---|
Physical | host | [] | [kvm] | kvm |
Virtual Machine | guest | [kvm] | [] | kvm |
Container (lxc) | guest | [lxc, container] | [kvm] | lxc |
I’m going to use platform_type
as the Ansible variable that is set when a host type has been determined. I’ve written the playbook to exclude the host
from further processing if the type cannot be determined.
I’ve split up the yaml so that one can merely include platform_detection.yaml
at the beginning of their playbook.
playbook.yaml
:
- name: playbook to include platform detection logic
hosts: all
gather_facts: true
tasks:
- name: include platform detection tasks
ansible.builtin.include_tasks:
file: platform_detection.yaml
platform_detection.yaml
:
---
- name: set initial detected state to false
set_fact:
is_detected: false
- name: check if platform is a virtual machine
set_fact:
is_detected: true
platform_type: virtual
when:
- ansible_virtualization_role == "guest"
- "'kvm' in ansible_virtualization_tech_guest"
- name: check if platform is an lxc container
set_fact:
is_detected: true
platform_type: container
when:
- ansible_virtualization_role == "guest"
- "'container' in ansible_virtualization_tech_guest"
- "'lxc' in ansible_virtualization_tech_guest"
- name: check if platform is a physical machine
set_fact:
is_detected: true
platform_type: physical
when:
- ansible_virtualization_role == "host"
- ansible_virtualization_tech_guest|length == 0
- name: end the play for a host whose platform we couldn't detect
ansible.builtin.meta: end_host
when:
- is_detected is false
- name: print platform type
ansible.builtin.debug:
msg: "Platform type: {{ platform_type }}, detected: {{ is_detected }}"
The ansible.builtin.meta: end_host
task is used to exclude hosts whose platform type was unable to be deduced.
The variable to use in when
conditions for tasks which need to know the platform type is platform_type
variable, whose values are either physical
, virtual
, or container
.
Now I can use the platform type to decide which Ansible netbox module to use when inserting/updating entries.
But that’s for another post.