from https://rutgerblom.com/2020/07/27/automated-ubuntu-server-20-04-installation-with-ansible/comment-page-1/?unapproved=7068&moderation-hash=d86dbfe9e37d1983697e666fced34447--comment-7068

note this requires a vcenter server due to the fact the the /ha-datacenter/vm file path is always prepended to any view/crete vmware.guest requests to an esxihost


tasks:

- name: Create working directory on Ansible Controller

  ansible.builtin.file:
    path: "{{ WorkingDir }}"
    state: directory

- name: Check if Ubuntu ISO exists locally on Ansible Controller

  ansible.builtin.stat:
    path: "{{ TempDir }}/{{ UbuntuISO }}"
  register: InstallerFileCheck

- name: Download Ubuntu ISO (if ISO file doesn't exist locally)

  ansible.builtin.get_url:
    url:  "{{ UbuntuISO_URL }}{{ UbuntuISO }}"
    dest: "{{ TempDir }}/{{ UbuntuISO }}"
  when:
    - InstallerFileCheck.stat.exists != true

- name: Mount Ubuntu ISO

  ansible.posix.mount:
    path:   "{{ WorkingDir }}/iso"
    src:    "{{ TempDir }}/{{ UbuntuISO }}"
    fstype: iso9660
    opts:   ro,noauto
    state:  mounted

- name: Copy txt.cfg from Ubuntu ISO

  ansible.builtin.copy: 
    src: "{{ WorkingDir }}/iso/isolinux/txt.cfg"
    dest: "{{ WorkingDir }}/isocopy/isolinux/"
    mode: "666"

- name: Edit txt.cfg to modify append line

  ansible.builtin.replace:
    dest: "{{ WorkingDir }}/isocopy/isolinux/txt.cfg"
    regexp: 'append   initrd=/casper/initrd quiet  ---'
    replace: 'append   initrd=/casper/initrd quiet --- autoinstall ds=nocloud;s=/cdrom/autoinstall/'

- name: Create directory to store user-data and meta-data

  ansible.builtin.file:
    path: "{{ WorkingDir }}/isocopy/autoinstall"
    state: directory

- name: Copy user-data file to directory

  ansible.builtin.template: 
    src: ./Ubuntu_user-data.j2
    dest: "{{ WorkingDir }}/isocopy/autoinstall/user-data"
    mode: "666"

- name: Create empty meta-data file in directory

  ansible.builtin.file:
    path: "{{ WorkingDir }}/isocopy/autoinstall/meta-data"
    state: touch
    mode: "666"

- name: Create custom Ubuntu ISO

  ansible.builtin.command: "xorrisofs -relaxed-filenames -J -R -o {{ TempDir }}/{{ UbuntuNewISO }} -b isolinux/isolinux.bin -c isolinux/boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table {{ WorkingDir }}/iso/ {{ WorkingDir }}/isocopy/"
  args:
    chdir: "{{ WorkingDir }}/isocopy/"

- name: Unmount Ubuntu ISO

  ansible.posix.mount:
    path:   "{{ WorkingDir }}/iso"
    src:    "{{ TempDir }}/{{ UbuntuISO }}"
    fstype: iso9660
    opts:   ro,noauto
    state:  absent

- name: Upload the custom Ubuntu ISO to the vSphere datastore

  community.vmware.vsphere_copy: 
    hostname: "{{ VCenterServer }}"
    username: "{{ vCenterUser }}"
    password: "{{ vCenterPassword }}"
    validate_certs: no
    datacenter: "{{ DataCenter }}"
    src: "{{ TempDir }}/{{ UbuntuNewISO }}" 
    datastore: "{{ Datastore }}"
    path: "{{ DatastoreDir }}/{{ UbuntuNewISO }}"

- name: Deploy Ubuntu VM

  community.vmware.vmware_guest:
    hostname: "{{ VCenterServer }}"
    username: "{{ vCenterUser }}"
    password: "{{ vCenterPassword }}"
    validate_certs: no
    name: "{{ UbuntuVMName }}"
    state: poweredon
    guest_id: ubuntu64Guest
    datacenter: "{{ DataCenter }}"
    datastore: "{{ Datastore }}"
    folder: "{{ VMFolder }}"
    disk:
    - size_gb: "{{ UbuntuVMDiskSize }}"
      type: thin
      datastore: "{{ Datastore }}"
    hardware:
      memory_mb: "{{ UbuntuVMMemorySize }}"
      num_cpus: "{{ UbuntuVMCPUs }}"
      num_cpu_cores_per_socket: "{{ UbuntuVMCPUCores }}"
      scsi: paravirtual
    networks:
      - name: "{{ UbuntuVMPortGroup }}"
        device_type: vmxnet3
    cdrom:
      - controller_number: 0
        unit_number: 0
        type: iso
        iso_path: "[{{ Datastore }}] {{ DatastoreDir }}/{{ UbuntuNewISO }}"
        state: present
    annotation: | 
                *** Auto-Deployed by Ansible ***
                Username: {{ UbuntuOSUser }}
                Password: {{ UbuntuOSPassword }}

- name: Start checking if the Ubuntu VM is ready

  community.vmware.vmware_guest_info:
    hostname: "{{ VCenterServer }}"
    username: "{{ vCenterUser }}"
    password: "{{ vCenterPassword }}"
    datacenter: "{{ DataCenter }}"
    validate_certs: no
    name: "{{ UbuntuVMName }}"
    schema: vsphere
  register: vm_facts
  until: vm_facts.instance.guest.hostName is search(UbuntuOSHostname)
  retries: 30
  delay: 60

- name: Set password for the Ubuntu user

  community.vmware.vmware_vm_shell:
    hostname: "{{ VCenterServer }}"
    username: "{{ vCenterUser }}"
    password: "{{ vCenterPassword }}"
    validate_certs: no
    vm_id: "{{ UbuntuVMName }}"
    vm_username: "{{ UbuntuOSUser }}"
    vm_password: VMware1!
    vm_shell: /usr/bin/echo
    vm_shell_args: "'{{ UbuntuOSUser }}:{{ UbuntuOSPassword}}' | sudo chpasswd"

- name: Copy network configuration file to working directory

  ansible.builtin.template: 
    src: ./Ubuntu_Netplan.j2
    dest: "{{ WorkingDir }}/00-installer-config.yaml"
    mode: "666"

- name: Copy network configuration file to Ubuntu VM

  community.vmware.vmware_guest_file_operation:
    hostname: "{{ VCenterServer }}"
    username: "{{ vCenterUser }}"
    password: "{{ vCenterPassword }}"
    validate_certs: no
    vm_id: "{{ UbuntuVMName }}"
    vm_username: "{{ UbuntuOSUser }}"
    vm_password: VMware1!
    copy:
        src: "{{ WorkingDir }}/00-installer-config.yaml"
        dest: "/home/{{ UbuntuOSUser }}/00-installer-config.yaml"

- name: Move network configuration file to right location on Ubuntu VM

  community.vmware.vmware_vm_shell:
    hostname: "{{ VCenterServer }}"
    username: "{{ vCenterUser }}"
    password: "{{ vCenterPassword }}"
    validate_certs: no
    vm_id: "{{ UbuntuVMName }}"
    vm_username: "{{ UbuntuOSUser }}"
    vm_password: VMware1!
    vm_shell: /usr/bin/sudo
    vm_shell_args: "mv /home/{{ UbuntuOSUser }}/00-installer-config.yaml /etc/netplan/00-installer-config.yaml"

- name: Appply the network configuration on Ubuntu VM

  community.vmware.vmware_vm_shell:
    hostname: "{{ VCenterServer }}"
    username: "{{ vCenterUser }}"
    password: "{{ vCenterPassword }}"
    validate_certs: no
    vm_id: "{{ UbuntuVMName }}"
    vm_username: "{{ UbuntuOSUser }}"
    vm_password: VMware1!
    vm_shell: /usr/bin/sudo
    vm_shell_args: netplan apply

- name: Delete working directory on Ansible Controller

  ansible.builtin.file:
    path: "{{ WorkingDir }}"
    state: absent