I’m facing a race condition on my playbooks. In one task I’m creating a VM, and in the next I’m starting it, and I’m facing issues in which the VM hasn’t finished being created, so the task to start it fails as the VM doesn’t exist. Is there a way to wait for the VM to finish being created before I go to start it?
Depends on where you create vms. For Azure (for instance) one not have only to ensure vm only created, but it is also started:
state: present
started: true
‘started’ in this context means that ssh port will be open for connections (if I am not mistaken)
If my understanding is correct (and this depends on where you create vms) if you run create action syncronously machine should be created at the end of the action. If asyncronously - you will have to wait for async action to be completed (or fail)
You can also leverage vm_info module (if there is one for your platform) to get wm state and wait until vm is provisioned with until keyword. See
You can put a task with ansible.builtin.wait_for_connection module between your tasks.
But it’s better if you tell us which module you are using for VM provisioning because there could be a better, module specific, way.
If you intend to wait until the machine has finished creating instead of waiting until the machine has finished starting, you can try this:
At the end of the creation script/step, you could shut down the machine, then use qm wait to wait until the VM is shut down, using something like this:
# [some command like `qm start`]
- name: "ASYNC WAIT: Start waiting for OS install on {{ current_vm.name }}"
ansible.builtin.command: "qm wait {{ current_vm.vmid }}"
async: 14400 # 4 hours
poll: 0
register: async_task_result
- name: Add the new job ID to our list
ansible.builtin.set_fact:
async_job_ids: "{{ async_job_ids | default([]) + [async_task_result.ansible_job_id] }}"
And in the outer yaml that calls the previous one, do something like this:
- name: "Stage 2 - Wait for all VM OS installations to complete"
ansible.builtin.async_status:
jid: "{{ item }}"
loop: "{{ async_job_ids | default([]) }}"
register: async_poll_results
until: async_poll_results.finished
retries: 480 # 4 hours worth of checks
delay: 30
Thanks everyone for the comments
A couple of clarifications (that thinking back should have been in the original message, sorry):
- This is for VMs (and technically LXC containers as well) on Proxmox, so I’m using the
communiy.proxmoxcollection, specificallycommunity.proxmox.proxmoxfor LXC containers andcommunity.proxmox.proxmox_kvmfor full VMs. In my case is for servers in my own homelab, so no requests going to the cloud - I don’t think that there’s a way to make the VM creations through the
community.proxmoxinstance creation to be synchronous, although if that was possible it would solve all my problems
- The modules don’t allow me to create a VM and start it in a single shot, or at least they didn’t use to when I tried for the first time. Because of this the first task creates the VM, but doesn’t start it. This means that I cannot wait for ports to be open or connections to succeed. Even if I could do both in the same task, there are cases in which I need to modify the VM somehow for it to be able to start, like when I’m bringing up HomeAssistantOS on a VM
- I would like something like
community.proxmox.wait_for_instance_to_exist, and if we don’t have anything like that I might go and create it
Did you try state: started?
I do not have any experience with proxmox, but looks like you can get VM state with
state: current
“If current, the current state of the VM will be fetched. You can access it with results.status.” (see link above). That means you can wait with until keyword (see my first comment).