Day: May 26, 2021
How to add VM-Tags and Custom attributes with Anisble(VMware)
So whether your using cloud or doing in house deploys. Tagging is a used a lot especially in cloud type environments. Which we will cover in later posts.
So a common reason to tag your vm is wanting to have the creation date and the type of server or environment its using, handy for backup solutions & other auditables.
Pre-requisites: Assumed.
Step by Step:
1.Create a roles directory inside /etc/ansible/roles
b.mkdir -p /etc/ansible/roles/ custom-tags-attributes-vmware/defaults
2.Now you want to create a task for the snapshots.
d.Create a file called main.yml
Note: Okay for the custom attributes to work you need to get the MOID, UUID & Folder of the vm by using the vm name. So we need to gather facts about the vm and the set those facts as variables that we can pass to the next tasks.
– name: get list of facts
vmware_guest_facts:
hostname: “{{ vcenter_host }}”
username: “{{ vcenter_username }}”
password: “{{ vcenter_password }}”
name: “{{ inventory_hostname }}”
datacenter: “{{ vcenter_dc }}”
validate_certs: False
delegate_to: localhost
ignore_errors: true
register: vm_facts
Note: So when we use the vmware_guest_facts module to gather the facts about the vm by register the facts to a variable “vm_facts”, which when you run the playbook with –vvvv will spit out the facst you can pass as indicated below.
“hw_folder“: “/SysUnix/Testing“,
“hw_guest_full_name“: “Red Hat Enterprise Linux 7 (64-bit)”,
“hw_guest_ha_state“: true,
“hw_guest_id“: “rhel7_64Guest”,
“hw_interfaces“: [
“eth0”
],
“hw_is_template“: false,
“hw_memtotal_mb“: 2048,
“hw_name“: “v-sits-test4”,
“hw_power_status“: “poweredOn“,
“hw_processor_count“: 2,
“hw_product_uuid“: “4226d4e1-6be8-9447-5ced-b037075e2ffd”,
“hw_version“: “vmx-11”,
“instance_uuid“: “50263518-c95b-c3be-5c77-4e1ea69ec295”,
“ipv4”: “192.168.1.29“,
“ipv6”: null,
“module_hw“: true,
“moid“: “vm-296678”,
“snapshots”: [],
“vimref“: “vim.VirtualMachine:vm-296678”,
“vnc“: {}
Note: Now that we have the UUID, MOID, & Folder. We now want to create static variables for UUID, MOID, & folder by using the previous variable we registered as “vm_facts”, and we want to set them as static variables by setting them as facts we can past to the tasks after. As indicated below. Again setting facts is the same as defining variables in bash. Just ansible way to do it.
– set_fact:
vm_uuid: “{{ vm_facts.instance.instance_uuid }}”
– set_fact:
moid: “{{ vm_facts.instance.moid }}”
– set_fact:
vm_folder: “{{ vm_facts.instance.hw_folder }}”
Note: Now want to use the ansible server date and pass that as a variable so you don’t have to input the date as manual value each time you deploy a new host. So we want to grab the date and setup a static fact and then pass it as its own variable. Like we did above…
– name: Get Date
shell: date +%Y-%m-%d
register: date
delegate_to: localhost
Note: We use shell module to get the date in the format we want, then register the result as the variable {{ date }}. We then set a static fact of the result and create another variable called date with using the result from the above.
– set_fact:
date: “{{ date.stdout }}”
Note: We now want to pass all the fact to the “vmware_guest_custom_attributes” module UUID, MOID, DATE, and Folder indicated as below.
– name: Add multiple virtual machine custom attributes
vmware_guest_custom_attributes:
hostname: “{{ vcenter_host }}”
username: “{{ vcenter_username }}”
password: “{{ vcenter_password }}”
name: “{{ inventory_hostname }}”
datacenter: “{{ vcenter_dc }}”
folder: “{{ vm_folder }}”
uuid: “{{ vm_facts.instance.instance_uuid }}”
moid: “{{ vm_facts.instance.moid }}”
state: present
validate_certs: False
use_instance_uuid: True
attributes:
– name: Creation Date
value: “{{ date }}”
# – name: MyAttribute2 – Note: You can add additional attributes if you wish
# value: test2 – Note: You can add additional attributes if you wish
delegate_to: localhost
register: attributes
Note: Okay so depending on which module you use, some require you to gather facts about the vmware categories. This is just incase you need the cateogory_id which is usually derived from using a REST API in json or other method. The “community.vmware.vmware_category_facts”will be able to pull the info and then you can pass it as a variable or a static value. IF YOU NEED, however this is NOT needed. If you use the “vmware_tag_manager” module”
– name: Gather facts about tag categories
community.vmware.vmware_category_facts:
hostname: “{{ vcenter_host }}”
username: “{{ vcenter_username }}”
password: “{{ vcenter_password }}”
validate_certs: no
delegate_to: localhost
register: all_tag_category_facts
ok: [v-sits-test4] => {
“changed”: false,
“invocation”: {
“module_args“: {
“hostname”: “vmware.nicktailor.com“,
“password”: “VALUE_SPECIFIED_IN_NO_LOG_PARAMETER”,
“port”: 443,
“protocol”: “https”,
“username”: “admin“,
“validate_certs“: false
}
},
“tag_category_facts“: [
{
“category_associable_types“: [
“VirtualMachine“
],
“category_cardinality“: “SINGLE”,
“category_description“: “VM Type – Clone, Decomm, Dev, Prod, SRM, SLM, Template or Test”,
“category_id“: “urn:vmomi:InventoryServiceCategory:f1024eb4-d7d4-49fe-9725-4dcba39fbe3b:GLOBAL”,
“category_name“: “VMType“,
“category_used_by“: []
},
{
“category_associable_types“: [
“VirtualMachine“
],
“category_cardinality“: “SINGLE”,
“category_description“: “Team or Department”,
“category_id“: “urn:vmomi:InventoryServiceCategory:888a0877-5335-4477-9347-6d8de5b3e60e:GLOBAL”,
“category_name“: “Team/Dept”,
“category_used_by“: []
}
]
}
Note: Now that we want to create the tag for the vm using the ““vmware_tag_manager” module. The only variable that is passed from outside the defaults at the inventory_hostname level “host_var/nicktest1” is the {{ vm_tag }} Make sure you have this defined for the role to work properly.
– name: Add tags to a virtual machine
vmware_tag_manager:
hostname: ‘{{ vcenter_host }}’
username: ‘{{ vcenter_username }}’
password: ‘{{ vcenter_password }}’
validate_certs: no
tag_names:
– “{{ vm_tag }}” – passed at the host_var/nicktest1
object_name: “{{ inventory_hostname }}”
object_type: VirtualMachine
state: present
delegate_to: localhost
Note: You will likely have a group_var from you vmdeploy role that you can use for here.
vcenter_username: admin
vcenter_password: should be vault encrypted variable
vcenter_host: vmware.nicktailor.com
vcenter_dc: London
/etc/ansible/inventory/TEST/hosts
Run your playbook: from /etc/ansible
Playbook log:
[root@ansible-server]# ansible-playbook –i inventory/TEST/hosts justcustomattrib.yml –ask-vault-pass –limit=’v-sits-test4′
Vault password:
PLAY [all] **********************************************************************************************************************************
TASK [custom-tags-attributes-vmware : get list of facts] ************************************************************************************
[DEPRECATION WARNING]: The ‘vmware_guest_facts‘ module has been renamed to ‘vmware_guest_info‘. This feature will be removed in version
2.13. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.
ok: [v-sits-test4]
TASK [custom-tags-attributes-vmware : set_fact] *********************************************************************************************
ok: [v-sits-test4]
TASK [custom-tags-attributes-vmware : set_fact] *********************************************************************************************
ok: [v-sits-test4]
TASK [custom-tags-attributes-vmware : set_fact] *********************************************************************************************
ok: [v-sits-test4]
TASK [custom-tags-attributes-vmware : Get Date] *********************************************************************************************
changed: [v-sits-test4]
TASK [custom-tags-attributes-vmware : set_fact] *********************************************************************************************
ok: [v-sits-test4]
TASK [custom-tags-attributes-vmware : Add multiple virtual machine custom attributes] *******************************************************
ok: [v-sits-test4]
TASK [custom-tags-attributes-vmware : Gather facts about tag categories] ********************************************************************
ok: [v-sits-test4]
TASK [custom-tags-attributes-vmware : Add tags to a virtual machine] ************************************************************************
ok: [v-sits-test4]
PLAY RECAP **********************************************************************************************************************************
v-sits-test4 : ok=9 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
How to remove snapshots with Ansible(VMware)
Okay, so lots of folks ask me about this, and there are a number of ways you can do this.
But if you’re using vmware and redhat satellite for central patch management for your redhat environment.
Then depending on how you patch your systems. If you snapshot every group prior to patching. Then this post will be perfect for you.
Process:
Pre-requisites: Assumed.
Step by Step:
1.Create a roles directory inside /etc/ansible/roles
b.mkdir -p /etc/ansible/roles/remove-snapshot/defaults
2.Now you want to create a task for the snapshots.
d.Create a file called main.yml
– name: Login into vCenter and get cookies
delegate_to: localhost
uri:
url: https://{{ vcenter_host }}/rest/com/vmware/cis/session
force_basic_auth: yes
validate_certs: no
method: POST
user: ‘{{ vcenter_username }}’
password: ‘{{ vcenter_password }}’
register: login
Note: Okay so what we want to do is find the virtual machine in vsphere by name and then grab its folder value and pass it as a variable so you don’t need to define it statically in your host_var. The main reason is, say you deployed a vm and months later moved it to another folder, your code will likely have the origin folder which would be annoying, and the ansible documentation doesn’t really cover this approach, you basically figure it out as you do it. So im going to save you all time. Here is how you do it. The below will gather vm_facts based on the inventory_hostname
– name: Find Guest’s Folder using name
vmware_guest_find:
hostname: “{{ vcenter_host }}”
username: “{{ vcenter_username }}”
password: “{{ vcenter_password }}”
validate_certs: no
name: “{{ inventory_hostname }}”
delegate_to: localhost
ignore_errors: true
register: vm_facts
Note: It will than gather those facts and find the folder value. You then register the facts to a variable “vm_facts” Now it will spit out what it finds when you do –vvvv when you do your play. From there you can see the folder setting. You now want to set that that folder setting as its own variable that you can pass to another task as indicated below.
ok: [ansible-server] => {
“changed”: false,
“folders”: [
“/SysUnix/Teststuff“
],
“invocation”: {
“module_args“: {
“datacenter“: null,
“hostname”: “vmware.nicktailor.com“,
“name”: ” ansible-server“,
“password”: “VALUE_SPECIFIED_IN_NO_LOG_PARAMETER”,
“port”: 443,
“proxy_host“: null,
“proxy_port“: null,
“use_instance_uuid“: false,
“username”: “svc_ans“,
“uuid“: null,
“validate_certs“: false
}
}
}
– name: “vm_folder – setting folder value”
set_fact:
folder : “{{ vm_facts.folders }}”
Note: So you can see that the facts has a sub fact called “folders”. We want to pass that by setting that value as its own variable by making it a fact. Ansible way to set variables is setting facts. So we make that value above into a variable “vm_facts.folders” and then pass that into the next task where it asks for folders. This will get around the having to provide the exact folder the vm_resides to create snapshotting for an array of hosts. This section is basically identical to create except the “state” is set to absent
– name: Remove Snapshot
vmware_guest_snapshot:
hostname: “{{ vcenter_host }}”
username: “{{ vcenter_username }}”
password: “{{ vcenter_password }}”
datacenter: “{{ vcenter_dc }}”
validate_certs: no
name: “{{ inventory_hostname }}”
state: absent
snapshot_name: “Ansible Managed Snapshot”
folder: “‘{{ vm_facts.folders }}'”
description: “This snapshot is created by Ansible Playbook”
delegate_to: localhost
Note: You will likely have a group_var from you vmdeploy role that you can use for here.
vcenter_username: admin
vcenter_password: should be vault encrypted variable
vcenter_host: vmware.nicktailor.com
vcenter_dc: London
/etc/ansible/inventory/TEST/hosts
Run your playbook: from /etc/ansible
Playbook log:
[root@ansible-server]# ansible-playbook –i inventory/TEST/hosts justremovevmsnap.yml –ask-vault-pass –limit=’nicktest1‘
Vault password:
PLAY [all] **********************************************************************************************************************************
TASK [remove_snapshot : Login into vCenter and get cookies] *********************************************************************************
ok: [nicktest1]
TASK [remove_snapshot : Find Guest’s Folder using name] *************************************************************************************
ok: [nicktest1]
TASK [remove_snapshot : vm_folder – setting folder value] ***********************************************************************************
ok: [nicktest1]
TASK [remove_snapshot : remove Snapshot] ****************************************************************************************************
ok: [nicktest1]
PLAY RECAP **********************************************************************************************************************************
nicktest1 : ok=4 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Note: This uses the snapshot name to remove as the one you used to create. If another snapshot exists with a different name it will ignore it entirely. If you pass snapshot variable with another name and run the book again, it will remove another snapshot. The same applies to removing snapshots, it will remove based on the name.