Does vmware_guest have an idempotency issue or do I hold it wrong?

72 views
Skip to first unread message

Jörg Kastning

unread,
Mar 1, 2022, 5:16:36 AM3/1/22
to Ansible Project

Hey folks,

I'm using the vmware_guest module to clone virtual machines (VMs) from a template and customizing them. When running the same playbook with the same parameters/values again while the VMs already exist I would expect that there is nothing to do and task status would just be 'OK'. Instead the task status is 'Changed' every time I run the playbook.

Now, I'm in doubt wether I hold it wrong or is vmware_guest not idempotent?

Here are my `{defaults,tasks}/main.yml`, playbook and output of the playbook run:


~~~
$ cat defaults/main.yml
---
# defaults file for vsphere_provision_lab
vsphere_provision_lab_vc_hostname: "vcenter.example.com"
vsphere_provision_lab_vc_username: "b...@example.com"
vsphere_provision_lab_vc_password: "ThatsASecret"
vsphere_provision_lab_vc_datacenter: "DC"
vsphere_provision_lab_vc_cluster: "vSphere-Cluster"
vsphere_provision_lab_vc_datastore: "DS1"
vsphere_provision_lab_vc_folder: "/ha-datacenter/vm"

vsphere_provision_lab_guests:
  vm1:
    vm_template: rhel8-en
    vm_ram_mb: 512
    vm_vcpu: 1
    vm_net: VLAN123
    vm_ip: 192.168.0.1
    vm_netmask: 255.255.255.0
    vm_gateway: 192.168.0.254
    vm_domain: sub.example.com
    vm_hostname: host1
    vm_dns_servers:
      - 192.168.0.2
      - 192.168.0.3
    vm_dns_suffix:
      - sub.example.com
      - sub2.example.com
      - sub3.example.com
    vm_second_hdd: false
    vm_second_hdd_size_gb: ""
    vm_second_hdd_type: ""
    vm_second_hdd_datastore: ""
    vm_scsi_controller: ""
    vm_unit_number: ""
    vm_scsi_type: ''

  vm2:
    vm_template: rhel8-en
    vm_ram_mb: 1024
    vm_vcpu: 2
    vm_net: VLAN123
    vm_ip: 192.168.0.5
    vm_netmask: 255.255.255.0
    vm_gateway: 192.168.0.254
    vm_domain: sub.example.com
    vm_hostname: host2
    vm_dns_servers:
      - 192.168.0.2
      - 192.168.0.3
    vm_dns_suffix:
      - sub.example.com
      - sub2.example.com
      - sub3.example.com
    vm_second_hdd: true
    vm_second_hdd_size_gb: "10"
    vm_second_hdd_type: "thin"
    vm_second_hdd_datastore: "DS1"
    vm_scsi_controller: "1"
    vm_unit_number: "1"
    vm_scsi_type: 'paravirtual'

$ cat tasks/main.yml
---
# tasks file for vsphere_provision_lab
- name: Clone virtual machines from RHEL template and customize
  vmware_guest:
    hostname: "{{ vsphere_provision_lab_vc_hostname }}"
    username: "{{ vsphere_provision_lab_vc_username }}"
    password: "{{ vsphere_provision_lab_vc_password }}"
    datacenter: "{{ vsphere_provision_lab_vc_datacenter }}"
    cluster: "{{ vsphere_provision_lab_vc_cluster }}"
    datastore: "{{ vsphere_provision_lab_vc_datastore }}"
    validate_certs: no
    state: present
    folder: "{{ vsphere_provision_lab_vc_folder }}"
    template: "{{ item.value.vm_template }}"
    name: "{{ item.key }}"
    hardware:
      memory_mb: "{{ item.value.vm_ram_mb }}"
      num_cpus: "{{ item.value.vm_vcpu }}"
    networks:
      - name: "{{ item.value.vm_net }}"
        ip: "{{ item.value.vm_ip }}"
        netmask: "{{ item.value.vm_netmask }}"
        gateway: "{{ item.value.vm_gateway }}"
    wait_for_ip_address: True
    customization:
      domain: "{{ item.value.vm_domain }}"
      hostname: "{{ item.value.vm_hostname }}"
      dns_servers: "{{ item.value.vm_dns_servers }}"
      dns_suffix: "{{ item.value.vm_dns_suffix }}"
  delegate_to: localhost
  with_dict: "{{ vsphere_provision_lab_guests }}"

- name: Add disks to virtual machine using name
  vmware_guest_disk:
    hostname: "{{ vsphere_provision_lab_vc_hostname }}"
    username: "{{ vsphere_provision_lab_vc_username }}"
    password: "{{ vsphere_provision_lab_vc_password }}"
    datacenter: "{{ vsphere_provision_lab_vc_datacenter }}"
    validate_certs: no
    name: "{{ item.key }}"
    disk:
      - size_gb: "{{ item.value.vm_second_hdd_size_gb }}"
        type: "{{ item.value.vm_second_hdd_type }}"
        datastore: "{{ item.value.vm_second_hdd_datastore }}"
        scsi_controller: "{{ item.value.vm_scsi_controller }}"
        unit_number: "{{ item.value.vm_unit_number }}"
        scsi_type: "{{ item.value.vm_scsi_type }}"
  with_dict: "{{ vsphere_provision_lab_guests }}"
  when: item.value.vm_second_hdd is defined and item.value.vm_second_hdd|bool == true

$ cat vsphere_provision_rhel_lab.yml
---
- hosts: localhost
  connection: local
  gather_facts: no
  vars_files:
    - /some/path/vault.vars
    - roles/vsphere_provision_lab/vars/rhel.yml

  roles:
    - vsphere_provision_lab
~~~

The first playbook run produces the following output:

~~~
$ ansible-playbook --ask-vault-pass vsphere_provision_rhel_lab.yml
Vault password:

PLAY [localhost] ***********************************************************************************************************************************************************************************************************************

TASK [vsphere_provision_lab : Clone virtual machines from RHEL template and customize] *************************************************************************************************************************************************
changed: [localhost -> localhost] => (item=...)
changed: [localhost -> localhost] => (item=...)

TASK [vsphere_provision_lab : Add disks to virtual machine using name] *****************************************************************************************************************************************************************
skipping: [localhost] => (item=...)
changed: [localhost] => (item=...)

PLAY RECAP *****************************************************************************************************************************************************************************************************************************
localhost                  : ok=2    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

# NOW I START  A SECOND RUN

$ ansible-playbook --ask-vault-pass vsphere_provision_rhel_lab.yml
Vault password:

PLAY [localhost] ***********************************************************************************************************************************************************************************************************************

TASK [vsphere_provision_lab : Clone virtual machines from RHEL template and customize] *************************************************************************************************************************************************
changed: [localhost -> localhost] => (item=...)
changed: [localhost -> localhost] => (item=...)

TASK [vsphere_provision_lab : Add disks to virtual machine using name] *****************************************************************************************************************************************************************
skipping: [localhost] => (item=...)
ok: [localhost] => (item=...)

PLAY RECAP *****************************************************************************************************************************************************************************************************************************
localhost                  : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
~~~

I truncated the output for a better overview here. But I checked locally that the values for the task 'vsphere_provision_lab : Clone virtual machines from RHEL template and customize' are the same in both runs and the VMs exist before the second run starts. Why is the status 'changed' and not 'ok' as I would expect?

Kind regards,
Joerg

Jörg Kastning

unread,
Jul 14, 2022, 4:13:17 PM7/14/22
to Ansible Project
Hi there,
I would like to bring this up again. Does somebody have an idea on this?
Reply all
Reply to author
Forward
0 new messages