How to change vmware network adapter with ansible - ansible

Im using ansible 2.9.2, i need to replace network adapter on vmware specific vm.
In my vcenter vm settings i see :
Networks: Vlan_12
My playbook doesnt see that network name.
tasks:
- name: Changing network adapter
vmware_guest_network:
datacenter: "{{ datacenter"}}
hostname: "{{ vcenter_server }}"
username: "{{ vcenter_user }}"
password: "{{ vcenter_pass }}"
folder: "{{ folder }}"
cluster: "{{ cluster }}"
validate_certs: no
name: test
networks:
- name: "Vlan_12"
vlan: "Vlan_12"
connected: false
state: absent
register: output
I get this error:
fatal: [localhost]: FAILED! => {"changed": false, "msg": "Network 'Vlan_12' does not exist."}
Im trying to replace vlan_12 with another network adapter named Vlan_13, so i tried first to delete the exsisting network adapter. in ansible docs they have a very limited examples.
Thanks.

You dont have to poweroff the machine while addin/removing networks.
You can remove/add nic on the fly, well at least on linux vm's not sure about Win vm's.

Changing networks live works just fine. All you need is state: present, the label of your current interface (almost certainly 'Network adapter 1', which is the default for the first network interface), and the name of the port group that you'd like to connect to this interface.
Here's the playbook I've been using:
---
- hosts: localhost
gather_facts: no
tasks:
- name: migrate network
vmware_guest_network:
hostname: '{{ vcenter_hostname }}'
username: '{{ vcenter_username }}'
password: '{{ vcenter_password }}'
datacenter: '{{ datacenter }}'
validate_certs: False
name: '{{ vm_hostname }}'
gather_network_info: False
networks:
- state: present
label: "Network adapter 1"
name: '{{ new_net_name }}'
delegate_to: localhost

You need vmware specific machine to be powerdoff so you can change network adapter:
tasks:
- name: Changing network adapter
vmware_guest_network:
datacenter: "{{ datacenter"}}
hostname: "{{ vcenter_server }}"
username: "{{ vcenter_user }}"
password: "{{ vcenter_pass }}"
folder: "{{ folder }}"
cluster: "{{ cluster }}"
validate_certs: no
name: test
networks:
- name: "Vlan_12"
label: "Network adapter 1"
connected: False
state: absent
- label: "Network adapter 1"
state: new
connected: True
name: Vlan_13
This playbook deletes the present network adapter and the it adds the new adapter instead. i couldnt find a way to change. only delete and add.

Related

Ansible - vmware: how to find a guest on a multiple hosts vcenter?

One of the many Ansible Community.VMWare modules parameters is 'hostname', which is the name of the ESXi server.
In my case, a guest could be in one of multiple ESXi servers (8, for now), and also a new server could be added by the support team at any time.
Is there a way to find on which ESXi server a guest is? Or is it mandatory that I know this at start?
I could have a list of the ESXi servers, keep updating it on demand, and loop over this list using module 'community.vmware.vmware_guest_find' and "with_items", but actually, I don't know how would I do this (iterate over the servers, changing the 'hostname', and stopping when I finally find the guest).
Any help?
I came up with this solution below. It's necessary to have previously the list of ESXi hosts.
[...]
vars:
vcenters_hostname:
- vcenter01
- vcenter02
- ...
[...]
- block:
- name: Navigate throughout all vcenters looking for the guest
community.vmware.vmware_guest_find:
hostname: "{{ item }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
name: "{{ guest_name }}"
validate_certs: no
delegate_to: localhost
register: guest_find_result
with_items: "{{ vcenter_hostnames }}"
rescue:
- name: Doing nothing only to don't raise a fail message
meta: noop
always:
- name: Record which vcenter and folder is the guest
ansible.builtin.set_fact:
guest_folder: "{{ item['folders'][0] }}"
vcenter_hostname: "{{ item['item'] }}"
with_items: "{{ guest_find_result['results'] }}"
when: item['failed'] == false

Multi VM Create using ansible playbook from Templates

Problem Statement:
while trying to create a VM from a template especially in the case of a windows OS template(working fine for linux OS template). VM after being created through ansible playbook is "powered off".
Here is my playbook to create multiple VMS from template, please help me in making this playbook more efficient...thanks in advance.
---
- name: Create a multiple VMs asynchronously
hosts: localhost
connection: local
gather_facts: no
tasks:
- name: Clone the template
vmware_guest:
hostname: xxx.xxx.xx
username: username
password: password
validate_certs: False
name: "{{ item }}"
template: Template-Win-2016
cluster: cluster
datacenter: Dev and QA DC
folder: /
state: poweredon
hardware:
memory_mb: 12288
num_cpus: 4
disk:
- size_gb: 60
type: thin
autoselect_datastore: True
wait_for_ip_address: yes
with_items:
- testvm001
- testvm002
register: vm_create
async: 600
poll: 0
- name: Waiting for status
async_status:
jid: "{{ item.ansible_job_id }}"
register: job_result
until: job_result.finished
delay: 60
retries: 60
with_items: "{{ vm_create.results }}"

Ansible | Deploy VM then run additional playbooks against new host?

I am fairly new to Ansible. I have created an Ansible role that contains the following tasks that will deploy a vm from a template, then configure the VM with custom OS settings:
create-vm.yml
configure-vm.yml
I can successfully deploy a VM from a template via the "create-vm" task. But after that is
complete, I would like to continue with the "configure-vm" task. Since the playbooks/role-vm-deploy.yml file contains "localhost" as shown here...
- hosts: localhost
roles:
- vm-deploy
gather_facts: no
connection: local
... the next task doesn't run successfully because it is attempting to run the task against "localhost" and not the new VM hostname. I have since added the following to the end of the "create-vm" task...
- name: Add host to group 'just_created'
add_host:
name: '{{ hostname }}.{{ domain }}'
groups: just_created
...but I'm not quite sure what to do with it. I can't quite wrap my head around what else I need to do and how to call the new hostname in the "configure-vm" task instead of localhost.
I am executing the playbook via CLI
# ansible-playbook playbooks/role-vm-deploy.yml
I saw this post, which was kind of helpful
I also saw the dynamic inventory documentation, but it's a bit over my head at this juncture. Any help would be appreciated. Thank you!
Here are the contents for the playbooks and tasks
### playbooks -> role-vm-deploy.yml
- hosts: localhost
roles:
- vm-deploy
gather_facts: no
connection: local
### roles -> vm-deploy -> tasks -> main.yml
- name: Deploy VM
include: create-vm.yml
tags:
- create-vm
- name: Configure VM
include: configure-vm.yml
tags:
- configure-vm
### roles -> vm-deploy -> tasks -> create-vm.yml
- name: Clone the template
vmware_guest:
hostname: '{{ vcenter_hostname }}'
username: '{{ vcenter_username }}'
password: '{{ vcenter_pwd }}'
validate_certs: False
name: '{{ hostname }}'
template: '{{ template_name }}'
datacenter: '{{ datacenter }}'
folder: '/'
hardware:
memory_mb: '{{ memory }}'
num_cpus: '{{ num_cpu }}'
networks:
- label: "Network adapter 1"
state: present
connected: True
name: '{{ vlan }}'
state: poweredon
wait_for_ip_address: yes
### roles -> vm-deploy -> tasks -> configure-vm.yml
### This task is what I need to execute on the new hostname, but it attempts to execute on "localhost" ###
# Configure Networking
- name: Configure IP Address
lineinfile:
path: '{{ network_conf_file }}'
regexp: '^IPADDR='
line: 'IPADDR={{ ip_address }}'
- name: Configure Gateway Address
lineinfile:
path: '{{ network_conf_file }}'
regexp: '^GATEWAY='
line: 'GATEWAY={{ gw_address }}'
### roles -> vm-deploy -> defaults -> main.yml
- All of the variables reside here including "{{ hostname }}.{{ domain }}"
You got so close! The trick is to observe that a playbook is actually a list of plays (the yaml objects that are {"hosts": "...", "tasks": []}), and the targets of subsequent plays don't have to exist when the playbook starts -- presumably for this very reason. Thus:
- hosts: localhost
roles:
- vm-deploy
gather_facts: no
connection: local
# or wherever you were executing this -- it wasn't obvious from your question
post_tasks:
- name: Add host to group 'just_created'
add_host:
name: '{{ hostname }}.{{ domain }}'
groups: just_created
- hosts: just_created
tasks:
- debug:
msg: hello from the newly created {{ inventory_hostname }}

Boot Virtual Machine using Ansible

I am using Ansible to deploy VM.
My playbook looks like this
- name: Create a virtual machine on given ESXi hostname
This is the VMware guest module provided by Ansible:
vmware_guest:
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
validate_certs: no
folder: /DC1/vm/
name: test_vm_0001
state: poweredon
guest_id: centos64Guest
This is the hostname of a particular ESXi server on which the user wants a VM to be deployed
esxi_hostname: "{{ esxi_hostname }}"
This is the hardware and network information:
disk:
- size_gb: 10
type: thin
datastore: datastore1
hardware:
memory_mb: 512
num_cpus: 4
scsi: paravirtual
networks:
- name: VM Network
mac: aa:bb:dd:aa:00:14
ip: 10.10.10.100
netmask: 255.255.255.0
device_type: vmxnet3
cdrom:
type: iso
iso_path: "[datastore1] livecd.iso"
wait_for_ip_address: yes
delegate_to: localhost
register: deploy_vm
But how should I provide Booting (i.e username/press enter/password) information i.e boot process. How should I automate this process after the VM is deployed on the ESXi server?
I know we can use template module for this but is there any way provision it through playbook?

Ansible Module vmware_host_facts only returning one Host

I'm playing around with Ansible VMWare Modules and tried to get all the Information from ESXi Hosts from a vCenter.
With the Module vmware_host_facts it should be possible.
But when I run a Playbook with the following configuration, I only get the Information of one Host back - and not all. In this vCenter there are about 20 Hosts.
Playbook:
- name: Gather vmware host facts
vmware_host_facts:
hostname: vCenter_IP
username: username
password: password
register: host_facts
delegate_to: localhost
In the Documentation it tells me, that the hostname can also be a vCenter IP.
Resource:
http://docs.ansible.com/ansible/latest/modules/vmware_host_facts_module.html#vmware-host-facts
Is that module not the correct one to gather all host information from a vCenter? Or is there a "hidden trick", which I am missing?
Thanks a lot!
Kind regards,
M
I got an answer on another resource.
https://github.com/ansible/ansible/issues/43187
Basically you have to add the Hostnames as a list to the Task.
Example:
- name: Gather vmware host facts
vmware_host_facts:
hostname: "{{ item.esxi_hostname }}"
username: "{{ item.esxi_user }}"
password: "{{ item.esxi_pass }}"
validate_certs: no
register: host_facts
delegate_to: localhost
with_items:
- {esxi_hostname: hostname_1, esxi_user: username_host_1, esxi_pass: pass_host_1}
- {esxi_hostname: hostname_2, esxi_user: username_host_2, esxi_pass: pass_host_2}
These Hostnames you can gather with another module - vmware_vm_facts. Here you can get the Hostnames from. I will update this with an example playbook in the near future.
I use this module with these options, so far I have one issue if I put vcenter address it only give me first Esxi output.
- name: Somethign.
vmware_host_facts:
hostname: '{{ vcenter_hostname }}'
username: '{{ vcenter_user }}'
password: '{{ vcenter_pass }}'
validate_certs: no
register: all_cluster_hosts_facts
delegate_to: localhost
- debug: var=all_cluster_hosts_facts

Resources