community.vmware icon indicating copy to clipboard operation
community.vmware copied to clipboard

vmware_guest - not idempotent

Open Findarato opened this issue 2 years ago • 7 comments

SUMMARY
ISSUE TYPE

When running either a create VM from template or a blank VM the process completes successfully but when run a second time results in an error.

COMPONENT NAME
ANSIBLE VERSION

ansible [core 2.12.5]
  config file = /home/jharry/.ansible.cfg
  configured module search path = ['/home/jharry/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3.10/site-packages/ansible
  ansible collection location = /home/jharry/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/bin/ansible
  python version = 3.10.4 (main, Mar 25 2022, 00:00:00) [GCC 12.0.1 20220308 (Red Hat 12.0.1-0)]
  jinja version = 3.0.3
  libyaml = False


COLLECTION VERSION

# /usr/lib/python3.10/site-packages/ansible_collections
Collection       Version
---------------- -------
community.vmware 1.18.0 

# /home/jharry/.ansible/collections/ansible_collections
Collection       Version
---------------- -------
community.vmware 2.5.0  


CONFIGURATION
ANSIBLE_NOCOWS(env: ANSIBLE_NOCOWS) = True
CACHE_PLUGIN(/home/jharry/.ansible.cfg) = memory
CACHE_PLUGIN_TIMEOUT(/home/jharry/.ansible.cfg) = 86400
COLOR_CHANGED(/home/jharry/.ansible.cfg) = yellow
COLOR_DEBUG(/home/jharry/.ansible.cfg) = dark gray
COLOR_ERROR(/home/jharry/.ansible.cfg) = red
COLOR_OK(/home/jharry/.ansible.cfg) = green
COLOR_WARN(/home/jharry/.ansible.cfg) = bright purple
DEFAULT_EXECUTABLE(/home/jharry/.ansible.cfg) = /bin/bash
DEFAULT_GATHER_TIMEOUT(/home/jharry/.ansible.cfg) = 20
DEFAULT_LOAD_CALLBACK_PLUGINS(/home/jharry/.ansible.cfg) = True
DEFAULT_MANAGED_STR(/home/jharry/.ansible.cfg) = Ansible managed
DEFAULT_PRIVATE_KEY_FILE(/home/jharry/.ansible.cfg) = /home/jharry/.ssh/ansible
DEFAULT_REMOTE_USER(/home/jharry/.ansible.cfg) = ansible
DEFAULT_STDOUT_CALLBACK(/home/jharry/.ansible.cfg) = yaml
DEFAULT_TIMEOUT(/home/jharry/.ansible.cfg) = 20
DEFAULT_VAULT_PASSWORD_FILE(/home/jharry/.ansible.cfg) = /home/jharry/bin/ansiblePass.sh
HOST_KEY_CHECKING(/home/jharry/.ansible.cfg) = False
RETRY_FILES_ENABLED(/home/jharry/.ansible.cfg) = False

OS / ENVIRONMENT
NAME="Fedora Linux"
VERSION="36 (Workstation Edition)"
ID=fedora
VERSION_ID=36
VERSION_CODENAME=""
PLATFORM_ID="platform:f36"
PRETTY_NAME="Fedora Linux 36 (Workstation Edition)"
ANSI_COLOR="0;38;2;60;110;180"
LOGO=fedora-logo-icon
CPE_NAME="cpe:/o:fedoraproject:fedora:36"
HOME_URL="https://fedoraproject.org/"
DOCUMENTATION_URL="https://docs.fedoraproject.org/en-US/fedora/f36/system-administrators-guide/"
SUPPORT_URL="https://ask.fedoraproject.org/"
BUG_REPORT_URL="https://bugzilla.redhat.com/"
REDHAT_BUGZILLA_PRODUCT="Fedora"
REDHAT_BUGZILLA_PRODUCT_VERSION=36
REDHAT_SUPPORT_PRODUCT="Fedora"
REDHAT_SUPPORT_PRODUCT_VERSION=36
PRIVACY_POLICY_URL="https://fedoraproject.org/wiki/Legal:PrivacyPolicy"
VARIANT="Workstation Edition"
VARIANT_ID=workstation
STEPS TO REPRODUCE
    - name: Create VMs 
      community.vmware.vmware_guest:
        annotation: Deployed by Ansible
        hostname: "{{ item.vcenter_ip }}"
        username: "{{ vcenter_username }}"
        password: "{{ vcenter_password }}"
        validate_certs: False
        disk: "{{ item.os }}"
        hardware: "{{ item.hardware }}"
        name: "{{ item.vm_name }} - {{ item.ip }}"
        template: "{{ item.template }}"
        datacenter: "{{ datacenter_name }}"
        folder: "{{ item.folder }}"
        guest_id: "{{ item.guest_id }}"
        state: "{{ item.state }}"
        cluster: "{{ item.cluster_name }}"
        networks: "{{ item.networks }}"
        wait_for_customization: False
        customization: "{{item.customization}}"
      with_items:
        - "{{ vcenter_deploy }}"
EXPECTED RESULTS

Should return ok state because the VM already exists and nothing needs to be changed.

ACTUAL RESULTS
TASK [Create VMs] ************************************************************************************************************************************************************
task path: /home/jharry/Documents/src/Ansible/vmware/DATACENTER_deploy_setup_linuxVM.yml:26
<127.0.0.1> ESTABLISH LOCAL CONNECTION FOR USER: jharry
<127.0.0.1> EXEC /bin/bash -c '( umask 77 && mkdir -p "` echo /tmp/ansible `"&& mkdir "` echo /tmp/ansible/ansible-tmp-1653663939.0918806-29092-269988249311721 `" && echo ansible-tmp-1653663939.0918806-29092-269988249311721="` echo /tmp/ansible/ansible-tmp-1653663939.0918806-29092-269988249311721 `" ) && sleep 0'
Using module file /home/jharry/Documents/src/Ansible/vmware/collections/ansible_collections/community/vmware/plugins/modules/vmware_guest.py
<127.0.0.1> PUT /home/jharry/.ansible/tmp/ansible-local-29006ro65q8yj/tmpilp1ckol TO /tmp/ansible/ansible-tmp-1653663939.0918806-29092-269988249311721/AnsiballZ_vmware_guest.py
<127.0.0.1> EXEC /bin/bash -c 'chmod u+x /tmp/ansible/ansible-tmp-1653663939.0918806-29092-269988249311721/ /tmp/ansible/ansible-tmp-1653663939.0918806-29092-269988249311721/AnsiballZ_vmware_guest.py && sleep 0'
<127.0.0.1> EXEC /bin/bash -c '/usr/bin/env python3 /tmp/ansible/ansible-tmp-1653663939.0918806-29092-269988249311721/AnsiballZ_vmware_guest.py && sleep 0'
<127.0.0.1> EXEC /bin/bash -c 'rm -f -r /tmp/ansible/ansible-tmp-1653663939.0918806-29092-269988249311721/ > /dev/null 2>&1 && sleep 0'
failed: [localhost] (item={'vm_name': 'VM NAME', 'ip': 'IP', 'datacenter': 'DATACENTER', 'cluster_name': 'CLUSTER_NAME', 'dns': 'DNS IP DNS IP', 'folder': '/VM/FOLDER/PATH/', 'guest_id': '', 'state': 'powered-on', 'template': 'CentOS Stream 8', 'username': 'administrator', 'vcenter_ip': 'VCENTER NAME', 'networks': [{'connected': True, 'device_type': 'vmxnet3', 'dns_servers': 'DNS IP DNS IP', 'domain': 'DOMAIN', 'gateway': 'IP 'ip': 'IP', 'netmask': 'NETMASK', 'type': 'static', 'name': 'VLAN'}], 'os': [{'datastore': 'DATASTORE', 'size_gb': 50, 'type': 'thin'}], 'disks': [{'datastore': 'DATASTORE', 'size_gb': 500, 'type': 'thin', 'state': 'present', 'scsi_controller': 0, 'unit_number': 1}, {'datastore': 'DATASTORE', 'size_gb': 500, 'type': 'thin', 'state': 'present', 'scsi_controller': 0, 'unit_number': 2}, {'datastore': 'DATASTORE', 'size_gb': 500, 'type': 'thin', 'state': 'present', 'scsi_controller': 0, 'unit_number': 3}, {'datastore': 'DATASTORE', 'size_gb': 500, 'type': 'thin', 'state': 'present', 'scsi_controller': 0, 'unit_number': 4}, {'datastore': 'DATASTORE', 'size_gb': 500, 'type': 'thin', 'state': 'present', 'scsi_controller': 0, 'unit_number': 5}], 'hardware': {'memory_mb': '16384', 'num_cpus': '8', 'hotadd_cpu': 'True', 'hotremove_cpu': 'True', 'hotadd_memory': 'True', 'scsi': 'lsilogicsas'}, 'customization': {'hostname': 'VM NAME', 'dns_servers': ['IP', 'IP'], 'dns_suffix': 'methnet'}}) => changed=false 
  ansible_loop_var: item
  invocation:
    module_args:
      advanced_settings: []
      annotation: Deployed by Ansible
      cdrom: []
      cluster: CLUSTER_NAME
      convert: null
      customization:
        autologon: null
        autologoncount: null
        dns_servers:
        - DNS IP
        - DNS IP
        dns_suffix:
        - methnet
        domain: null
        domainadmin: null
        domainadminpassword: null
        existing_vm: null
        fullname: null
        hostname: VM NAME
        hwclockUTC: null
        joindomain: null
        joinworkgroup: null
        orgname: null
        password: null
        productid: null
        runonce: null
        timezone: null
      customization_spec: null
      customvalues: []
      datacenter: DATACENTER
      datastore: null
      delete_from_inventory: false
      disk:
      - autoselect_datastore: null
        controller_number: null
        controller_type: null
        datastore: DATASTORE
        disk_mode: null
        filename: null
        size: null
        size_gb: 50
        size_kb: null
        size_mb: null
        size_tb: null
        type: thin
        unit_number: null
      esxi_hostname: null
      folder: /VM/FOLDER/PATH
      force: false
      guest_id: ''
      hardware:
        boot_firmware: null
        cpu_limit: null
        cpu_reservation: null
        hotadd_cpu: true
        hotadd_memory: true
        hotremove_cpu: true
        iommu: null
        max_connections: null
        mem_limit: null
        mem_reservation: null
        memory_mb: 16384
        memory_reservation_lock: null
        nested_virt: null
        num_cpu_cores_per_socket: null
        num_cpus: 8
        scsi: lsilogicsas
        secure_boot: null
        version: null
        virt_based_security: null
      hostname: VCENTER NAME
      is_template: false
      linked_clone: false
      name: VM NAME - IP
      name_match: first
      networks:
      - connected: true
        device_type: vmxnet3
        dns_servers: ip ip
        domain: domain
        gateway: IP
        ip: ip
        name: VLAN
        netmask: NETMASK
        type: static
      nvdimm:
        label: null
        size_mb: 1024
        state: null
      password: VALUE_SPECIFIED_IN_NO_LOG_PARAMETER
      port: 443
      proxy_host: null
      proxy_port: null
      resource_pool: null
      snapshot_src: null
      state: powered-on
      state_change_timeout: 0
      template: CentOS Stream 8
      use_instance_uuid: false
      username: 
      uuid: null
      validate_certs: false
      vapp_properties: []
      wait_for_customization: false
      wait_for_customization_timeout: 3600
      wait_for_ip_address: false
      wait_for_ip_address_timeout: 300
  item:
    cluster_name: CLUSTER_NAME
    customization:
      dns_servers:
      - DNS IP
      - DNS IP
      dns_suffix: methnet
      hostname: VM NAME
    datacenter: DATACENTER
    disks:
    - datastore: DATASTORE
      scsi_controller: 0
      size_gb: 500
      state: present
      type: thin
      unit_number: 1
    - datastore: DATASTORE
      scsi_controller: 0
      size_gb: 500
      state: present
      type: thin
      unit_number: 2
    - datastore: DATASTORE
      scsi_controller: 0
      size_gb: 500
      state: present
      type: thin
      unit_number: 3
    - datastore: DATASTORE
      scsi_controller: 0
      size_gb: 500
      state: present
      type: thin
      unit_number: 4
    - datastore: DATASTORE
      scsi_controller: 0
      size_gb: 500
      state: present
      type: thin
      unit_number: 5
    dns: DNS IP DNS IP
    folder: /VM/FOLDER/PATH/
    guest_id: ''
    hardware:
      hotadd_cpu: 'True'
      hotadd_memory: 'True'
      hotremove_cpu: 'True'
      memory_mb: '16384'
      num_cpus: '8'
      scsi: lsilogicsas
    ip: IP
    networks:
    - connected: true
      device_type: vmxnet3
      dns_servers: DNS IP DNS IP
      domain: methnet.org
      gateway: IP: IP
      name: VLAN NAME
      netmask: NETMASK
      type: static
    os:
    - datastore: DATASTORE
      size_gb: 50
      type: thin
    state: powered-on
    template: CentOS Stream 8
    username: administrator
    vcenter_ip: VCENTER
    vm_name: VM NAME
  msg: 'Failed to create a virtual machine : The name ''VM NAME'' already exists.'

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

Findarato avatar May 27 '22 15:05 Findarato

Files identified in the description: None

If these files are inaccurate, please update the component name section of the description or use the !component bot command.

click here for bot help

ansibullbot avatar May 27 '22 15:05 ansibullbot

We had the same thing recently. In your Folder var, try taking off the trailing / and I suspect it will then be idempotent

folder: /VM/FOLDER/PATH/

change to

folder: /VM/FOLDER/PATH

MallocArray avatar Jun 13 '22 13:06 MallocArray

same here, unfortunately removing the trailing slash doesn't change the situation. All states are not idempotent, tested also with removal.

kubealex avatar Jun 26 '22 09:06 kubealex

I noticed your state is set to powered-on. We have had some really odd behavior with that when you are also configuring other options at the same time, such as it would clone a template, but the customizations wouldn’t actually apply. I couldn’t quite nail down a full reproducible example to open an Issue, but we split out the task to several. One that only has the minimum to create the VM using the template and a state of present, one that changes things that the VM must be powered off for, such as CPU/Memory, one for all other settings like Network and Customizations (customizations power on the VM even when the state is present) and then one to ensure the VM is powered on with state: powered-on.

More tasks, but ensures things happen like we want. I think we also did a block/rescue at the beginning to search for a VM with the specified name and create it only if it was missing, but I believe that was when working with Content Library items.

From: Alessandro @.> Sent: Sunday, June 26, 2022 4:37 AM To: @.> Cc: @.>; @.> Subject: Re: [ansible-collections/community.vmware] vmware_guest - not idempotent (Issue #1332)

same here, unfortunately removing the trailing slash doesn't change the situation. All states are not idempotent, tested also with removal.

— Reply to this email directly, view it on GitHubhttps://github.com/ansible-collections/community.vmware/issues/1332#issuecomment-1166470947, or unsubscribehttps://github.com/notifications/unsubscribe-auth/ACHQZJHVQXAAOUSSFJF3HG3VRAQGXANCNFSM5XEQW6LA. You are receiving this because you commented.Message ID: @.***>

MallocArray avatar Jun 27 '22 01:06 MallocArray

I've been trying to reproduce this issue but couldn't at first. Then I tried:

folder: /VM/FOLDER/PATH/

Just as @MallocArray mentioned, this triggered the issue. Removing the trailing / fixed it again. Btw, including the datacenter in the path also triggered the issue:

folder: DATACENTER/VM/FOLDER/PATH/

Without the trailing / it works.

same here, unfortunately removing the trailing slash doesn't change the situation. All states are not idempotent, tested also with removal.

@kubealex I couldn't reproduce the issue any other way. Maybe you run into a different problem. Does your playbook also fail with 'Failed to create a virtual machine : The name ''VM NAME'' already exists.'?

mariolenz avatar Jun 27 '22 13:06 mariolenz

@Findarato Do you have a trailing / in your folder parameter? And, if so, does it help to remove it?

mariolenz avatar Jun 27 '22 15:06 mariolenz

I've been trying to reproduce this issue but couldn't at first. Then I tried:

folder: /VM/FOLDER/PATH/

Just as @MallocArray mentioned, this triggered the issue. Removing the trailing / fixed it again. Btw, including the datacenter in the path also triggered the issue:

folder: DATACENTER/VM/FOLDER/PATH/

Without the trailing / it works.

same here, unfortunately removing the trailing slash doesn't change the situation. All states are not idempotent, tested also with removal.

@kubealex I couldn't reproduce the issue any other way. Maybe you run into a different problem. Does your playbook also fail with 'Failed to create a virtual machine : The name ''VM NAME'' already exists.'?

Yep..it fails in that exact way. I probably spotted one of the issues, I'll try to work on a PR as soon as I have some spare time.

kubealex avatar Jul 05 '22 07:07 kubealex

Ok I can confirm that with out the slash is idempotent, but with it breaks things. I removed a lot of the logging because it was not needed, as both of the VMs have the exact same config but one has a slash at the end and the other does not.

TASK [Create VMs from Template] *******************************************************************************************************
ok: [localhost] => (item=testStuff-delete)
failed: [localhost] (item=testStuff-delete-slash) => changed=false 
  msg: 'Failed to create a virtual machine : The name ''testStuff-delete-slash - DHCP'' already exists.'

I noticed your state is set to powered-on. We have had some really odd behavior with that when you are also configuring other options at the same time, such as it would clone a template, but the customizations wouldn’t actually apply. I couldn’t quite nail down a full reproducible example to open an Issue, but we split out the task to several. One that only has the minimum to create the VM using the template and a state of present, one that changes things that the VM must be powered off for, such as CPU/Memory, one for all other settings like Network and Customizations (customizations power on the VM even when the state is present) and then one to ensure the VM is powered on with state: powered-on. More tasks, but ensures things happen like we want. I think we also did a block/rescue at the beginning to search for a VM with the specified name and create it only if it was missing, but I believe that was when working with Content Library items. From: Alessandro @.> Sent: Sunday, June 26, 2022 4:37 AM To: @.> Cc: @.>; @.> Subject: Re: [ansible-collections/community.vmware] vmware_guest - not idempotent (Issue #1332) same here, unfortunately removing the trailing slash doesn't change the situation. All states are not idempotent, tested also with removal. — Reply to this email directly, view it on GitHub<#1332 (comment)>, or unsubscribehttps://github.com/notifications/unsubscribe-auth/ACHQZJHVQXAAOUSSFJF3HG3VRAQGXANCNFSM5XEQW6LA. You are receiving this because you commented.Message ID: @.***>

I have actually updated my playbooks to power off and then fix a few things before powering it up again. The networking no matter what I do would stay disconnected. Fixed that before powering on and all is good

    - name: Update VMs Disks
      community.vmware.vmware_guest_disk:
        hostname: "{{ item.vcenter_ip }}"
        username: "{{ vcenter_username }}"
        password: "{{ vcenter_password }}"
        datacenter: "{{ datacenter_name }}"
        validate_certs: False
        disk: "{{ item.disks }}"
        name: "{{ item.vm_name }} - {{ item.ip }}"
      with_items:
        - "{{ vcenter_deploy }}"
      loop_control:
        label: "{{ item.vm_name }}"

    - name: Turn the networking on
      community.vmware.vmware_guest_network:
        hostname: "{{ item.vcenter_ip }}"
        username: "{{ vcenter_username }}"
        password: "{{ vcenter_password }}"
        datacenter: "{{ datacenter_name }}"
        name: "{{ item.vm_name }} - {{ item.ip }}"
        mac_address: "{{ vm_data['results'][0]['instance']['hw_eth0']['macaddress'] }}"
        validate_certs: False
        connected: true
        start_connected: true
      with_items:
        - "{{ vcenter_deploy }}"
      # no_log: true
      loop_control:
        label: "{{ item.vm_name }}"

    - name: Update and Power on
      community.vmware.vmware_guest:
        annotation: Deployed by Ansible
        hostname: "{{ item.vcenter_ip }}"
        username: "{{ vcenter_username }}"
        password: "{{ vcenter_password }}"
        validate_certs: False
        name: "{{ item.vm_name }} - {{ item.ip }}"
        state: poweredon
        networks: "{{ item.networks }}"
      with_items:
        - "{{ vcenter_deploy }}"
      loop_control:
        label: "{{ item.vm_name }}"

Findarato avatar Nov 10 '22 15:11 Findarato