From e22e7902f53169650f1dc2a3ff4c666535085bc8 Mon Sep 17 00:00:00 2001 From: Danielle Barda Date: Thu, 15 Feb 2024 15:24:09 +0200 Subject: [PATCH] Provisioning VM role --- playbooks/provision_vm/manage_vm.yml | 11 + playbooks/provision_vm/provision_vm.yml | 20 -- .../provisioning_vm_from_template.yml | 11 + .../provision_vm/provisioning_vm_from_vm.yml | 12 + roles/create_vm_template/README.md | 69 +++++ roles/create_vm_template/defaults/main.yml | 1 + .../tasks/clone_template_to_template.yml | 0 .../tasks/clone_vm_to_template.yml | 0 roles/create_vm_template/tasks/main.yml | 5 + roles/provision_vm/README.md | 289 ++++++++++++++++++ roles/provision_vm/defaults/main.yml | 3 + .../tasks/clone_an_existing_vm.yml | 75 +++++ roles/provision_vm/tasks/create_new_vm.yml | 54 ++++ .../tasks/deploy_from_template.yml | 60 ++++ roles/provision_vm/tasks/main.yml | 20 ++ 15 files changed, 610 insertions(+), 20 deletions(-) create mode 100644 playbooks/provision_vm/manage_vm.yml delete mode 100644 playbooks/provision_vm/provision_vm.yml create mode 100644 playbooks/provision_vm/provisioning_vm_from_template.yml create mode 100644 playbooks/provision_vm/provisioning_vm_from_vm.yml create mode 100644 roles/create_vm_template/README.md create mode 100644 roles/create_vm_template/defaults/main.yml create mode 100644 roles/create_vm_template/tasks/clone_template_to_template.yml create mode 100644 roles/create_vm_template/tasks/clone_vm_to_template.yml create mode 100644 roles/create_vm_template/tasks/main.yml create mode 100644 roles/provision_vm/README.md create mode 100644 roles/provision_vm/defaults/main.yml create mode 100644 roles/provision_vm/tasks/clone_an_existing_vm.yml create mode 100644 roles/provision_vm/tasks/create_new_vm.yml create mode 100644 roles/provision_vm/tasks/deploy_from_template.yml create mode 100644 roles/provision_vm/tasks/main.yml diff --git a/playbooks/provision_vm/manage_vm.yml b/playbooks/provision_vm/manage_vm.yml new file mode 100644 index 00000000..ba09fb8a --- /dev/null +++ b/playbooks/provision_vm/manage_vm.yml @@ -0,0 +1,11 @@ +--- +- name: Playbook to provision a new VM on VMware + hosts: all + gather_facts: false + + vars: + clone_from_template: false + clone_from_vm: false + + roles: + - role: redhat_cop.vmware_ops.provisioning_vm diff --git a/playbooks/provision_vm/provision_vm.yml b/playbooks/provision_vm/provision_vm.yml deleted file mode 100644 index 1b7f7d77..00000000 --- a/playbooks/provision_vm/provision_vm.yml +++ /dev/null @@ -1,20 +0,0 @@ -- name: Playbook to provision a VM on VMware - hosts: localhost - gather_facts: false - - tasks: - - name: set connection info - ansible.builtin.set_fact: - connection_args: - vcenter_hostname: "" - vcenter_username: "" - vcenter_password: "" - vcenter_validate_certs: "false" - - - name: Test urlEncoded issue with list datasoruces - vmware.vmware_rest.vcenter_datacenter_info: - vcenter_hostname: "{{ connection_args.vcenter_hostname }}" - vcenter_username: "{{ connection_args.vcenter_username }}" - vcenter_password: "{{ connection_args.vcenter_password }}" - vcenter_validate_certs: "false" - register: create_vsphere_vm_datacenter diff --git a/playbooks/provision_vm/provisioning_vm_from_template.yml b/playbooks/provision_vm/provisioning_vm_from_template.yml new file mode 100644 index 00000000..ca4ab487 --- /dev/null +++ b/playbooks/provision_vm/provisioning_vm_from_template.yml @@ -0,0 +1,11 @@ +--- +- name: Playbook to provision a new VM from template on VMware + hosts: all + gather_facts: false + + vars: + clone_from_template: true + clone_from_vm: false + + roles: + - role: redhat_cop.vmware_ops.provisioning_vm diff --git a/playbooks/provision_vm/provisioning_vm_from_vm.yml b/playbooks/provision_vm/provisioning_vm_from_vm.yml new file mode 100644 index 00000000..bc63c1d7 --- /dev/null +++ b/playbooks/provision_vm/provisioning_vm_from_vm.yml @@ -0,0 +1,12 @@ +--- +- name: Playbook to provision a new VM from an existing VM on VMware + hosts: all + gather_facts: false + + vars: + clone_from_template: false + clone_from_vm: true + + roles: + - role: redhat_cop.vmware_ops.provisioning_vm + diff --git a/roles/create_vm_template/README.md b/roles/create_vm_template/README.md new file mode 100644 index 00000000..2da805a7 --- /dev/null +++ b/roles/create_vm_template/README.md @@ -0,0 +1,69 @@ +Provision virtual machine +================ + +A role to provision a virtual machine, create associated resources if they don’t exist (subnets, vCPU, memory configuration, storage configuration, etc) +This includes cloning and building from VM templates +Boot a VM from these types: +* Windows Server +* RHEL8 +* RHEL9 + + +Requirements +------------ + +vCenter logged in permission + +Role Variables +-------------- + +* **vcenter_hostname** (str): (Required) +* **vcenter_username** (str): (Required) +* **vcenter_password** (str): (Required) +* **vcenter_validate_certs** (str): (Required) +* **provision_virtual_machine_operation** (str): (Required) Operation to perform. Valid values are: + clone_an_existing_vm, clone_template_to_template, clone_vm_to_template, create_new_vm, create_vm_from_template, + deploy_from_template. + +Dependencies +------------ + +N/A + +Example Playbook +---------------- + +All the variables defined in section [Role Variables](#role-variables) can be defined inside the ``vars.yml`` file. + +Create a ``playbook.yml`` file like this: + +``` +--- +- hosts: localhost + gather_facts: true + + tasks: + - name: Provision a VM + ansible.builtin.import_role: + name: cloud.vmware_ops.provision_virtual_machine + vars: + aa: "{{ }}" +``` + +Run the playbook: + +```shell +ansible-playbook playbook.yml -e "@vars.yml" +``` + +License +------- + +GNU General Public License v3.0 or later + +See [LICENCE](https://github.com/ansible-collections/cloud.vmware_ops/blob/main/LICENSE) to see the full text. + +Author Information +------------------ + +- ?? \ No newline at end of file diff --git a/roles/create_vm_template/defaults/main.yml b/roles/create_vm_template/defaults/main.yml new file mode 100644 index 00000000..73b314ff --- /dev/null +++ b/roles/create_vm_template/defaults/main.yml @@ -0,0 +1 @@ +--- \ No newline at end of file diff --git a/roles/create_vm_template/tasks/clone_template_to_template.yml b/roles/create_vm_template/tasks/clone_template_to_template.yml new file mode 100644 index 00000000..e69de29b diff --git a/roles/create_vm_template/tasks/clone_vm_to_template.yml b/roles/create_vm_template/tasks/clone_vm_to_template.yml new file mode 100644 index 00000000..e69de29b diff --git a/roles/create_vm_template/tasks/main.yml b/roles/create_vm_template/tasks/main.yml new file mode 100644 index 00000000..4fc1bd7c --- /dev/null +++ b/roles/create_vm_template/tasks/main.yml @@ -0,0 +1,5 @@ +--- +# vm name or vm template +- name: Create VM or template + ansible.builtin.include_tasks: "clone_vm_to_template.yml" + diff --git a/roles/provision_vm/README.md b/roles/provision_vm/README.md new file mode 100644 index 00000000..6911bab4 --- /dev/null +++ b/roles/provision_vm/README.md @@ -0,0 +1,289 @@ +# Provision virtual machine +A role to provision a virtual machine, create associated resources if they don’t exist (subnets, vCPU, memory configuration, storage configuration, etc) +This includes cloning and building from VM templates. + + +## Requirements +N/A + + +## Role Variables +### Auth +- **provision_vm_username**: (string, Required) + - The vSphere vCenter username. + +- **provision_vm_password**: (string, Required) + - The vSphere vCenter password. + +- **provision_vm_hostname**: (string, Required) + - The hostname or IP address of the vSphere vCenter. + +- **provision_vm_validate_certs** (boolean) + - Allows connection when SSL certificates are not valid. Set to false when certificates are not trusted. + +### Provisioning a VM +- **provision_vm_clone_from_vm** (boolean): + Create from an existing VM + +- **provision_vm_clone_from_template** (boolean): + Create from template VM + +- **provision_vm_vm_name** (string, Required): + +- **provision_vm_uuid** (): + +- **provision_vm_port** (): + +- **provision_vm_proxy_host** (): + +- **provision_vm_proxy_port** (): + +- **provision_vm_cluster** (String): + The cluster name where the virtual machine will run. + +- **provision_vm_esxi_hostname** (string): +- **provision_vm_datacenter** (string): + Destination datacenter for the deploy operation. + This parameter is case sensitive. + Default: "ha-datacenter" + +- **provision_vm_folder** (): + +- **provision_vm_datastore** (string): + Specify datastore or datastore cluster to provision virtual machine. + This parameter takes precedence over disk.datastore parameter. + This parameter can be used to override datastore or datastore cluster setting of the virtual machine when deployed from the template. + Please see example for more usage. + +- **provision_vm_resource_pool** (): +- **provision_vm_template** (): + +- **provision_vm_convert** (string): + Specify convert disk type while cloning template or virtual machine. + Choices: + "thin" + "thick" + "eagerzeroedthick" + +- **provision_vm_linked_clone** (): +- **provision_vm_snapshot_src** (): +- **provision_vm_advanced_settings** (list): + Define a list of advanced settings to be added to the VMX config. + An advanced settings object takes the two fields key and value. + +- **provision_vm_annotation** (string): + A note or annotation to include in the virtual machine. + +- **provision_vm_cdrom** (list): + A list of CD-ROM configurations for the virtual machine. + For ide controller, hot-add or hot-remove CD-ROM is not supported. + + Element keys: + * controller_number (integer) - + For cdrom.controller_type=ide, valid value is 0 or 1. + For cdrom.controller_type=sata, valid value is 0 to 3. + * controller_type (string) - + When set to sata, please make sure cdrom.unit_number is correct and not used by SATA disks. + Choices: + "ide" ← (default) + "sata" + * iso_path (string) - + The datastore path to the ISO file to use, in the form of [datastore1] path/to/file.iso. + Required if type is set iso. + * state (string) - + If set to absent, then the specified CD-ROM will be removed. + Choices: + "present" ← (default) + "absent" + * type (string) - + The type of CD-ROM. + With none the CD-ROM will be disconnected but present. + Choices: + "none" + "client" ← (default) + "iso" + * unit_number (integer) - + For cdrom.controller_type=ide, valid value is 0 or 1. + For cdrom.controller_type=sata, valid value is 0 to 29. + cdrom.controller_number and cdrom.unit_number are mandatory attributes. + +- **provision_vm_customization** (dictionary): + Parameters for OS customization when cloning from the template or the virtual machine, or apply to the existing virtual machine directly. + Not all operating systems are supported for customization with respective vCenter version, please check VMware documentation for respective OS customization. + For supported customization operating system matrix, (see http://partnerweb.vmware.com/programs/guestOS/guest-os-customization-matrix.pdf) + All parameters and VMware object names are case sensitive. + Linux based OSes requires Perl package to be installed for OS customizations. + + Element keys: + * autologon (boolean) - + Auto logon after virtual machine customization. + Specific to Windows customization. + Choices: + false + true + * autologoncount (integer) - + Number of autologon after reboot. + Specific to Windows customization. + Ignored if customization.autologon is unset or set to customization.autologon=false. + If unset, 1 will be used. + * dns_servers (list) - + List of DNS servers to configure. + Common for Linux and Windows customization. + * dns_suffix (list) - + List of domain suffixes, also known as DNS search path. + Default domain parameter. + Common for Linux and Windows customization. + * domain (string) + DNS domain name to use. + Common for Linux and Windows customization. + * domainadmin (string) - + User used to join in AD domain. + Required if customization.joindomain specified. + Specific to Windows customization. + * domainadminpassword (string) - + Password used to join in AD domain. + Required if customization.joindomain specified. + Specific to Windows customization. + * existing_vm (boolean) - + If set to true, do OS customization on the specified virtual machine directly. + Common for Linux and Windows customization. + Choices: + false + true + * fullname (string) - + Server owner name. + Specific to Windows customization. + If unset, “Administrator” will be used as a fall-back. + * hostname (string) - + Computer hostname. + Default is shortened name parameter. + Allowed characters are alphanumeric (uppercase and lowercase) and minus, rest of the characters are dropped as per RFC 952. + Common for Linux and Windows customization. + * hwclockUTC (boolean) - + Specifies whether the hardware clock is in UTC or local time. + Specific to Linux customization. + Choices: + false + true + * joindomain (string) - + AD domain to join. + Not compatible with customization.joinworkgroup. + Specific to Windows customization. + * joinworkgroup (string) - + Workgroup to join. + Not compatible with customization.joindomain. + Specific to Windows customization. + If unset, “WORKGROUP” will be used as a fall-back. + * orgname (string) - + Organisation name. + Specific to Windows customization. + If unset, “ACME” will be used as a fall-back. + * password (string) - + Local administrator password. + If not defined, the password will be set to blank (that is, no password). + Specific to Windows customization. + * productid (string) - + Product ID. + Specific to Windows customization. + * runonce (list) - + List of commands to run at first user logon. + Specific to Windows customization. + * script_text (string) - + Script to run with shebang. + Needs to be enabled in vmware tools with vmware-toolbox-cmd config set deployPkg enable-custom-scripts true + https://docs.vmware.com/en/VMware-vSphere/7.0/com.vmware.vsphere.vm_admin.doc/GUID-9A5093A5-C54F-4502-941B-3F9C0F573A39.html + Specific to Linux customization. + * timezone (string) - + Timezone. + See List of supported time zones for different vSphere versions in Linux/Unix. + Common for Linux and Windows customization. + Windows. + +- **provision_vm_customization_spec** (string): + Unique name identifying the requested customization specification. + This parameter is case sensitive. + If set, then overrides customization parameter values. + +- **provision_vm_customvalues** (list) + Define a list of custom values to set on virtual machine. + A custom value object takes the two fields key and value. + Incorrect key and values will be ignored. + +- **provision_vm_delete_from_inventory** (): +- **provision_vm_disk** (list): + A list of disks to add. + This parameter is case sensitive. + Shrinking disks is not supported. + Removing existing disks of the virtual machine is not supported. + Attributes disk.controller_type, disk.controller_number, disk.unit_number are used to configure multiple types of disk controllers and disks for creating or reconfiguring virtual machine. + + Every element include: + * autoselect_datastore (boolean) - + * controller_number (integer) - + * controller_type (string) - + * datastore (string) - + * disk_mode (string) - + * filename (string) - + * size (string) - + * size_gb (integer) - + * size_kb (integer) - + * size_mb (integer) - + * size_tb (integer) - + * type (string) - + * unit_number (integer) - + +- **provision_vm_encryption** (): +- **provision_vm_force** (): +- **provision_vm_guest_id** (): +- **provision_vm_hardware** (): +- **provision_vm_state** (): +- **provision_vm_state_change_timeout** (): +- **provision_vm_vapp_properties** (): +- **provision_vm_wait_for_customization** (): +- **provision_vm_wait_for_customization_timeout** (): +- **provision_vm_wait_for_ip_address** (): +- **provision_vm_wait_for_ip_address_timeout** (): +- **provision_vm_networks** (): +- **provision_vm_nvdimm** (): +- **provision_vm_use_instance_uuid** (): +- **provision_vm_name_match** (): +- + +## Dependencies + +N/A + +## Example Playbook + +All the variables defined in section [Role Variables](#role-variables) can be defined inside the ``vars.yml`` file. + +Create a ``playbook.yml`` file like this: + +``` +--- +- hosts: localhost + gather_facts: true + + tasks: + - name: Provision a VM + ansible.builtin.import_role: + name: cloud.vmware_ops.provision_virtual_machine + vars: + aa: "{{ }}" +``` + +Run the playbook: + +```shell +ansible-playbook playbook.yml -e "@vars.yml" +``` + +## License + +GNU General Public License v3.0 or later + +See [LICENCE](https://github.com/ansible-collections/cloud.vmware_ops/blob/main/LICENSE) to see the full text. + +## Author Information + +- Ansible Cloud Content Team \ No newline at end of file diff --git a/roles/provision_vm/defaults/main.yml b/roles/provision_vm/defaults/main.yml new file mode 100644 index 00000000..9e0c251f --- /dev/null +++ b/roles/provision_vm/defaults/main.yml @@ -0,0 +1,3 @@ +--- +provision_vm_clone_from_template: false +provision_vm_clone_from_vm: false diff --git a/roles/provision_vm/tasks/clone_an_existing_vm.yml b/roles/provision_vm/tasks/clone_an_existing_vm.yml new file mode 100644 index 00000000..d97ad2cf --- /dev/null +++ b/roles/provision_vm/tasks/clone_an_existing_vm.yml @@ -0,0 +1,75 @@ +--- +- name: Retrieve all the details about the new VM + vmware.vmware_rest.vcenter_vm_info: + vcenter_hostname: "{{ provision_vm_hostname }}" + vcenter_username: "{{ provision_vm_username }}" + vcenter_password: "{{ provision_vm_password }}" + vcenter_validate_certs: "{{ omit if provision_vm_validate_certs is not defined else provision_vm_validate_certs}}" + names: + - "{{ provision_vm_template }}" + register: vms + +- name: Fail when the template VM is not exists + ansible.builtin.fail: + msg: The VM "{{ provision_vm_template }}" from is not exist + when: vms.value | length <1 + +- name: Create or update the VM + community.vmware.vmware_guest: + hostname: "{{ provision_vm_hostname }}" + username: "{{ provision_vm_username }}" + password: "{{ provision_vm_password }}" + validate_certs: "{{ omit if provision_vm_validate_certs is not defined else provision_vm_validate_certs}}" + + port: "{{ omit if provision_vm_port is not defined else provision_vm_port }}" + proxy_host: "{{ omit if provision_vm_proxy_host is not defined else provision_vm_proxy_host }}" + proxy_port: "{{ omit if provision_vm_proxy_port is not defined else provision_vm_proxy_port }}" + + name: "{{ provision_vm_vm_name }}" + uuid: "{{ omit if provision_vm_uuid is not defined else provision_vm_uuid }}" + + # compute resource: + cluster: "{{ omit if provision_vm_cluster not defined else provision_vm_cluster }}" + esxi_hostname: "{{ omit if provision_vm_esxi_hostname is not defined else provision_vm_esxi_hostname}}" + datacenter: "{{ omit if provision_vm_datacenter is not defined else provision_vm_datacenter}}" + folder: "{{ omit if provision_vm_folder is not defined else provision_vm_folder}}" + datastore: "{{ omit if provision_vm_datastore is not defined else provision_vm_datastore}}" + resource_pool: "{{ omit if provision_vm_resource_pool is not defined else provision_vm_resource_pool}}" + + # for cloning VM + template: "{{ provision_vm_template }}" + convert: "{{ omit if provision_vm_convert is not defined else provision_vm_convert }}" + linked_clone: "{{ omit if provision_vm_linked_clone is not defined else provision_vm_linked_clone }}" + snapshot_src: "{{ omit if provision_vm_snapshot_src is not defined else provision_vm_snapshot_src }}" + + # optional: + advanced_settings: "{{ omit if provision_vm_advanced_settings is not defined else provision_vm_advanced_settings}}" + annotation: "{{ omit if provision_vm_annotation is not defined else provision_vm_annotation}}" + cdrom: "{{ omit if provision_vm_cdrom is not defined else provision_vm_cdrom }}" + customization: "{{ omit if provision_vm_customization is not defined else provision_vm_customization }}" + customization_spec: "{{ omit if provision_vm_customization_spec is not defined else provision_vm_customization_spec }}" + customvalues: "{{ omit if provision_vm_customvalues is not defined else provision_vm_customvalues }}" + delete_from_inventory: "{{ omit if provision_vm_delete_from_inventory is not defined else provision_vm_delete_from_inventory }}" + disk: "{{ omit if provision_vm_disk is not defined else provision_vm_disk }}" + encryption: "{{ omit if provision_vm_encryption is not defined else provision_vm_encryption }}" + force: "{{ omit if provision_vm_force is not defined else provision_vm_force }}" + guest_id: "{{ omit if provision_vm_guest_id is not defined else provision_vm_guest_id }}" + hardware: "{{ omit if provision_vm_hardware is not defined else provision_vm_hardware }}" + state: "{{ omit if provision_vm_state is not defined else provision_vm_state}}" + state_change_timeout: "{{ omit if provision_vm_state_change_timeout is not defined else provision_vm_state_change_timeout}}" + vapp_properties: "{{ omit if provision_vm_vapp_properties is not defined else provision_vm_vapp_properties}}" + wait_for_customization: "{{ omit if provision_vm_wait_for_customization is not defined else provision_vm_wait_for_customization}}" + wait_for_customization_timeout: "{{ omit if provision_vm_wait_for_customization_timeout is not defined else provision_vm_wait_for_customization_timeout}}" + wait_for_ip_address: "{{ omit if provision_vm_wait_for_ip_address is not defined else provision_vm_wait_for_ip_address}}" + wait_for_ip_address_timeout: "{{ omit if provision_vm_wait_for_ip_address_timeout is not defined else provision_vm_wait_for_ip_address_timeout}}" + networks: "{{ omit if provision_vm_networks is not defined else provision_vm_networks }}" + nvdimm: "{{ omit if provision_vm_nvdimm is not defined else provision_vm_nvdimm }}" + use_instance_uuid : "{{ omit if provision_vm_use_instance_uuid is not defined else provision_vm_use_instance_uuid }}" + name_match: "{{ omit if provision_vm_name_match is not defined else provision_vm_name_match }}" + + is_template: false + register: my_vm + +- name: Print VM information + ansible.builtin.debug: + var: my_vm \ No newline at end of file diff --git a/roles/provision_vm/tasks/create_new_vm.yml b/roles/provision_vm/tasks/create_new_vm.yml new file mode 100644 index 00000000..32e8d773 --- /dev/null +++ b/roles/provision_vm/tasks/create_new_vm.yml @@ -0,0 +1,54 @@ +--- +- name: Create or update the VM + community.vmware.vmware_guest: + hostname: "{{ provision_vm_hostname }}" + username: "{{ provision_vm_username }}" + password: "{{ provision_vm_password }}" + validate_certs: "{{ omit if provision_vm_validate_certs is not defined else provision_vm_validate_certs}}" + + port: "{{ omit if provision_vm_port is not defined else provision_vm_port }}" + proxy_host: "{{ omit if provision_vm_proxy_host is not defined else provision_vm_proxy_host }}" + proxy_port: "{{ omit if provision_vm_proxy_port is not defined else provision_vm_proxy_port }}" + + name: "{{ provision_vm_vm_name }}" + uuid: "{{ omit if provision_vm_uuid is not defined else provision_vm_uuid }}" + + # compute resource: + cluster: "{{ omit if provision_vm_cluster not defined else provision_vm_cluster }}" + esxi_hostname: "{{ omit if provision_vm_esxi_hostname is not defined else provision_vm_esxi_hostname}}" + datacenter: "{{ omit if provision_vm_datacenter is not defined else provision_vm_datacenter}}" + folder: "{{ omit if provision_vm_folder is not defined else provision_vm_folder}}" + datastore: "{{ omit if provision_vm_datastore is not defined else provision_vm_datastore}}" + resource_pool: "{{ omit if provision_vm_resource_pool is not defined else provision_vm_resource_pool}}" + + # optional + advanced_settings: "{{ omit if provision_vm_advanced_settings is not defined else provision_vm_advanced_settings}}" + annotation: "{{ omit if provision_vm_annotation is not defined else provision_vm_annotation}}" + cdrom: "{{ omit if provision_vm_cdrom is not defined else provision_vm_cdrom }}" + customization: "{{ omit if provision_vm_customization is not defined else provision_vm_customization }}" + customization_spec: "{{ omit if provision_vm_customization_spec is not defined else provision_vm_customization_spec }}" + customvalues: "{{ omit if provision_vm_customvalues is not defined else provision_vm_customvalues }}" + delete_from_inventory: "{{ omit if provision_vm_delete_from_inventory is not defined else provision_vm_delete_from_inventory }}" + disk: "{{ omit if provision_vm_disk is not defined else provision_vm_disk }}" + encryption: "{{ omit if provision_vm_encryption is not defined else provision_vm_encryption }}" + force: "{{ omit if provision_vm_force is not defined else provision_vm_force }}" + guest_id: "{{ omit if provision_vm_guest_id is not defined else provision_vm_guest_id }}" + hardware: "{{ omit if provision_vm_hardware is not defined else provision_vm_hardware }}" + state: "{{ omit if provision_vm_state is not defined else provision_vm_state}}" + state_change_timeout: "{{ omit if provision_vm_state_change_timeout is not defined else provision_vm_state_change_timeout}}" + vapp_properties: "{{ omit if provision_vm_vapp_properties is not defined else provision_vm_vapp_properties}}" + wait_for_customization: "{{ omit if provision_vm_wait_for_customization is not defined else provision_vm_wait_for_customization}}" + wait_for_customization_timeout: "{{ omit if provision_vm_wait_for_customization_timeout is not defined else provision_vm_wait_for_customization_timeout}}" + wait_for_ip_address: "{{ omit if provision_vm_wait_for_ip_address is not defined else provision_vm_wait_for_ip_address}}" + wait_for_ip_address_timeout: "{{ omit if provision_vm_wait_for_ip_address_timeout is not defined else provision_vm_wait_for_ip_address_timeout}}" + networks: "{{ omit if provision_vm_networks is not defined else provision_vm_networks }}" + nvdimm: "{{ omit if provision_vm_nvdimm is not defined else provision_vm_nvdimm }}" + use_instance_uuid: "{{ omit if provision_vm_use_instance_uuid is not defined else provision_vm_use_instance_uuid }}" + name_match: "{{ omit if provision_vm_name_match is not defined else provision_vm_name_match }}" + + is_template: false + register: my_vm + +- name: Print VM information + ansible.builtin.debug: + var: my_vm \ No newline at end of file diff --git a/roles/provision_vm/tasks/deploy_from_template.yml b/roles/provision_vm/tasks/deploy_from_template.yml new file mode 100644 index 00000000..77002144 --- /dev/null +++ b/roles/provision_vm/tasks/deploy_from_template.yml @@ -0,0 +1,60 @@ +--- +- name: Create or update the VM + community.vmware.vmware_guest: + hostname: "{{ provision_vm_hostname }}" + username: "{{ provision_vm_username }}" + password: "{{ provision_vm_password }}" + validate_certs: "{{ omit if provision_vm_validate_certs is not defined else provision_vm_validate_certs}}" + + port: "{{ omit if provision_vm_port is not defined else provision_vm_port }}" + proxy_host: "{{ omit if provision_vm_proxy_host is not defined else provision_vm_proxy_host }}" + proxy_port: "{{ omit if provision_vm_proxy_port is not defined else provision_vm_proxy_port }}" + + name: "{{ provision_vm_vm_name }}" + uuid: "{{ omit if provision_vm_uuid is not defined else provision_vm_uuid }}" + + # compute resource: + cluster: "{{ omit if provision_vm_cluster not defined else provision_vm_cluster }}" + esxi_hostname: "{{ omit if provision_vm_esxi_hostname is not defined else provision_vm_esxi_hostname}}" + datacenter: "{{ omit if provision_vm_datacenter is not defined else provision_vm_datacenter}}" + folder: "{{ omit if provision_vm_folder is not defined else provision_vm_folder}}" + datastore: "{{ omit if provision_vm_datastore is not defined else provision_vm_datastore}}" + resource_pool: "{{ omit if provision_vm_resource_pool is not defined else provision_vm_resource_pool}}" + + # for cloning VM + template: "{{ provision_vm_template }}" + convert: "{{ omit if provision_vm_convert is not defined else provision_vm_convert }}" + linked_clone: "{{ omit if provision_vm_linked_clone is not defined else provision_vm_linked_clone }}" + snapshot_src: "{{ omit if provision_vm_snapshot_src is not defined else provision_vm_snapshot_src }}" + + # optional: + advanced_settings: "{{ omit if provision_vm_advanced_settings is not defined else provision_vm_advanced_settings}}" + annotation: "{{ omit if provision_vm_annotation is not defined else provision_vm_annotation}}" + cdrom: "{{ omit if provision_vm_cdrom is not defined else provision_vm_cdrom }}" + customization: "{{ omit if provision_vm_customization is not defined else provision_vm_customization }}" + customization_spec: "{{ omit if provision_vm_customization_spec is not defined else provision_vm_customization_spec }}" + customvalues: "{{ omit if provision_vm_customvalues is not defined else provision_vm_customvalues }}" + delete_from_inventory: "{{ omit if provision_vm_delete_from_inventory is not defined else provision_vm_delete_from_inventory }}" + disk: "{{ omit if provision_vm_disk is not defined else provision_vm_disk }}" + encryption: "{{ omit if provision_vm_encryption is not defined else provision_vm_encryption }}" + force: "{{ omit if provision_vm_force is not defined else provision_vm_force }}" + guest_id: "{{ omit if provision_vm_guest_id is not defined else provision_vm_guest_id }}" + hardware: "{{ omit if provision_vm_hardware is not defined else provision_vm_hardware }}" + state: "{{ omit if provision_vm_state is not defined else provision_vm_state}}" + state_change_timeout: "{{ omit if provision_vm_state_change_timeout is not defined else provision_vm_state_change_timeout}}" + vapp_properties: "{{ omit if provision_vm_vapp_properties is not defined else provision_vm_vapp_properties}}" + wait_for_customization: "{{ omit if provision_vm_wait_for_customization is not defined else provision_vm_wait_for_customization}}" + wait_for_customization_timeout: "{{ omit if provision_vm_wait_for_customization_timeout is not defined else provision_vm_wait_for_customization_timeout}}" + wait_for_ip_address: "{{ omit if provision_vm_wait_for_ip_address is not defined else provision_vm_wait_for_ip_address}}" + wait_for_ip_address_timeout: "{{ omit if provision_vm_wait_for_ip_address_timeout is not defined else provision_vm_wait_for_ip_address_timeout}}" + networks: "{{ omit if provision_vm_networks is not defined else provision_vm_networks }}" + nvdimm: "{{ omit if provision_vm_nvdimm is not defined else provision_vm_nvdimm }}" + use_instance_uuid: "{{ omit if provision_vm_use_instance_uuid is not defined else provision_vm_use_instance_uuid }}" + name_match: "{{ omit if provision_vm_name_match is not defined else provision_vm_name_match }}" + + is_template: false + register: my_vm + +- name: Print VM information + ansible.builtin.debug: + var: my_vm \ No newline at end of file diff --git a/roles/provision_vm/tasks/main.yml b/roles/provision_vm/tasks/main.yml new file mode 100644 index 00000000..1cf250c7 --- /dev/null +++ b/roles/provision_vm/tasks/main.yml @@ -0,0 +1,20 @@ +--- +- name: Fail if cluster and esxi_hostname both weren't set or both were set + when: ("{{ cluster }}" is defined and "{{ esxi_hostname }}" is defined) or ("{{ cluster }}" is not defined and "{{ esxi_hostname }}" is not defined) + ansible.builtin.fail: + msg: esxi_hostname and cluster are mutually exclusive parameters + +- name: Create VM from template + when: "{{ clone_from_template }}" + ansible.builtin.include_tasks: + file: deploy_from_template.yml + +- name: Create VM from VM + when: "{{ clone_from_vm }}" + ansible.builtin.include_tasks: + file: clone_an_existing_vm.yml + +- name: Create VM from scratch + when: "{{ not clone_from_vm and not clone_from_template }}" + ansible.builtin.include_tasks: + file: create_new_vm.yml \ No newline at end of file