Im somewhat at my google-fu end. I can't see a reason why i would get "The conditional check 'XYZ.results[item] is success' failed. The error was: The 'failed' test expects a dictionary". It works with list a of numbers but not a list of strings? If i add prints statement and compare the outputs, the only notable differences are different item names.
Maybe their is a better and correct way to loop over hosts, if host needs to be pve?
This works.
- name: Clone Virtual Machine
community.general.proxmox_kvm:
api_host: ANYPVEHOST
api_user: APIPVEUSER@pve
api_token_id: PVETOKEN
api_token_secret: "{{ PVETOKENSECRET }}"
name: "{{ '%s%02d' | format(hostvars[groups['docker_swarm'][0]]['target_name_prefix'], item | int + 1) }}"
newid: "{{ '%d' | format(hostvars[groups['docker_swarm'][0]]['first_id'] + item) }}"
node: PVENODE
clone: debian12-genericcloud
storage: local-zfs
state: present
register: vm_clone
loop: "{{ range(0, hostvars[groups['docker_swarm'][0]]['target_count'] | int, 1) | list }}"
- name: Check if VM is present
when: vm_clone.results[item] is success
community.general.proxmox_vm_info:
api_host: ANYPVEHOST
api_user: APIPVEUSER@pve
api_token_id: PVETOKEN
api_token_secret: "{{ PVETOKENSECRET }}"
node: PVENODE
vmid: "{{ vm_clone.results[item].vmid }}"
until: >
vm_present is defined and
vm_present.proxmox_vms is defined
retries: 60
delay: 1
register: vm_present
loop: "{{ range(0, hostvars[groups['docker_swarm'][0]]['target_count'] | int, 1) | list }}"
and also this
- name: Check if VM is present
community.general.proxmox_vm_info:
api_host: ANYPVEHOST
api_user: APIPVEUSER@pve
api_token_id: PVETOKEN
api_token_secret: "{{ PVETOKENSECRET }}"
node: "{{ hostvars[groups['windows'][item]].vars.node }}"
vmid: "{{ hostvars[groups['windows'][item]].vars.vmid }}"
until: >
vm_present is defined and
vm_present.proxmox_vms is defined
retries: 60
delay: 1
register: vm_present
loop: "{{ range(0, groups['windows'] | length, 1) | list }}"
- name: Start VM
when: vm_present.results[item] is success
community.general.proxmox_kvm:
api_host: ANYPVEHOST
api_user: APIPVEUSER@pve
api_token_id: PVETOKEN
api_token_secret: "{{ PVETOKENSECRET }}"
vmid: "{{ hostvars[groups['windows'][item]].vars.vmid }}"
node: PVENODE
state: started
register: vm_started
loop: "{{ range(0, groups['windows'] | length, 1) | list }}"
But not this
- name: Check if VM is present
community.general.proxmox_vm_info:
api_host: ANYPVEHOST
api_user: APIPVEUSER@pve
api_token_id: PVETOKEN
api_token_secret: "{{ PVETOKENSECRET }}"
node: "{{ hostvars[item].vars.node }}"
vmid: "{{ hostvars[item].vars.vmid }}"
until: >
vm_present is defined and
vm_present.proxmox_vms is defined
retries: 60
delay: 1
register: vm_present
loop: "{{ groups.windows }}"
- name: Start VM
when: vm_present.results[item] is success
community.general.proxmox_kvm:
api_host: ANYPVEHOST
api_user: APIPVEUSER@pve
api_token_id: PVETOKEN
api_token_secret: "{{ PVETOKENSECRET }}"
vmid: "{{ hostvars[item].vars.vmid }}"
node: PVENODE
state: started
register: vm_started
loop: "{{ groups.windows }}"
Simply debug the content of all your variables to see your mistake. You loop over a range of integers in your first examples which are then used as list indexes in your when
clause.
Your last example loops over machine names in a group as strings which are indeed not list indexes.
You are taking this the wrong way anyhow. To fix a first common Ansible beginners error, you could loop directly on the results filtering out the unsuccessful ones. Each element contains the original looped value in the item
key (the machine name is hence item.item
)
- name: Check if VM is present
community.general.proxmox_vm_info:
api_host: ANYPVEHOST
api_user: APIPVEUSER@pve
api_token_id: PVETOKEN
api_token_secret: "{{ PVETOKENSECRET }}"
node: "{{ hostvars[item].node }}"
vmid: "{{ hostvars[item].vmid }}"
until: vm_present.proxmox_vms is defined
retries: 60
delay: 1
register: vm_present
loop: "{{ groups.windows }}"
- name: Start VM
community.general.proxmox_kvm:
api_host: ANYPVEHOST
api_user: APIPVEUSER@pve
api_token_id: PVETOKEN
api_token_secret: "{{ PVETOKENSECRET }}"
vmid: "{{ hostvars[item.item].vmid }}"
node: PVENODE
state: started
register: vm_started
loop: "{{ vm_present.results | select('success') }}"
This is still not optimal as you are using unnecessary loops. Your playbook becomes much simpler if you directly target your group and delegate the necessary tasks to localhost. The hosts failing the first task will not make it to the second one.
---
- name: Manage VMS
hosts: windows
gather_facts: false
tasks:
- name: Check if VM is present
community.general.proxmox_vm_info:
api_host: ANYPVEHOST
api_user: APIPVEUSER@pve
api_token_id: PVETOKEN
api_token_secret: "{{ PVETOKENSECRET }}"
node: "{{ node }}"
vmid: "{{ vmid }}"
register: vm_present
until: vm_present.proxmox_vms is defined
retries: 60
delay: 1
delegate_to: localhost
- name: Start VM
community.general.proxmox_kvm:
api_host: ANYPVEHOST
api_user: APIPVEUSER@pve
api_token_id: PVETOKEN
api_token_secret: "{{ PVETOKENSECRET }}"
vmid: "{{ vmid }}"
node: PVENODE
state: started
delegate_to: localhost