ansible-collections / community.vmware

Ansible Collection for VMware
GNU General Public License v3.0
352 stars 336 forks source link

vmware_guest module fails to set static IP during Windows Server VM deployment #1396

Open lbp-code opened 2 years ago

lbp-code commented 2 years ago
SUMMARY

When using the module 'vmware_guest' to clone and customize a Windows Server 2019 VM, the process fails to set a static IP address. The new VM is deployed as DHCP.

The module configuration also calls a VM Customization Specification. That works perfectly, the new Windows Server VM is enrolled into AD as part of that VM Customization Specification.

This playbook is tested in 3 different vCenter servers in 3 different datacenters. All vCenters servers and ESXi hosts have the same versions.

I see the problem was also reported in the issue https://github.com/ansible/ansible/issues/38715, but it also says that it was fixed in Ansible 2.7.7 In my scenario, the issue is also reproducible in Ansible 2.9.6

Is there something special to be configured in the Windows Server template that I should be aware of?

As I checked here --> http://partnerweb.vmware.com/programs/guestOS/guest-os-customization-matrix.pdf the customization should be possible in our scenario.

By the way, the same playbook used to target the same 3 datacenters but used for deploying CentOS 7 and Ubuntu 20.04 works perfectly. It can set the new VMs with static IP address.

Thanks in advance

As a possibly related question from the info I collected for reporting the issue, how can I make sure to have the last stable release of Ansible core and the VMware collections in Ubuntu 20.04? 'apt update && apt upgrade' didn't bring any newer version of Ansible. I installed Ansible by adding the apt repo 'ppa:ansible/ansible'

Thanks again!

ISSUE TYPE
COMPONENT NAME

vmware_guest

ANSIBLE VERSION
ansible 2.10.7
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/opt/ansible/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/lib/python3.8/dist-packages/ansible
  executable location = /usr/local/bin/ansible
  python version = 3.8.10 (default, Jun 22 2022, 20:18:18) [GCC 9.4.0]
COLLECTION VERSION
$ ansible-galaxy collection list community.general

# /usr/local/lib/python3.8/dist-packages/ansible_collections
Collection        Version
----------------- -------
community.general 2.2.0

# /usr/lib/python3/dist-packages/ansible_collections
Collection        Version
----------------- -------
community.general 4.8.3

$ ansible-galaxy collection list community.vmware

# /usr/local/lib/python3.8/dist-packages/ansible_collections
Collection       Version
---------------- -------
community.vmware 1.8.0

# /usr/lib/python3/dist-packages/ansible_collections
Collection       Version
---------------- -------
community.vmware 1.18.2
CONFIGURATION
$ ansible-config dump --only-changed
DEFAULT_FORKS(/etc/ansible/ansible.cfg) = 50
DEFAULT_HOST_LIST(/etc/ansible/ansible.cfg) = ['/etc/ansible/hosts']
DEFAULT_REMOTE_USER(/etc/ansible/ansible.cfg) = ansible
DEFAULT_ROLES_PATH(/etc/ansible/ansible.cfg) = ['/etc/ansible/roles']
DEPRECATION_WARNINGS(/etc/ansible/ansible.cfg) = False
HOST_KEY_CHECKING(/etc/ansible/ansible.cfg) = False
OS / ENVIRONMENT

Ansible is executed on Ubuntu 20.04

vCenter Server 6.7.0 build 19299595 VMware ESXi 6.7.0 build 18828794 Template to deploy and customize is Windows Server Standard 2019

STEPS TO REPRODUCE

Fill in the variables and execute the playbook

- hosts: localhost
  remote_user: ansible
  become: no
  gather_facts: yes

  vars_files:
    - vars/vcenter_creds.yml

  tasks:
    - name: Clone a virtual machine from Windows template and customize - STATIC IP
      vmware_guest:
        hostname: "{{ vcenter_hostname }}"
        username: "{{ vcenter_username }}"
        password: "{{ vcenter_password }}"
        validate_certs: no
        datacenter: "{{ vcenter_datacenter }}"
        cluster: "{{ vcenter_cluster }}"
        datastore: "{{ vcenter_datastore }}"
        folder: "/{{ vcenter_datacenter }}/vm/{{ vm_folder }}"
        template: "{{ vm_template }}"
        name: "{{ vm_name }}"
        state: poweredon
        convert: thin
        force: yes
        networks:
          - name: '{{ vm_portgroup }}'
            type: static
            ip: "{{ vm_ip_address }}"
            netmask: "{{ vm_netmask }}"
            gateway: "{{ vm_gateway }}"
            allow_guest_control: yes
            start_connected: yes
            dns_servers:
              - "{{ vm_dns1 }}"
              - "{{ vm_dns2 }}"
              - "{{ vm_dns3 }}"
        wait_for_ip_address: yes
        customization_spec: FSD-WindowsServer2019-2022
        wait_for_customization: yes
        annotation: "VM created by {{ vcenter_username }} on {{ ansible_date_time.date }} at {{ ansible_date_time.time }} {{ ansible_date_time.tz }}"
        hardware:
          memory_mb: "{{ vm_memory_mb }}"
          num_cpus: "{{ vm_num_cpus }}"
          num_cpu_cores_per_socket: 2
          nested_virt: yes
      delegate_to: localhost
EXPECTED RESULTS

It is expected the newly deployed Windows Server VM to have a fixed/static IP address

ACTUAL RESULTS

No errors output VM has DHCP setting instead of the defined static IP

lbp-code commented 2 years ago

Hi, I wonder if anyone else is having the same issue.

Summary: When cloning a Windows Server 2019 template and setting static IP address, the new VM is using DHCP instead of the specified static IP address.

Let me know if you need more details, or if you want me to make some tests.

Thanks!

ReinerNippes commented 2 years ago

Similar problem here. (Windows 2019, Ansible 2.9 & 2.12, VMware 7.0U1, VMware collection 2.7)

No customization is done at all. Also when existing_vm: true is set.

We don't use templates. We start an unattended installation with a custom ISO image. The installation works. Nevertheless VMware won't do any any customization.

Are there any logs on the Windows machine to check?

@lbp-code "how can I make sure to have the last stable release of Ansible core and the VMware collections in Ubuntu 20.04"

Did you try to create a Python venv and install ansible via pip install ansible?

lbp-code commented 2 years ago

@ReinerNippes thanks for the hint! I did try it, same results. Does it work for you now?

I ran a new search on the topic, apparently nobody else is experiencing this issue

lorcopotia commented 1 year ago

@lbp-code I'm having the same issue... any updates on this?

simeononsecurity commented 1 year ago

Running into the same issue here @lbp-code

simeononsecurity commented 1 year ago

@lbp-code I'm having the same issue... any updates on this?

I was able to resolve the issue by making sure I had the latest version of the modules downloaded: https://galaxy.ansible.com/community/vmware

darthVikes commented 1 year ago

Also seeing this, and updated to latest verison of community.vmware aka 3.3.0, 3.4.0 both Win2019,2022

simeononsecurity commented 1 year ago

Another issue I ran into is that if another system has the ip assigned even if it is off it'll not set the ip and also not error out.

darthVikes commented 1 year ago

This seems to be very common problem with windows, for whatever reason, I've been finding people are working around it like in this post;

https://stackoverflow.com/questions/51769902/ansible-vmware-windows-server

Hoping though this could be fixed at some point and we wont have to do additional steps, but not sure really where the issue lies. if its with this module, or something underneath.

som-shekhar commented 1 year ago

Try provisioning the VM after removing the customization spec

simeononsecurity commented 1 year ago

Try provisioning the VM after removing the customization spec

That beats the entire purpose of the automations. If you mean for troubleshooting sure. But otherwise..

darthVikes commented 1 year ago

Removing the customization spec made no difference for me.

som-shekhar commented 1 year ago

Removing the customization spec made no difference for me.

Well the workaround is as follows. Follow the steps as follows: (1) Use vmware guest module to provision the VM with the customization spec. (2) Wait for VMWare tools installation to complete (3) Use netsh.exe to change the ip address ( The network adaptor name has to be given in double quotes or else it wont work at all. ) (4) Wait for some time to get the right ip address

Please check the tasks below and let me know if it is working

 -  name: "Provisioning the server(Windows)"
    community.vmware.vmware_guest:
          hostname: "{{ vcenter_hostname }}"
          username: "{{ vcenter_username }}"
          password: "{{ vcenter_password }}"
          validate_certs: False
          name: "{{ vm_hostname  }}"
          template: "{{ template_name }}"
          datacenter: "{{ datacenter}}"
          folder: "{{ folder }}"
          esxi_hostname: "{{ esxi_hostname }}"
          datastore: "{{ datastore }}"
          state: poweredon
          customization_spec: "{{ customization_spec }}"
          wait_for_customization: true
          wait_for_customization_timeout: 3600
          networks: "{{ network_params }}"
          hardware:
            num_cpus: "{{ num_cpu }"
            memory_mb: "{{ memory_mb }}"
          disk:
            #For OS (Operating System)
            - size_gb: "{{ disk1_size }} "
              type: "{{ disk_type }}"
              datastore: "{{ datastore }}"
     delegate_to: localhost
     register: vm_op

- name: "Waiting for VMware Tools installation on server"
  community.vmware.vmware_guest_tools_wait:
    hostname: "{{ vcenter_hostname }}"
    username: "{{ vcenter_username }}"
    password: "{{ vcenter_password }}"
    validate_certs: False
    datacenter: "{{ datacenter }}"
    folder: "{{ folder }}"
    name: "{{ vm_hostname }}"
    timeout: 300
  register: vmware_tools_status

#Adding the below task to assign ip address of the windows machine
- name: "Changing the IP Address"
  vmware_vm_shell:
    hostname: "{{ vcenter_hostname }}"
    username: "{{ vcenter_username }}"
    password: "{{ vcenter_password }}"
    validate_certs: False
    datacenter: "{{ datacenter }}"
    folder: "{{  folder }}"
    vm_id: "{{ vm_hostname }}"
    vm_username: "{{ vm_user_name }}"
    vm_password: "{{ vm_password }}"
    vm_shell: netsh.exe
   **#It is important to have the Ethernet0 to be written in double quotes. Putting in single quotes wont work at all. Please check the right network adaptor in your case**
    vm_shell_args: "interface ip set address name=\"Ethernet0\" static {{ ip_address }} {{ netmask }} {{ gateway_ip }}"
    vm_shell_cwd: "C:\\Windows\\System32"
  delegate_to: localhost
  register: vm_shell_value

- name: "Waiting for the server to have the right ip address"
  community.vmware.vmware_guest_info:
    hostname: "{{ vcenter_hostname }}"
    username: "{{ vcenter_username }}"
    password: "{{ vcenter_password }}"
    validate_certs: False
    datacenter: "{{  datacenter}}"
    name: "{{ server_hostname }}"
    schema: "vsphere"
    properties: [ "guest.ipAddress" ]
  delegate_to: localhost
  register: ip_address_status
  ignore_errors: true
  until: ip_address_status.instance.guest.ipAddress==required_ip_address
  retries: 50
  delay: 5

- debug:
    var: ip_address_status

===

darthVikes commented 1 year ago

Right that was the workaround I had to do as well for now.

som-shekhar commented 1 year ago

Right that was the workaround I had to do as well for now.

Yeah...that is the workaround for now..

lbp-code commented 12 months ago

Thank you @som-shekhar for the workaround. Still waiting for this to get fixed in the VMware Ansible module.

Zombro commented 12 months ago

I experienced this issue as well and traced it down to some misconfiguration in my windows server 2022 template. This solution may or may not be feasible for you depending on the complexity of your base template.

Basically, when you customize a windows VM, a process called 'sysprep' kicks off to handle things like static ip and hostname assignment. You can find the logs on the VM you provisioned at C:\System32\SysPrep\Panther.

For the VM that failed customization, within the sysprep error log, you will probably find something like this:

Microsoft.MicrosoftEdge.Stable_86.0.622.38_neutral__8wekyb3d8bbwe was installed for a user, but not provisioned for all users. This package will not function properly in the sysprep image

... and then sysprep promptly fails out

I traced this issue back to some microsoft documentation: https://learn.microsoft.com/en-us/troubleshoot/windows-client/deployment/sysprep-fails-remove-or-update-store-apps

Apparently, apps provisioned through the microsoft store are relegated to the user account who installed them, which chokes sysprep. 🤷

So, uninstall the offending apps in your base template. In my case these apps were Microsoft.MicrosoftEdge.Stable... and MicrosoftCorporationII.WindowsSubsystemForLinux...

image

After all this, ensure your VM provisions, customizations are applied successfully, and then leverage ansible to reinstall the stuff you need.

Forced to figure this out as part of a vanilla k8s cluster build in vsphere.