I am using the Proxmox dynamic inventory community plugin and it is working.
I name my Proxmox VMs like this: hostname-os-LastTwoIpOctets
.
For example, ns1-deb-10.10.
ns1
is the hostname without the domain suffix — the full hostname is actually ns1.123.org
.
deb
= Debian
10.10
= 10.0.10.10
— the third octet tells me the VLAN.
Out of the box, Ansible uses the VM name to reach the remote instance. So in this case, it uses ns1-deb-10.10.
I have authoritative DNS set up. That means all of my systems are reachable by hostname, so I’m already set up for success. I don’t need QEMU or other tools to gather host data — I simply want to connect via my actual hostname.
I’m able to use compose
and split
on -
to build the hostvars
with no problem.
What I need now is to transform the host name so that Ansible reaches the remote host using my real DNS hostname, rather than the VM name.
Is this doable?
Since I have DNS configured properly, being able to just tweak something in the *.proxmox.yml
file would save a lot of time and effort — I’m essentially ready to go and don’t need to waste time standing up extra or modfying existing infrastructure.
Thanks.
I don’t know of a quick way to transform hostnames, but you could set the ansible_host
variable manually for your VMs, as that is what Ansible will use in the background when connecting to systems. I use it all the time in lab settings that don’t have (proper) DNS set up.
On the other hand, I can’t resist a little ‘you seem to be doing it wrong’
, why don’t you use tags for that? They can convey more information, be browsed using the webUI and, when configured, can also be made visible in the Ansible inventory. Which would then also give you a convenient list of, in your case, OS-specific groups to use in targeting 
I’m technically not doing anything currently and am open to / asking for any methodology, tags included. How can I use a tag as the hostname in my inventory?
Or are you saying,
- Name the vm “ns1.123.org”.
- Use tags for the other identifying information?
The latter, this is a screengrab from my lab server:
I don’t really need the extra info from the tags in my Ansible inventory (I use ansible_facts
for that), but I create/destroy most of these systems with OpenTofu. And as an easy means for my colleagues to identify them, I tagged them. But situations and needs can differ, so here’s mine, feel free to ask away 
Use the compose function of the plugin. I’ve included an example of how I’m doing in my lab env.
compose:
ansible_host: proxmox_agent_interfaces[1].ip-addresses[0]|ansible.utils.ipaddr('address')
@Thulium-Drake
I prefer to use a consistent naming convention across everything. It gives me predictability and lets me see exactly what I care about at a glance.
Regarding ansible_facts
: that only works after Ansible connects to the target host via SSH. What I’m trying to solve happens before that / allows that to happen. I appreciate the screenshot.
@bindashroot
The issue isn’t with compose:
itself — it’s that Ansible is still using the VM name as the inventory_hostname
, even when I define ansible_host
.
Here’s an example:
compose:
ansible_hostname: inventory_hostname.split('-')[0] ~ '.123.org'
This gives me:
"ns1-fed-10.12": {
"ansible_hostname": "ns1.123.org",
"proxmox_boot": {
"order": "scsi0;ide2;net0"
}
}
But when I try to reach the machine via ns1.123.org
, it doesn’t work — because Ansible is still looking for the original VM name (inventory_hostname
: ns1-fed-10.12
).
Yes, there are workarounds — but I don’t feel like I should have to use them.
I have authoritative DNS set up. Every instance is already reachable by its hostname. If Ansible and the Proxmox dynamic inventory simply used that hostname as the inventory key, everything would “just work.” That unlocks hands-off automation: I can spin up a new instance and run my Ansible setup without needing to touch or configure anything.
I’m getting closer. After reading through the plugin code, it’s appears that certain values (like name
) are not passed into the compose
context as you might expect:
https://github.com/ansible-collections/community.general/blob/main/plugins/inventory/proxmox.py
Taking a break for now, but I’ll follow up if I get it sorted.
Thanks again to everyone.
Your example shows ansible_hostname which is different than ansible_host. The ansible_host variable is a special variable which can take a dns name or an IP. ansible_host is a connection variable. ansible_hostname is the hostname as discovered by Ansible on the remote host.
hostname
is just a type-o. I meant host
It didn’t make a difference either way.
The following doesn’t work. It still expects, ns1-fed-10.12
which obviously a DNS entry doesn’t exist for.
ansible ns1.123.org -m ping -i inventories/inventory.proxmox.yml
"ns1-fed-10.12": {
"ansible_host": "ns1.123.org",
"proxmox_boot": {
"order": "scsi0;ide2;net0"
}
}
Ansible doesn’t “discover hostnames” out of the box. The default behavior is to use the name of the VM, not to be confused with the acual hostname.
Thanks.
Thanks, everyone. I had this solved and didn’t know it.
Even if you set ansible_host
, you sill have to refer to the target as the inventory_hostname
. Which means, if your VM is named ns1-fed-10.12
, and you use compose to transform that and set ansible_host
to ns1.123.org
- you still have to refer to the taget as ns1-fed-10.12
.
That was my biggest hurdle figuring everyhing out - Ansible sort of expects you to adapt your infra around it rather than it around your infra.
ansible ns1-fed-10.12 -m ping -vvv
...
<ns1.123.org> ESTABLISH SSH CONNECTION FOR USER: brazzle
...
The solution is to use compose like this:
compose:
ansible_host: inventory_hostname.split('-')[0] ~ '.123.org'
Thanks again, everyone.