I use Ansible to take snapshots of VM in VMware vCenter.
If vcenter only one, then it works fine, but what if there are many vcenter?
How to describe multiple Vmware vCenter in the current role?
My current example for one vcenter:
# cat snapshot.yml
- name: ROLE_update
hosts: all
gather_facts: False
become: yes
become_method: su
become_user: root
vars_files:
- /ansible/vars/privileges.txt
roles:
- role: snapshot
# cat tasks/main.yml
- block:
- name: "Create vmware snapshot of {{ inventory_hostname }}"
vmware_guest_snapshot:
hostname: "{{vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
datacenter: "{{datacenter_name}}"
folder: find_folder.yml
name: "{{inventory_hostname }}"
state: present
snapshot_name: snap check
validate_certs: False
delegate_to: localhost
register: vm_facts
# cat find_folder.yml
- name: Find folder path of an existing virtual machine
hosts: all
gather_facts: False
vars:
ansible_python_interpreter: "/usr/bin/env python3"
tasks:
- name: "Find folder for VM - {{ vm_name }}"
vmware_guest_find:
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
datacenter: "{{ datacenter_name }}"
validate_certs: False
name: "{{ vm_name }}"
delegate_to: localhost
register: vm_facts
# cat vars/main.yml variables declared
vcenter_hostname: <secret>
vcenter_username: <secret>
vcenter_password: <secret>
Thanks!
Is having the variables for the different vcenter in different ".yml" files an option? If so, you could easily call for those variables at runtime execution like:
ansible-playbook your_playbook.yml --extra-vars "your_vcenter_1.yml"
There are other ways i could think of, like using tags in your playbook for each task, and invoke your playbook using a specific tag. On each task with the different tags, on the import_role, you could define the new variables like this:
tasks:
- import_tasks: your_role.yml
vars:
vcenter_hostname: your_vcenter_1
tags:
- vcenter1
Related
I am trying to develop the code for creating multiple VM's using module deploy ovf in Ansible. I've tried to find out with other solution, but, it didn't work out. Here you can see my playbook :
- hosts: localhost
become: yes
gather_facts: false
vars_files:
- vars: vars.yml
tasks:
- name: deploy ovf
vmware_deploy_ovf:
hostname: "{{ hostname }}"
username: "{{ username }}"
password: "{{ password }}"
validate_certs: "{{ validate_certs }}"
datacenter: "{{ datacenter }}"
name: "{{ vm_name }}"
ovf: "{{ ovf_path }}"
cluster: "{{ cluster }}"
wait_for_ip_address: true
inject_ovf_env: false
power_on: no
datastore: "{{ datastore }}"
networks: "{{ vcen_network }}"
disk_provisioning: thin
In variables files, I set "vm_name" as list.
vars.yml
vm_name:
vm-01
vm-02
So I've ran the code with extra variables like this:
ansible-playbook main.yml -e "vm_name=vm-01" -e "vm_name=vm-02".
It's only create vm-02 but not for both. Also, I tried to use "loop" or "with_items", but, it didn't work out.
Please assist, thank you
Yeah. Don't do that. Have the hosts in your inventory, and let Ansible do its thing:
- hosts: all
become: no
gather_facts: false
vars_files:
- vars: vars.yml
tasks:
- name: deploy ovf
vmware_deploy_ovf:
# hostname: "{{ hostname }}" # use environment variables
# username: "{{ username }}" # use environment variables
# password: "{{ password }}" # use environment variables
validate_certs: "{{ validate_certs }}"
datacenter: "{{ datacenter }}"
name: "{{ inventory_hostname }}"
ovf: "{{ ovf_path }}"
cluster: "{{ cluster }}"
wait_for_ip_address: true
inject_ovf_env: false
power_on: no
datastore: "{{ datastore }}"
networks: "{{ vcen_network }}"
disk_provisioning: thin
delegate_to: localhost
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?
I have my ansible playbook which basically create a new Virtual machine from template in esxi what , i have to convert the playbook into roles. I am new to ansible so i don't know how to call my hard coded variables from roles(install)->vars directory .
This is my playbook
---
# 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 }}"
hardware:
memory_mb: "{{ vm_memory | default(1024) }}"
wait_for_ip_address: True
state: present
register: newvm2
I have divide this into my role(install)->tasks->main.yml like this
---
- 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 }}"
hardware:
memory_mb: "{{ vm_memory | default(1024) }}"
wait_for_ip_address: True
state: present
register: newvm2
Then in my main directory i create new file run.yml and include my role
---
# create a new VM from a template
- name: VM from template
hosts: localhost
gather_facts: false
connection: local
roles:
- install
The issue is i don't know how to call vars from roles->vars directory as you can see in my playbook i have hard code variables. I need to get or set the variable in file and call it from that file.
**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"
datacenter: CD06
folder: Test**
Variables in ansible are a set of values that will replace certain place-holders. You supply them when running your playbook and they will "trickle down" if you include roles etc. Check the documentation to find out about variable precedence in ansible.
So what you want to do is to put your variable-assignments in your inventory (you can split out variables in separate files as well, using group_vars) and then use the -i path/to/inventory.yml on your ansible-playbook command.
A structure could look like that:
my-ansible/
roles/
my-role/
tasks/
main.yaml
defaults/
main.yaml # contains default values for your variables
inventory/
inventory.yaml # contains hosts and variable assignments
run.yaml
Then, you can run it like that:
ansible-playbook -i inventory/inventory.yaml run.yaml
Hints:
Don't use my-role/vars as it is very hard to override variable assignments in there. (See variable precedence)
defaults/main.yaml is not necessary, but can be handy for variables you rarely change
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 .
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']"