--- - name: Expand Ubuntu disk in vCenter and inside guest hosts: all gather_facts: yes become: yes vars: disk_unit_number: 0 disk_controller_number: 0 tasks: - name: Gather VM info from vCenter community.vmware.vmware_guest_info: hostname: "{{ vcenter_hostname }}" username: "{{ vcenter_username }}" password: "{{ vcenter_password }}" validate_certs: false datacenter: "{{ vcenter_datacenter }}" name: "{{ vm_name }}" delegate_to: localhost register: vm_info - name: Get current disk size in GB ansible.builtin.set_fact: current_disk_gb: >- {{ ( vm_info.instance.hw_disk | selectattr('controller_number', 'equalto', disk_controller_number) | selectattr('unit_number', 'equalto', disk_unit_number) | map(attribute='capacity_in_kb') | first ) | int // 1024 // 1024 }} - name: Calculate target disk size in GB ansible.builtin.set_fact: target_disk_gb: "{{ current_disk_gb + (increase_gb | int) }}" - name: Show resize plan ansible.builtin.debug: msg: "Disk will be expanded from {{ current_disk_gb }} GB to {{ target_disk_gb }} GB" - name: Expand disk in vCenter community.vmware.vmware_guest_disk: hostname: "{{ vcenter_hostname }}" username: "{{ vcenter_username }}" password: "{{ vcenter_password }}" validate_certs: false datacenter: "{{ vcenter_datacenter }}" name: "{{ vm_name }}" disk: - state: present unit_number: "{{ disk_unit_number }}" controller_number: "{{ disk_controller_number }}" size_gb: "{{ target_disk_gb }}" delegate_to: localhost - name: Rescan SCSI bus ansible.builtin.shell: | for host in /sys/class/scsi_host/host*; do echo "- - -" > "$host/scan" done args: executable: /bin/bash changed_when: true - name: Wait a moment after rescan ansible.builtin.pause: seconds: 5 - name: Detect root source device ansible.builtin.command: findmnt -n -o SOURCE / register: root_source changed_when: false - name: Detect base disk and partition number ansible.builtin.shell: | set -e ROOT_SRC="$(findmnt -n -o SOURCE /)" PKNAME="$(lsblk -no PKNAME "$ROOT_SRC" | head -n1)" PARTNUM="$(lsblk -no PARTN "$ROOT_SRC" | head -n1)" if [ -z "$PKNAME" ]; then PKNAME="$(basename "$(readlink -f "$ROOT_SRC")" | sed 's/[0-9]*$//')" PARTNUM="$(basename "$(readlink -f "$ROOT_SRC")" | grep -o '[0-9]*$')" fi echo "DISK=/dev/${PKNAME}" echo "PARTNUM=${PARTNUM}" args: executable: /bin/bash register: root_layout changed_when: false - name: Parse disk layout ansible.builtin.set_fact: root_disk: "{{ (root_layout.stdout_lines | select('match', '^DISK=') | first).split('=')[1] }}" root_partnum: "{{ (root_layout.stdout_lines | select('match', '^PARTNUM=') | first).split('=')[1] }}" - name: Ensure growpart is installed ansible.builtin.apt: name: cloud-guest-utils state: present update_cache: yes - name: Expand root partition ansible.builtin.command: "growpart {{ root_disk }} {{ root_partnum }}" register: growpart_result changed_when: "'NOCHANGE' not in growpart_result.stdout" failed_when: false - name: Detect filesystem source after partition grow ansible.builtin.command: findmnt -n -o SOURCE / register: root_source_after changed_when: false - name: Detect filesystem type ansible.builtin.command: findmnt -n -o FSTYPE / register: root_fstype changed_when: false - name: Check if root is on LVM ansible.builtin.shell: | lsblk -no TYPE "$(readlink -f {{ root_source_after.stdout | quote }})" | head -n1 args: executable: /bin/bash register: root_dev_type changed_when: false - name: Resize LVM physical volume ansible.builtin.command: "pvresize {{ root_disk }}{{ root_partnum }}" when: root_dev_type.stdout == "lvm" failed_when: false changed_when: true - name: Extend root logical volume and filesystem ansible.builtin.command: "lvextend -r -l +100%FREE {{ root_source_after.stdout }}" when: root_dev_type.stdout == "lvm" changed_when: true - name: Resize ext4 filesystem on non-LVM root ansible.builtin.command: "resize2fs {{ root_source_after.stdout }}" when: - root_dev_type.stdout != "lvm" - root_fstype.stdout in ["ext4", "ext3", "ext2"] changed_when: true - name: Resize xfs filesystem on non-LVM root ansible.builtin.command: "xfs_growfs /" when: - root_dev_type.stdout != "lvm" - root_fstype.stdout == "xfs" changed_when: true - name: Show final disk usage ansible.builtin.command: df -h / register: df_root changed_when: false - name: Print final disk usage ansible.builtin.debug: var: df_root.stdout_lines