Dynamic Inventory

Ansible for Proxmox VE · Module 06

credativ GmbH

Learning goals

  • Understand why a static inventory goes stale
  • Configure the community.proxmox.proxmox inventory plugin
  • Read the groups and facts it generates
  • Build your own groups from Proxmox tags

The problem

pve01: {ansible_host: 192.168.0.1}
web01: {ansible_host: 192.168.0.50}
db01:  {ansible_host: 192.168.0.51}
  • Someone creates a VM in the GUI → it is not in your inventory
  • Someone deletes one → your playbook fails on a host that no longer exists
  • Someone renames one → you find out at the worst possible moment

The cluster already knows all of this. Ask it.

The plugin

inventory/lab.proxmox.yml
plugin: community.proxmox.proxmox
url: https://192.168.0.1:8006
user: automation@pve
token_id: ansible
token_secret: "{{ lookup('ansible.builtin.env', 'PVE_TOKEN_SECRET') }}"
validate_certs: false
want_facts: true
exclude_nodes: false

The file name must end in .proxmox.yml or .proxmox.yaml. Otherwise the plugin politely ignores it and you debug an empty inventory.

What you get

ansible-inventory -i inventory/lab.proxmox.yml --graph
@all:
  |--@proxmox_all_qemu:
  |  |--web01
  |--@proxmox_all_running:
  |  |--web01
  |--@proxmox_all_stopped:
  |--@proxmox_nodes:
  |  |--pve01
  |  |--pve02
  |  |--pve03
  |--@proxmox_pve02_qemu:
  |  |--web01

Groups per node, per type, per status, per pool. Generated, never maintained.

Facts, if you ask for them

With want_facts: true every guest carries its Proxmox configuration:

ansible-inventory -i inventory/lab.proxmox.yml --host web01
{
  "proxmox_vmid": 9001,
  "proxmox_node": "pve02",
  "proxmox_status": "stopped",
  "proxmox_maxmem": 536870912,
  "proxmox_tags_parsed": ["web", "staging"]
}

Tags become groups

Tag a guest in Proxmox VE, group on it in Ansible:

keyed_groups:
  - key: proxmox_tags_parsed
    separator: ""
    prefix: tag

groups:
  webservers: "'web' in (proxmox_tags_parsed | list)"
  production: "'prod' in (proxmox_tags_parsed | list)"

The person creating the VM decides its role, in the GUI, with a tag, and your playbooks follow.

Static and dynamic together

ansible-playbook site.yml -i inventory/hosts.yml -i inventory/lab.proxmox.yml

Or set both in ansible.cfg:

[defaults]
inventory = inventory/hosts.yml,inventory/lab.proxmox.yml

The nodes stay static, because they have to exist before anything is dynamic. The guests come from the cluster.

Exercise 06 — 8 minutes

Optional block at the end if you get there. → Exercise sheet: Dynamic inventory