How to use Ansible playbook loops to create multiple specific VMware guests on multiple free ESXi hosts using vsphere_guest module.

787 views
Skip to first unread message

Alex Lien

unread,
Feb 10, 2017, 3:01:20 PM2/10/17
to Ansible Project
I am running ansible version 2.2.0.0.  I have several free ESXi hosts.  I would like to create multiple specific guests on each of the free ESXi hosts.  I have tried to use with_dict with guests variables, hoping to loop through an arbitrary pre-defined set of ESXi hosts and guests list.  But I am getting error:

fatal: [esxi1]: FAILED! => {"failed": true, "msg": "the field 'args' has an invalid value, which appears to include a variable that is undefined. The error was: 'list object' has no attribute 'vmname'

Is there a way to have the playbook loop through the list of esxi hosts and guests list.

---
- hosts: all
  connection: local

  vars:
      esxi_user: root
      esxi_password: passwordxyz
      guests:
        esxi1:
          - vmname: vm1
        esxi4:
          - vmname: vm3
          - vmname: vm4
          - vmname: vm5

  tasks:
    - vsphere_guest:
        vcenter_hostname: "{{ item.key }}"
        username: "{{ esxi_user }}"
        password: "{{ esxi_password }}"
        guest: "{{ item.value.vmname }}"
        state: powered_on
        vm_extra_config:
          vcpu.hotadd: yes
          mem.hotadd:  yes
          notes: This is a test VM
        vm_disk:
          disk1:
            size_gb: 20
            type: thin
            datastore: store4
        vm_nic:
          nic1:
            type: vmxnet3
            network: VM01
            network_type: standard
        vm_hardware:
          memory_mb: 2048
          num_cpus: 2
          osid: centos64Guest
          scsi: lsi
          vm_cdrom:
            type: client
        esxi:
          datacenter: ha-datacenter
          hostname: "{{ item.key }}"
      with_dict: "{{ guests }}"

Kai Stian Olstad

unread,
Feb 10, 2017, 4:46:46 PM2/10/17
to ansible...@googlegroups.com
On 10. feb. 2017 10:45, Alex Lien wrote:
> I have tried to use with_dict with guests variables, hoping to loop
> through an arbitrary pre-defined set of ESXi hosts and guests list. But I
> am getting error:
>
> fatal: [esxi1]: FAILED! => {"failed": true, "msg": "the field 'args' has an
> invalid value, which appears to include a variable that is undefined. The
> error was: 'list object' has no attribute 'vmname'
>
> Is there a way to have the playbook loop through the list of esxi hosts and
> guests list.

Yes.

Because of your list under esxi1 and esxi2 you would need to have a loop
in a loop to make it work.
To address them it's item.value.0.vmname, item.value.1.vmname,
item.value.2.vmname and so on.

Loop in a loop is possible, but some what more cumbersome as it involves
include:
One way to do it.

---
- hosts: all
connection: local

vars:
esxi_user: root
esxi_password: passwordxyz
guests:
- esx_host: esxi1
vmname:
- vm1
- esx_host: esxi4
vmname:
- vm3
- vm4
- vm5

tasks:
- vsphere_guest:
vcenter_hostname: "{{ item.0.esx_host }}"
username: "{{ esxi_user }}"
password: "{{ esxi_password }}"
guest: "{{ item.1 }}"
state: powered_on
vm_extra_config:
vcpu.hotadd: yes
mem.hotadd: yes
notes: This is a test VM
vm_disk:
disk1:
size_gb: 20
type: thin
datastore: store4
vm_nic:
nic1:
type: vmxnet3
network: VM01
network_type: standard
vm_hardware:
memory_mb: 2048
num_cpus: 2
osid: centos64Guest
scsi: lsi
vm_cdrom:
type: client
esxi:
datacenter: ha-datacenter
hostname: "{{ item.0.esx_host }}"
with_subelements:
- "{{ guests }}"
- vmname


--
Kai Stian Olstad

Alex Lien

unread,
Feb 16, 2017, 1:36:33 AM2/16/17
to Ansible Project
Hi Kai,

Thank You so much for your help.  The loop works with your suggestions except it seems to run a duplicate task and create a duplicate guest.  This is with a test of 2 ESX hosts.  Is there a way to work around it?

This is what I have in my inventory:

[esxi]
esxi1
esxi4
 
# ansible-playbook --limit esxi cr_guests.yml 

PLAY [all] *********************************************************************

TASK [setup] *******************************************************************
ok: [esxi4]
ok: [esxi1]

TASK [vsphere_guest] ***********************************************************
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: pysphere.resources.vi_exception.VIException: [Task Error]: Another task is already in progress.
failed: [esxi1] (item=({u'esx_host': u'esxi1'}, u'vm1')) => {"failed": true, "item": [{"esx_host": "esxi1"}, "vm1"], "module_stderr": "Traceback (most recent call last):\n  File \"/tmp/ansible_R7ozs3/ansible_module_vsphere_guest.py\", line 1909, in <module>\n    main()\n  File \"/tmp/ansible_R7ozs3/ansible_module_vsphere_guest.py\", line 1897, in main\n    state=state\n  File \"/tmp/ansible_R7ozs3/ansible_module_vsphere_guest.py\", line 1454, in create_vm\n    vm.set_extra_config(vm_extra_config)\n  File \"/usr/lib/python2.7/site-packages/pysphere/vi_virtual_machine.py\", line 1589, in set_extra_config\n    FaultTypes.TASK_ERROR)\npysphere.resources.vi_exception.VIException: [Task Error]: Another task is already in progress.\n", "module_stdout": "", "msg": "MODULE FAILURE"}
changed: [esxi4] => (item=({u'esx_host': u'esxi1'}, u'vm1'))
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: TypeError: Value of unknown type: <class 'pysphere.resources.vi_exception.VIException'>, [Task Error]: The attempted operation cannot be performed in the current state (Powered off).
failed: [esxi4] (item=({u'esx_host': u'esxi4'}, u'vm3')) => {"failed": true, "item": [{"esx_host": "esxi4"}, "vm3"], "module_stderr": "Traceback (most recent call last):\n  File \"/tmp/ansible_lt4K1b/ansible_module_vsphere_guest.py\", line 1909, in <module>\n    main()\n  File \"/tmp/ansible_lt4K1b/ansible_module_vsphere_guest.py\", line 1815, in main\n    module.exit_json(changed=state_result)\n  File \"/tmp/ansible_lt4K1b/ansible_modlib.zip/ansible/module_utils/basic.py\", line 1799, in exit_json\n  File \"/tmp/ansible_lt4K1b/ansible_modlib.zip/ansible/module_utils/basic.py\", line 388, in remove_values\n  File \"/tmp/ansible_lt4K1b/ansible_modlib.zip/ansible/module_utils/basic.py\", line 388, in <genexpr>\n  File \"/tmp/ansible_lt4K1b/ansible_modlib.zip/ansible/module_utils/basic.py\", line 399, in remove_values\nTypeError: Value of unknown type: <class 'pysphere.resources.vi_exception.VIException'>, [Task Error]: The attempted operation cannot be performed in the current state (Powered off).\n", "module_stdout": "", "msg": "MODULE FAILURE"}
changed: [esxi1] => (item=({u'esx_host': u'esxi4'}, u'vm3'))
changed: [esxi4] => (item=({u'esx_host': u'esxi4'}, u'vm4'))
changed: [esxi1] => (item=({u'esx_host': u'esxi4'}, u'vm4'))
changed: [esxi1] => (item=({u'esx_host': u'esxi4'}, u'vm5'))
changed: [esxi4] => (item=({u'esx_host': u'esxi4'}, u'vm5'))
to retry, use: --limit @/root/learn/ansible/cr_guests.retry

PLAY RECAP *********************************************************************
esxi4                    : ok=1    changed=0    unreachable=0    failed=1   
esxi1                    : ok=1    changed=0    unreachable=0    failed=1   

Thanks,
Alex

Kai Stian Olstad

unread,
Feb 16, 2017, 10:26:44 AM2/16/17
to ansible...@googlegroups.com
On 15. feb. 2017 22:13, Alex Lien wrote:
> Hi Kai,
>
> Thank You so much for your help. The loop works with your suggestions
> except it seems to run a duplicate task and create a duplicate guest. This
> is with a test of 2 ESX hosts. Is there a way to work around it?
>
> This is what I have in my inventory:
>
> [esxi]
> esxi1
> esxi4
>
> # ansible-playbook --limit esxi cr_guests.yml
>
> PLAY [all]
> *********************************************************************

Since you inventory contain two hosts it will run the task two times,
one time for each hosts.
You only wanna run it once so in your playbook set "- hosts: localhost"
and remove the line "connection: local"

--
Kai Stian Olstad

Alex Lien

unread,
Feb 16, 2017, 2:57:30 PM2/16/17
to ansible...@googlegroups.com
Hi Kai,

The playbook works perfectly now.  Thanks again for all your help.

Regards,
Alex



--
You received this message because you are subscribed to a topic in the Google Groups "Ansible Project" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/ansible-project/m3bKGT4MIno/unsubscribe.
To unsubscribe from this group and all its topics, send an email to ansible-project+unsubscribe@googlegroups.com.
To post to this group, send email to ansible-project@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ansible-project/23048cd8-06f3-c44f-8861-cf8b6f04d97c%40olstad.com.

For more options, visit https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages