i get the below error when try this as below:
"msg": "Unsupported parameters for (vmware_vm_vm_drs_rule) module: delegate_to Supported parameters include: affinity_rule, cluster_name, drs_rule_name, enabled, hostname, mandatory, password, port, proxy_host, proxy_port, state, username, validate_certs, vms".
I dont want my module to execute when the final_list is empty or less than one object. Only if its more than 2 object in final_list i would want it to execute. Could someone help me with the correct condition
"ansible_facts": {"final_list": [ "NPSY7ADFS01"]}
"ansible_facts": {"final_list": []}
- name: Create DRS Anti Affinity Rule for VM-VM
vmware_vm_vm_drs_rule:
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
cluster_name: "{{ datacenter_name }}-{{ cluster_name }}"
validate_certs: no
vms: "{{ final_list }}"
drs_rule_name: "{{ rule_name }}"
enabled: True
mandatory: True
affinity_rule: "{{ action_type }}"
delegate_to: localhost
register: rule_creation
when: final_list is defined
Q: "Unsupported parameters for (vmware_vm_vm_drs_rule) module: delegate_to ... "
A: The error message is clear: "delegate_to is not a parameter of vmware_vm_vm_drs_rule". The indentation of delegate_to is wrong. This is the reason why delegate_to has been considered a parameter of the module. Fix the indentation of delegate_to
- name: Create DRS Anti Affinity Rule for VM-VM
vmware_vm_vm_drs_rule:
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
cluster_name: "{{ datacenter_name }}-{{ cluster_name }}"
validate_certs: no
vms: "{{ final_list }}"
drs_rule_name: "{{ rule_name }}"
enabled: True
mandatory: True
affinity_rule: "{{ action_type }}"
delegate_to: localhost
register: rule_creation
when: final_list is defined
FWIW. Use ansible-lint to validate the syntax.
Q: "I don't want the module to execute when the final_list is empty."
A: Try this
when: final_list|default([])|length > 0
Related
I have some codes like below, I want to iterate each host in groups['A'] and groups['B'] to create the group.
- name: Create a group
group:
name: "test_group"
state: "present"
delegate_to: "{{ item }}"
vars:
ansible_ssh_user: "{{ lookup('env', 'USER') }}#user#{{ item }}"
with_items:
- "{{ groups['A'] }}"
- "{{ groups['B'] }}"
Because I want to modify the ansible ssh connection user to connect to the "delegate_to" host, I override the ansible_ssh_user in this task, but it won't work and give me the error message like
FAILED! => {"msg": "'item' is undefined"}
But if I comment out the lines of
vars:
ansible_ssh_user: "{{ lookup('env', 'USER') }}#user#{{ item }}"
It gives no errors.
try changing the var to:
ansible_ssh_user: "{{ lookup('env', 'USER') }}#user#{{ ansible_hostname }}
this works fine for me:
- name: 'install public key on every server'
authorized_key:
user: '{{ myuser}}'
key: "{{ myuser.ssh_public_key }}"
delegate_to: '{{ item }}'
with_items:
- '{{ groups["A"] }}'
- '{{ groups["B"] }}'
- '{{ groups["C"] }}'
maybe you could try
but before I delegated a set_fact and recovered it locally...
Finally, I got a workaround, it involves all groups I need to use in my playbook.
And use "when" condition like
delegate_to: "{{ item }}"
with_items:
- "{{ groups['A'] }}"
- "{{ groups['B'] }}"
when: "inventory_hostname == item"
to let the task only run on the hosts mentioned in the "with_items" section.
It's not a very cool workaround but works for me...
Thank you for looking at this problem!
I wrote 2 Ansible playbooks to create and destroy a vm inside an ESXi instance.
The create task is:
- name: Clone the template
delegate_to: localhost
community.vmware.vmware_guest:
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
cluster: "{{ vcenter_cluster_name }}"
datacenter: "{{ vcenter_datacenter_name }}"
folder: "{{ vcenter_datacenter_folder }}"
datastore: "{{ vcenter_datastore }}"
validate_certs: False
name: "{{ inventory_hostname }}"
template: "{{ vm_template }}"
state: poweredon
wait_for_ip_address: yes
networks:
- name: "DSwitch_Dati-VM Network 869"
ip: "{{ ansible_host }}"
netmask: "{{ vm_netmask }}"
gateway: "{{ vm_gateway }}"
start_connected: yes
The delete playbook is:
- name: TMS Cleaner
hosts: all
remote_user: tms
tasks:
- name: Set powerstate of virtual machine to poweroff
delegate_to: localhost
community.vmware.vmware_guest:
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
validate_certs: False
name: "{{ inventory_hostname }}"
state: poweredoff
- name: Remove virtual machine from inventory
delegate_to: localhost
community.vmware.vmware_guest:
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
folder: "{{ vcenter_datacenter_folder }}"
datastore: "{{ vcenter_datastore }}"
validate_certs: False
name: "{{ inventory_hostname }}"
delete_from_inventory: True
state: absent
The creation is correct, while deletion can correctly stop and remove the vm BUT it doeas not remove the folder from the datastore.
What should I do to have a full deletion of all files related to a vm?
If you want to have the files deleted also from datastore you need to remove the following line:
delete_from_inventory: True
The ansible documentation for this module says:
delete_from_inventory:
Choices: Whether to delete Virtual machine from inventory or delete from disk.
no | yes
Only remove that line and files will be deleted from datastore.
In ansible, the vmware_guest_info module will give us a list of the tags on a vm, but does not include any information about those tags:
"tags": [
"10.16.3",
"dicky",
"develop"
],
The vmware_tag_info module gives us a dict withinfo on those tags, including description and Id, but NOT the tags name:
"10.16.3": {
"tag_category_id": "urn:vmomi:InventoryServiceCategory:6eb9d643-8fa3-42a1-8b50-78a1c6e99867:GLOBAL",
"tag_description": "10.16.3",
"tag_id": "urn:vmomi:InventoryServiceTag:ca46ab80-be91-4c3a-8f9f-019d163dd954:GLOBAL",
"tag_used_by": []
},
The vmware_category_info module gives us a list that includes ID and name of a tag.
"tag_category_info": [
{
"category_associable_types": [],
"category_cardinality": "SINGLE",
"category_description": "nodeVersion",
"category_id": "urn:vmomi:InventoryServiceCategory:6eb9d643-8fa3-42a1-8b50-78a1c6e99867:GLOBAL",
"category_name": "nodeVersion",
"category_used_by": []
},
]
So it seems I need to combine the output of three different lists to get the tag value, tag name and tag ID.
I really hope that someone has already done this. If not, can anyone shed some light on how to iterate over the output of vmware_tag_info and vmware_category_info, and find when tag_category_id matches category_id?
How about this?
---
- name: Example playbook
hosts: localhost
gather_facts: no
vars:
vcenter_hostname: change me
vcenter_username: administrator#vsphere.local
vcenter_password: change me
dc1: change me
vm_name: change me
tasks:
- name: Gather tags information
vmware_tag_info:
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
validate_certs: no
register: tags_info_result
- name: Gather tags category information
vmware_category_info:
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
validate_certs: no
register: tags_category_info_result
- name: Set tags_information variable
set_fact:
tags_information: >-
{{ tags_information | default({})
| combine({
item.key: tags_category_info_result.tag_category_info
| selectattr('category_id', '==', item.value.tag_category_id)
| list
| first
| combine(item.value)
| combine({'tag_name': item.key})
})
}}
with_dict: "{{ tags_info_result.tag_facts }}"
- name: Gather VM information
vmware_guest_info:
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
validate_certs: no
datacenter: "{{ dc1 }}"
name: "{{ vm_name }}"
tags: true
register: vm_info_result
- name: Display VM tags information
debug:
msg:
- "tags information about {{ vm_name }}"
- "{{ tags_information[item] }}"
loop: "{{ vm_info_result.instance.tags }}"
when:
- "'tags' in vm_info_result.instance"
Do I have to call hostname,Username and password field for all the individual task that I use with VMware module for Eg: if I call a task for Finding folder of VM and next for snapshot. Do we have an option to get authenticated and then parse token like we do with uri module ?
- name: Find Guest's Folder using name
vmware_guest_find:
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
validate_certs: no
name: "{{ inventory_hostname }}"
delegate_to: localhost
register: vm_folder
You can use module_defaults to achieve what you want.
For instance:
- hosts: localhost
module_defaults:
vmware_guest_find:
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
tasks:
- name: Find Guest's Folder using name
vmware_guest_find:
validate_certs: no
name: "{{ inventory_hostname }}"
I am trying to execute my ansible playbook to launch VMware-windows-server with IP settings, but VM is getting launched but without IP settings.
after executing the playbook am not getting any errors and its shows changes also done, but when i checked in Vmware environment IP is not reflecting.
tried all possible ways, can anyone help me out on this.
thanks
here is my playbook :
---
- hosts: vm-windows-server2012
gather_facts: false
connection: local
vars_files:
- group_vars/vm-windows-server2012
tasks:
- name: "PROVISION | Create Windows server 2012 from template"
vmware_guest:
validate_certs: false
hostname: "{{ vcenter_host }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
datacenter: "{{ datacenter }}"
name: "{{ guest_name }}"
folder: "{{ folder }}"
template: "{{ vmtemplate }}"
state: poweredon
esxi_hostname: "{{ esxi_host }}"
hardware:
num_cpus: "{{ cpu }}"
memory_mb: "{{ mem_mb }}"
disk:
- size_gb: "{{ disk }}"
type: thin
datastore: "{{ datastore }}"
register: new_vm
- name: Wait for VMware tools to become available
vmware_guest_tools_wait:
hostname: "{{ vcenter_host }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
validate_certs: False
name: "{{ vm_name }}"
folder: "/{{ datacenter }}/vm/{{ folder }}"
- name: "IP configuration"
local_action:
module: vmware_vm_shell
hostname: "{{ vcenter_host }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
datacenter: "{{ datacenter }}"
vm_id: "{{ vm_name }}"
vm_username: "{{ v_username }}"
vm_password: "{{ v_password }}"
vm_shell: 'C:\Windows\System32\WindowsPowershell\v1.0\powershell.exe'
vm_shell_args: 'netsh interface ip set address "Ethernet0 2" static 10.193.34.250 255.255.255.192 10.193.34.193'
vm_shell_cwd: 'C:\Users\Administrator'
validate_certs: False
Your code is fine, but you have to wait for the VMWare Tools to be active on the VM in order to use vmware_vm_shell.
Use this before your vmware_vm_shell:
- name: Wait for VMware tools to become available
vmware_guest_tools_wait:
hostname: "{{ vcenter_host }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
validate_certs: False
name: "{{ vm_name }}"
folder: "/{{ vcenter_datacenter }}/vm/{{ default_vm_folder }}"
- name: Change IP Address for Windows Machine
vmware_vm_shell:
hostname: "{{ vcenter_host }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
validate_certs: False
datacenter: "{{ vcenter_datacenter }}"
folder: "/{{ datacenter }}/vm/{{ folder }}"
vm_id: "{{ vm_name }}"
vm_username: "{{ v_username }}"
vm_password: "{{ v_password }}"
vm_shell: netsh.exe
vm_shell_args: ' interface ip set address name="Ethernet0 2" static 10.193.34.250 255.255.255.192 10.193.34.193'
vm_shell_cwd: "C:\\Windows\\System32"
- name: Change DNS for Windows Machine
vmware_vm_shell:
hostname: "{{ vcenter_host }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
validate_certs: False
datacenter: "{{ vcenter_datacenter }}"
folder: "/{{ datacenter }}/vm/{{ folder }}"
vm_id: "{{ vm_name }}"
vm_username: "{{ v_username }}"
vm_password: "{{ v_password }}"
vm_shell : netsh.exe
vm_shell_args : ' interface ip set dns name="Ethernet0 2" static 8.8.8.8'
vm_shell_cwd : "C:\\Windows\\System32"
- name: Wait until the ipaddress of machine is ready
wait_for:
port: 5986
delay: 20
state: started
host: "10.193.34.250"