Ansible playbook for VM deletion with validation - validation

This is the playbook that I have for VM deletion in vCenter.
My requirement here is to add a validation to check if the VM is in "poweredoff" state before proceeding for VM deletion, the task of VM deletion should trigger only if the "VM to be removed" is in "poweredoff" state.
If the "VM to be removed" is in "poweredon" state then it should display an message saying "VM is in powered on state."
Need help in adding validation to playbook, Thanks in advance.
---
# VM Automation Playbook
- name: Remove VM
hosts: localhost
connection: local
gather_facts: no
tasks:
- name: Remove VM
vmware_guest:
hostname: '{{ vcenter_hostname }}' #The hostname or IP address of the vSphere vCenter or ESXi server.
username: '{{ vcenter_username }}'
password: '{{ vcenter_password }}'
validate_certs: False
datacenter: '{{ datacenter_name }}' #Destination datacenter for the deploy operation.
name: '{{ vm_name }}' #Name of the VM to be created.
force: yes
state: absent #Specify the state the virtual machine should be in.

According the Ansible Collection documentation of Community.Vmware you may use the module vmware_vm_info to return basic info pertaining to a VMware machine guest
- name: Get virtual machine info
vmware_vm_info:
hostname: '{{ vcenter_hostname }}'
username: '{{ vcenter_username }}'
password: '{{ vcenter_password }}'
folder: '{{ of_datacenter }}'
validate_certs: no
vm_type: vm
delegate_to: localhost
register: vm_info
- name: Show 'power_state' of {{ vm_name }}
debug:
msg: "{{ item.power_state}}"
with_items:
- "{{ vm_info.virtual_machines | json_query(query) }}"
vars:
query: "[?guest_name=='{{ vm_name }}']"
as the Return Values will have a power_state.
If the "VM to be removed" is in "poweredon" state then it should display an message saying "VM is in powered on state."
Based on that you could proceed further with the result in the module assert.

Related

Ansible Tower how to pass inventory to my playbook variables

I am setting up a vmware job in Ansible Tower to snapshot a list of VM's, ideally, this list should be generated by AWX/Tower from the vSphere dynamic inventory. Inventory is named "lab_vm" in AWX and use either the hostname or the UUID of the VM.
How do I pass this through in my playbook variables file?
---
vars:
vmware:
host: '{{ lookup("env", "VMWARE_HOST") }}'
username: '{{ lookup("env", "VMWARE_USER") }}'
password: '{{ lookup("env", "VMWARE_PASSWORD") }}'
vcenter_datacenter: "dc1"
vcenter_validate_certs: false
vm_name: "EVE-NG"
vm_template: "Win2019-Template"
vm_folder: "Network Labs"
my playbook
---
- name: vm snapshot
hosts: localhost
become: false
gather_facts: false
collections:
- community.vmware
pre_tasks:
- include_vars: vars.yml
tasks:
- name: create snapshot
vmware_guest_snapshot:
# hostname: "{{ host }}"
# username: "{{ user }}"
# password: "{{ password }}"
datacenter: "{{ vcenter_datacenter }}"
validate_certs: False
name: "{{ vm_name }}"
state: present
snapshot_name: "Ansible Managed Snapshot"
folder: "{{ vm_folder }}"
description: "This snapshot is created by Ansible Playbook"
You're going about it backward. Ansible loops through the inventory for you. Use that feature, and delegate the task to localhost:
---
- name: vm snapshot
hosts: all
become: false
gather_facts: false
collections:
- community.vmware
pre_tasks:
- include_vars: vars.yml
tasks:
- name: create snapshot
vmware_guest_snapshot:
datacenter: "{{ vcenter_datacenter }}"
validate_certs: False
name: "{{ inventory_hostname }}"
state: present
snapshot_name: "Ansible Managed Snapshot"
folder: "{{ vm_folder }}"
description: "This snapshot is created by Ansible Playbook"
delegate_to: localhost
I've not used this particular module before, but don't your want snapshot_name to be unique for each guest?

How to stop VM and Validate that VM is stoped using Ansible?

For my Project, I need to create an Ansible script that does the following:
Shut down VM
Checks that vm are not reachable
Create messages that say what VM is still up and what vm is still down.
I wrote the following script for this:
---
# tasks file for start-stop-vm
- name: Stop all VM
community.general.shutdown:
# delay: 60
when: ('webservers' in group_names)
- name: check what vm is still up
ansible.builtin.ping:
register: result
# - name: Output result
# debug:
# var: result
- name: Return the vm that still running
debug:
msg: "Following VM are still up {{ inventory_hostname }}"
when: (result.failed == false)
- name: Return the vm that still running
debug:
msg: "Following VM are down {{ inventory_hostname }}"
when: (result.failed != false)
My question is, is there any better way to do this?
Is this a VMware-based VM? if that's the case, you can use the vmware modules:
- name: "Shuting down using guest tools"
vmware_guest_powerstate:
hostname: "{{ vcenter_ip }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
validate_certs: False
uuid: "{{ vm_facts.instance.hw_product_uuid }}"
state: shutdown-guest
state_change_timeout: 240
force: yes
delegate_to: "localhost"
register: newState
ignore_errors: yes
when: vm_facts.instance.guest_tools_status == "guestToolsRunning"
- name: "Power off from vCenter"
vmware_guest_powerstate:
hostname: "{{ vcenter_ip }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
validate_certs: False
uuid: "{{ vm_facts.instance.hw_product_uuid }}"
state: powered-off
force: yes
delegate_to: "localhost"
ignore_errors: yes
register: newState
First task tries to poweroff the VM using guest tools
Second task tries to poweroff the VM using the poweroff option from VMWare.
After this two steps, you can get current status for the VM to confirm that the actual state is powered off.

How can I create Virtual Machine in ESXI using Ansible?

I have esxi and vcenter installed. I found an ansible playbook online which creates a vm from a template:
---
# create a new VM from a template
- name: VM from template
hosts: localhost
gather_facts: false
connection: local
vars:
vcenter_hostname: vcenter-app
vcenter_user: john#doe
vcenter_pass: blabla6
esxhost: esx-4.cbalo.fr
datastore: VM-PROD-02-NORMAL
vmtemplate: Centos7-template
name: "newvm2"
notes: Ansible Test
dumpfacts: False
tasks:
- name: Create VM from template
vmware_guest:
validate_certs: False
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_user }}"
password: "{{ vcenter_pass }}"
esxi_hostname: "{{ esxhost }}"
datacenter: CD06
folder: Test
name: "{{ name }}"
template: "{{ vmtemplate }}"
disk:
- size_gb: "{{ disk_size | default(17) }}"
type: thin
datastore: "{{ datastore }}"
hardware:
memory_mb: "{{ vm_memory | default(1024) }}"
wait_for_ip_address: True
state: present
register: newvm2
I want to create my VM from ISO. Also, I can't see the network part in that script: is it using the template network (DHCP)? Any help is really appreciated .

Whan can I wait for after rebooting a VmWare VM in Ansible vsphere to ensure the state is booted?

I deploy some low supported OS like Debian 9, Debian 8, Rehhat 6,7, Centos 7.
The IP configuration is unsupported at boot time, so I add only the VLAN/virtual network interface, then I use vmware_vm_shell to configure the OS step by step.
What I'm looking for is a trick to wait for an event like /proc/net/dev exists on remote VM to continue other steps
What I tried so far :
- hosts: localhost
tasks:
- name: Create a virtual machine "{{ vm_name }}"
vmware_guest:
datacenter: '{{ datacenter }}'
hostname: '{{ vcenter }}'
username: "{{ login }}"
password: "{{ passwd }}"
folder: "{{ folder }}"
name: "{{ vm_name }}"
template: '{{ template }}'
cluster: "{{ cluster }}"
state: poweredon
disk:
- size_gb: "{{ disksizeGB }}"
datastore: '{{ datastore }}'
hardware:
memory_mb: '{{ ramsizeMB }}'
num_cpus: '{{ vcpu_num }}'
hotadd_cpu: True
hotremove_cpu: True
hotadd_memory: True
networks: '{{ vlans }}'
#wait_for_ip_address: yes # ERR there's ifaces, but not ip at this time
register: deploy
- name: Wait for server to start
local_action:
module: wait_for
timeout=15
when: deploy.changed
The last wait code block sucks (waiting N seconds) , I would like something smarter.
Any idea ?
If I don't wait, I sometimes get error : fatal: [localhost]: FAILED! => {"changed": false, "msg": "VMWareTools is not installed or is not running in the guest. VMware Tools are necessary to run this module."}
because the VM is not booted. The template have vmware-tools.
https://docs.ansible.com/ansible/2.6/modules/vmware_guest_module.html#vmware-guest-module
https://docs.ansible.com/ansible/latest/modules/vmware_vm_shell_module.html
Ok, found myself :)
- name: wait for server to boot
vmware_vm_shell:
datacenter: '{{ datacenter }}'
hostname: 'vcenter{{ vcenter }}'
username: "{{ login }}"
password: "{{ passwd }}"
validate_certs: False
folder: "{{ folder }}"
vm_id: "{{ vm_name }}"
cluster: "{{ cluster }}"
vm_password: '{{ passwd }}'
vm_username: root
vm_shell: '/bin/sleep'
vm_shell_args: 0
when: deploy.changed and 'debian' in distro
register: has_reboot
until: has_reboot.failed != 'true'
delay: 2
retries: 150

Getting UUID of a VMware Virtual Machine using Ansible

We are working on Ansible Environemt. We wanted to connect to a Newly Deployed VM using its UUUID.
How to Get the UUID of a VMware Virtual Machine using Ansible so that i can establish the connection.
Did you check this link: The UUID Location and Format
It can be accessed by standard SMBIOS scanning software — for example
SiSoftware Sandra or the IBM utility smbios2 [...]
You must use the vmware_guest_facts module first, and retrieve the UUID. However, there are two identified as uuid, so I listed them both. I am assuming that the uuid you want is the instance_uuid.
tasks:
- name: get list of facts
vmware_guest_facts:
hostname: '{{ vc_name }}'
username: '{{ vc_user }}'
password: '{{ vc_pwd }}'
datacenter: "{{ dc_name }}"
name: "{{ vm_name }}"
folder: "{{ dc_folder }}"
validate_certs: False
register: vm_facts
- set_fact:
vm_uuid: "{{ vm_facts.instance.instance_uuid }}"
- debug:
msg: "product uuid hw : {{ vm_facts.instance.hw_product_uuid }}\n instance: {{ vm_facts.instance.instance_uuid }}"
Now continue on in your script and use {{ vm_uuid }} where you need the uuid to the VM.
Ansible module vmware_guest_facts has been deprecated. This will not run in Ansible 2.9. You need to use the vmware_guest_info module instead.
- name: Getting VMWARE UUID
hosts: localhost
gather_facts: false
connection: local
tasks:
- name: Get Virtual Machine info
vmware_guest_info:
validate_certs: no
hostname: "{{ vcenter_hostname }}"
username: "{{ Password }}"
password: "{{ pass }}"
validate_certs: no
datacenter: "{{ datacenter_name }}"
name: "{{ VM_Name }}"
schema: "vsphere"
properties:
delegate_to: localhost
register: vminfo
- debug:
var: vminfo.instance.config.uuid
The above code assumes you know the datacenter the VM is sitting on. If unsure of such you can also run the following code:
- name: Get UUID from given VM Name
block:
- name: Get virtual machine info
vmware_vm_info:
hostname: '{{ vcenter_hostname }}'
username: '{{ vcenter_username }}'
password: '{{ vcenter_password }}'
folder: "/datacenter/vm/folder"
delegate_to: localhost
register: vm_info
- debug:
msg: "{{ item.uuid }}"
with_items:
- "{{ vm_info.virtual_machines | json_query(query) }}"
vars:
query: "[?guest_name=='DC0_H0_VM0']"

Resources