[ISSUE] Ansible for VMware, deploy vms and update them

598 views
Skip to first unread message

TheReal MVP

unread,
Aug 23, 2022, 11:08:32 AM8/23/22
to Ansible Project
Hi there,
I've been banging my head with this for some time now and I can't figure it out.

I'm using Ansible the vmware commnity plugins to deploy 4 VMs from a template and they all have DHCP running. Ultimately, I want to be able to grab the IPs from all 4 VMs, connect to them and run some commands (possibly update them and push my main ansible ssh key).

config.yml
vcenter_hostname: 'FQDN-of-my-vcenter'
vcenter_username: 'admini...@vsphere.local'
vcenter_password: 'MyPassword'
vcenter_datastore: 'Storage'
vcenter_datacenter: 'Datacenter'
vcenter_folder: 'deployments/ubuntu'
vcenter_datastore: 'Storage'

guest_id: 'Ubuntu64'
guest_network_1: 'VM Network'
guest_network_2: 'Docker'
guest_wait_for_ip_address: 'yes'
guest_state: 'poweredon'

# - Prepare VMs information
machine_user: user
machine_initial_user: root
machine_initial_password: P@ssw0rdP@ssw0rd


ansible.cfg
# config file for ansible -- http://ansible.com/
# ==============================================

# nearly all parameters can be overridden in ansible-playbook
# or with command line flags. ansible will read ANSIBLE_CONFIG,
# ansible.cfg in the current working directory, .ansible.cfg in
# the home directory or /etc/ansible/ansible.cfg, whichever it
# finds first

[defaults]

# some basic default values...
library        = ./library

# additional paths to search for roles in, colon separated
roles_path    = ./roles

[inventory]
#Nothing in here

My playbook
deploy-vm.yaml
root@user-ubuntu:/opt/ansible/multiple_vm# more deploy-vm.yaml
---
- hosts: all
  gather_facts: false
  vars_files:
    - config.yml
  roles:
     - deploy-vm


/roles/deploy-vm/tasks/main.yaml
---
# Deploy a VM from a template using Ansible 'vmware_guest' module
  - name: Deploying VMs
    community.vmware.vmware_guest:
      hostname: '{{ vcenter_hostname }}'
      username: '{{ vcenter_username }}'
      password: '{{ vcenter_password }}'
      validate_certs: no
      datacenter: '{{ vcenter_datacenter }}'
        #cluster: '{{ vcenter_cluster }}'
        #resource_pool: '{{ vcenter_resource_pool }}'
      folder: '{{ vcenter_folder }}'
      name: '{{ inventory_hostname }}'
      state: poweredon
      guest_id: '{{ guest_id }}'
      annotation: "{{ guest_notes }}"
      #disk:
      #- size_gb: 50
      #  type: thin
      #  datastore: '{{ vcenter_datastore }}'
      networks:
      - name: '{{ guest_network_1 }}'
        #ip: '{{ guest_custom_ip }}'
        #netmask: '{{ guest_netmask }}'
        #gateway: '{{ guest_gateway }}'
        type: dhcp
        connected: true
        start_connected: true
      - name: '{{ guest_network_2 }}'
        #ip: '{{ guest_custom_ip }}'
        #netmask: '{{ guest_netmask }}'
        #gateway: '{{ guest_gateway }}'
        type: dhcp
        connected: true
        start_connected: true
        #dns_servers:
        #- '{{ guest_dns_server }}'
      hardware:
        memory_mb: '{{ guest_memory }}'
        num_cpus: '{{ guest_vcpu }}'
      customization:
        dns_servers:
        - '{{ guest_dns_server }}'
        domain : '{{ guest_domain_name }}'
        hostname: '{{ inventory_hostname }}'
      template: '{{ guest_template }}'
      wait_for_ip_address: '{{ guest_wait_for_ip_address }}'
      state: '{{ guest_state }}'
    delegate_to: localhost


 I'll deploy all 4 VMs with this inventory file
[machines]
server01 guest_memory='4096' guest_vcpu='2' guest_template='Ubuntu 22.04 Template' guest_custom_ip='' guest_notes='server01'
server02 guest_memory='4096' guest_vcpu='2' guest_template='Ubuntu 22.04 Template' guest_custom_ip='' guest_notes='server02'
server03 guest_memory='4096' guest_vcpu='2' guest_template='Ubuntu 22.04 Template' guest_custom_ip='' guest_notes='server03'

[vms]
'VDI Template' guest_memory='2048' guest_vcpu='4' guest_template='Ubuntu 22.04 Template' guest_notes='VDI Template'


I'll deploy everything with this command:
ansible-playbook -i vm-to-deploy deploy-vm.yaml

All 4 VMs get deployed at the same time! AWESOME!
I'll need to right-click on each VMs and set the network to "connected" since it doesn't do this automatically, i'll need to figure this out.

Now, how do I gather the DHCP information, connect to them and update them? I was reading on using the vmware community dynamic inventory plugin but i'm getting weird errors which I don't really understand, so I can't really post them here.

Any points?
Sorry for the very long post.

Walter Rowe

unread,
Aug 23, 2022, 1:29:20 PM8/23/22
to Ansible Project
in our env we have an ansible tower workflow where we create the VM, register the results, then send the mac address of the new VM off to InfoBlox to create a new DHCP record. Once InfoBlox creates the DHCP record it sees the DHCP broadcasts from the VM and responds. This gives the VM all it needs to get on the network. At that point we have a DHCP record with FQDN and a VM on the network. Now we can reference the machine by FQDN.
--
Walter Rowe, Chief
Infrastructure Services
Office of Information Systems Management
National Institute of Standards and Technology
United States Department of Commerce

Paul Manno

unread,
Aug 23, 2022, 1:41:38 PM8/23/22
to ansible...@googlegroups.com
Hello,

Don't get me wrong, I love ansible, and I realize this is an ansible mailing group, but IMO Terraform is a better tool for this.

I build a whole workflow around packer and ansible glued together with Python and AWX in the mix and it's really, really hard to orchestrate a lot of this stuff reliably.  After just a few weeks using Terraform, things are coming together much more easily and with much more stability.

I'm using Terraform to clone the VMs, then using a terraform template to render out an inventory file and a provisioner tied to the template that launches ansible on the VM.  It's super clean, super fast, does not require waiting on AWX inventory to catch up or process and it's very simple to create/modify/delete infrastructure with this (something not really trivial with pure Ansible).

My 2 cents...

Best,
Paul


--
You received this message because you are subscribed to the Google Groups "Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-proje...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ansible-project/ae1e2cb7-5b7a-4b58-b639-df8e9ed149f0n%40googlegroups.com.

TheReal MVP

unread,
Aug 23, 2022, 1:51:45 PM8/23/22
to Ansible Project
Walter: Oh that would be the dream! Register the mac address with the DHCP server, then wait for the VM to pick up the ip.

Paul: I was looking at terraform as well, but I haven't really searched how well it was all working together. Do you have any off-hand scripts I could follow and check out? 

Thanks to both!

D

unread,
Aug 23, 2022, 2:03:47 PM8/23/22
to ansible...@googlegroups.com
Just use terraform


--
You received this message because you are subscribed to the Google Groups "Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-proje...@googlegroups.com.

TheReal MVP

unread,
Aug 23, 2022, 7:15:20 PM8/23/22
to Ansible Project
I'm getting close :)

I created this playbook after finding the vmware_vm_info module

- hosts: all
  gather_facts: false
  become: false
  tasks:
    - name: Gathering info from vms from '{{ folder }}'
      community.vmware.vmware_vm_info:
        hostname: 192.168.1.51
        username: admini...@vsphere.local
        password: password
        validate_certs: False
        folder: "/Datacenter/vm/deployments/ubuntu"
      delegate_to: localhost
      register: vm_info
    - debug:
        msg: "{{ vm_info }}"

I'll get a dump of information from all 4 machines inside the folder specified.

Now I need to find a way to extract the IP from it and save it somewhere to use it to connect to them :)

TheReal MVP

unread,
Aug 24, 2022, 12:07:44 AM8/24/22
to Ansible Project
I'll keep adding with my findings, might save people some time.

Wrote playbook:
- hosts: localhost
  gather_facts: false
  vars_files:
    - all_config.yml

  tasks:
    - name: Gathering info from vms
      community.vmware.vmware_vm_info:

        hostname: "{{ vcenter_hostname }}"
        username: "{{ vcenter_username }}"
        password: "{{ vcenter_password }}"
        validate_certs: False
        folder: "/Datacenter/vm/deployments/ubuntu"
      delegate_to: localhost
      register: vm_info
    - debug:
        var: name_ip
      vars:
        name_ip: "{{ vm_info.virtual_machines|
                     items2dict(key_name='guest_name',
                               value_name='ip_address') }}"

which will spit out this:

TASK [debug] ************************************************************************************************************************************
ok: [localhost] => {
    "name_ip": {
        "Ubuntu 22.04 VDI Template": "192.168.1.122",
        "server01": "192.168.1.181",
        "server02": "192.168.1.114",
        "server03": "192.168.1.117"
    }
}

I think i'm getting close. Took me a whole 3 hours to figure this part.

Now I need to save this into the ansible inventory (I think?) and run the apt update and apt upgrade against those vms.

Mike Tipton

unread,
Nov 7, 2022, 5:05:39 PM11/7/22
to Ansible Project
I was wondering if you figured out the "I'll need to right-click on each VMs and set the network to "connected" since it doesn't do this automatically, i'll need to figure this out." part and update you with my findings as I ran into this as well.

It was as simple as adding perl to my base template as it is needed to do the customization after deployment.

Cheers,
Tipton
Reply all
Reply to author
Forward
0 new messages