Create multiple VMware guests with a Playbook?

3,030 views
Skip to first unread message

Mark Matthews

unread,
Mar 10, 2016, 12:00:18 PM3/10/16
to Ansible Project
Hi

Is it at all possible to create multiple VMware VM's using an Ansible playbook? Giving each VM a unique name (server1, server2, server3, server4)?

I can see anyway of doing this using the following playbooks, as it keeps failing?
---
 - hosts: 127.0.0.1
   connection: local
   user: root
   sudo: false
   gather_facts: false
   serial: 1
   vars:
     vcenter_hostname: UK.server.local
     esxhost: xxx.xxx.xxx.xxx
     datastore: UK1
     network: Web
     vmcluster: UKCLUSTER
     guest_name: server1, server2, server3, server4 
     folder: Utilities
     notes: Created by Ansible

   tasks:
    - name: Create VM from template
      vsphere_guest:
        vcenter_hostname: "{{ vcenter_hostname }}"
        username: "{{ username }}"
        password: "{{ password }}"
        guest: "{{ guest_name }}"
        vm_extra_config:
          notes: "{{ notes }}"
          folder: "{{ folder }}"
        from_template: yes
        template_src: "{{ vmtemplate }}"
        cluster: "{{ vmcluster  }}"
        resource_pool: "/Resources"
        
        esxi:
          datacenter: UK
          hostname: "{{ esxhost }}"
Any ideas or suggestions would be really appreciated.
Cheers

J Hawkesworth

unread,
Mar 11, 2016, 5:58:25 AM3/11/16
to Ansible Project
Hi Mark,

I've not tried this myself with this specific module, but I think you should be able to use one of the with_  mechanisms in your playbook to create multiple vms.

Hope this helps,

Jon

Mark Matthews

unread,
Mar 11, 2016, 8:23:19 AM3/11/16
to Ansible Project
Hi Jon

Thanks so much for the response.

I was looking at that and have ried a few things without success.

Are you able to see if im on the right track here?
I have create a file called 'hostnames' which is located in a sub directory (files) where the playbook is, and have included the vm names in that file:
---
serverlist:
  - server1
  - server2
I have then added the 'with_items' and variable 'serverlist'. But i think I may be getting a bit confused through?
Im I completely off track here?


Playbook:
---
 - hosts: 127.0.0.1
   connection: local
   user: root
   sudo: false
   gather_facts: false
   serial: 1
   vars:
     vcenter_hostname: UK.server.local
     esxhost: xxx.xxx.xxx.xxx
     datastore: UK1
     network: Web
     vmcluster: UKCLUSTER
     serverlist: files/hostnames 
     folder: Utilities
     notes: Created by Ansible

   tasks:
    - name: Create VM from template
      vsphere_guest:
        vcenter_hostname: "{{ vcenter_hostname }}"
        username: "{{ username }}"
        password: "{{ password }}"
        guest: "{{ list }}"
        vm_extra_config:
          notes: "{{ notes }}"
          folder: "{{ folder }}"
        from_template: yes
        template_src: "{{ vmtemplate }}"
        cluster: "{{ vmcluster  }}"
        resource_pool: "/Resources"
       with_items: "{{ serverlist }}
        
        esxi:
          datacenter: UK
          hostname: "{{ esxhost }}"



Cheers
Mark 

J Hawkesworth

unread,
Mar 14, 2016, 4:52:31 AM3/14/16
to Ansible Project
Hi Mark,

I think you are getting pretty close.

I can see a couple of issues in your playbook which might unstick you...

First the with_items needs to go right at the end of all of the parameters for the vsphere guest module - at the moment you have the exsi parameter after the with_items.

Also there's a missing double quote at the end of the with items line:

with_items: "{{ serverlist }}

should probably be:

with_items: "{{ serverlist }}"


The other thing is actually getting your file containing the serverlist variable loaded into Ansible.  There's at least a couple of ways of doing this - either do an include_vars: file_containing_vars.yml at the top of your playbook, or you can pass in the contents of a yaml file on the command line using -e @/path/to/yaml/file.yml.  Not sure what is going to suit your usage best

Hope this is enough to get you unstuck.

Jon

Mark Matthews

unread,
Apr 5, 2016, 7:14:49 AM4/5/16
to Ansible Project
Hi Jon 

I am still really battling with this...

I have changed the playbook to the following:

Playbook:
---
 - hosts: 127.0.0.1
   connection: local
   user: root
   sudo: false
   gather_facts: false
   serial: 1
   vars:
     vcenter_hostname: UK.server.local
     esxhost: xxx.xxx.xxx.xxx
     datastore: UK1
     network: Web
     vmcluster: UKCLUSTER
     serverlist: files/hostnames 
     folder: Utilities
     notes: Created by Ansible

   tasks:
    - name: Create VM from template
      vsphere_guest:
        vcenter_hostname: "{{ vcenter_hostname }}"
        username: "{{ username }}"
        password: "{{ password }}"
        guest: "{{ list }}"
        vm_extra_config:
          notes: "{{ notes }}"
          folder: "{{ folder }}"
        from_template: yes
        template_src: "{{ vmtemplate }}"
        cluster: "{{ vmcluster  }}"
        resource_pool: "/Resources"
               
        esxi:
          datacenter: UK
          hostname: "{{ esxhost }}"
          
      with_items: "{{ serverlist }}"


As I mentioned, I have created a file called 'hostnames' which is located in a sub directory (files) where the playbook is, and have included the vm names in that file.

As you can see I have said that the variable {{ serverlist }} needs to look at the file path files/hostnames. Is that correct.

And in that hostnames file is the list of servers.
I have then put the variable "{{ list }}" for the guest option, but how does Ansible know to create multiple VM's with those servers names?

Im starting to think that this insnt possible and Ansible is not able to do this without having to repeat the playbook over and over again for as many VM's as you want?

Cheers
Mark


On Thursday, March 10, 2016 at 5:00:18 PM UTC, Mark Matthews wrote:

Nigel Metheringham

unread,
Apr 5, 2016, 9:01:43 AM4/5/16
to Mark Matthews, ansible...@googlegroups.com
On 5 April 2016 at 12:14:53, Mark Matthews (mdmat...@gmail.com) wrote:
I have then put the variable "{{ list }}" for the guest option, but how does Ansible know to create multiple VM's with those servers names?

I’m not very familiar with that module, but the iterator on a loop (which is effectively what you have with the with_items stanza) is “item" and not “list”

So try changing the guest part to:-

guest: “{{ item }”


Nigel.


-- 
[ Nigel Metheringham ------------------------------ ni...@dotdot.it ] 
[                 Ellipsis Intangible Technologies                  ]

Mark Matthews

unread,
Apr 5, 2016, 10:57:39 AM4/5/16
to Ansible Project
Hi Nigel / Jon

I changed the following as suggessted:

guest: "{{ item }}"

What is happening now is when I run the playbook it is creating one VM in vSphere called "files/hostnames"??

So its as if the playbook is looking at, with_items: "{{ serverlist }}", and then seeing the variable, serverlist: files/hostnames, and then creating a VM with that name. Its not looking into the 'hostnames' file and creating the multiple VM's in that file??

Any ideas?

Cheers
Mark 

On Thursday, March 10, 2016 at 5:00:18 PM UTC, Mark Matthews wrote:

Mark Matthews

unread,
Apr 5, 2016, 11:07:31 AM4/5/16
to Ansible Project
I dont even know if im on the right track here?

Can you guys think of a way that may be easier to do this?

Jon mentioned using looping....but I have looked at this and have no idea how I could apply that to this situation.



On Thursday, March 10, 2016 at 5:00:18 PM UTC, Mark Matthews wrote:

J Hawkesworth

unread,
Apr 5, 2016, 11:14:31 AM4/5/16
to Ansible Project
Hi Mark,

Quickest way to get going is probably to pass the serverlist file in to ansible using extra vars

ansible-playbook your_playbook -e @/full/path/to/your/serverlist

If you don't want to use the -e (extra vars) functionality, then I think you need to use include_vars, - see  http://docs.ansible.com/ansible/include_vars_module.html 

rather than naming the file you want to load in the vars: section of your playbook - vars is just for variables you want to declare within the playbook itself.

Jon

Mark Matthews

unread,
Apr 5, 2016, 11:16:15 AM4/5/16
to Ansible Project
Hi guys

Just to let you know, I just worked it out.

I removed the following variable "serverlist: files/hostnames "

And then changed the with_items to the following:

      with_items:
        - ans_testserver01
        - ans_testserver02

The playbook now creates both VMs (ans_testserver01 and ans_testserver02) when it is run.

I dont know if that is the correct way of doing it, but it seems to be working for me.



On Thursday, March 10, 2016 at 5:00:18 PM UTC, Mark Matthews wrote:

Mark Matthews

unread,
Apr 5, 2016, 11:18:16 AM4/5/16
to Ansible Project
Hi Jon

I will definitely try using your option for extra vars, and see if I can get that to work.

Thanks so much for all your help and assistance with this guys!!

Cheers 


On Thursday, March 10, 2016 at 5:00:18 PM UTC, Mark Matthews wrote:

J Hawkesworth

unread,
Apr 5, 2016, 11:21:26 AM4/5/16
to Ansible Project
Mark,

Something like this:

---
 - hosts: 127.0.0.1
   connection: local
   user: root
   sudo: false
   gather_facts: false
   serial: 1
   vars:
     vcenter_hostname: UK.server.local
     esxhost: xxx.xxx.xxx.xxx
     datastore: UK1
     network: Web
     vmcluster: UKCLUSTER
     folder: Utilities
     notes: Created by Ansible

   tasks:
    - name: pick up hostnames to create
      include_vars: hostnames.yml    
   
    - name: Create VM from template
      vsphere_guest:
        vcenter_hostname: "{{ vcenter_hostname }}"
        username: "{{ username }}"
        password: "{{ password }}"
        guest: "{{ list }}"
        vm_extra_config:
          notes: "{{ notes }}"
          folder: "{{ folder }}"
        from_template: yes
        template_src: "{{ vmtemplate }}"
        cluster: "{{ vmcluster  }}"
        resource_pool: "/Resources"    
        esxi:
          datacenter: UK
          hostname: "{{ esxhost }}"
       with_items: serverlist
          

J Hawkesworth

unread,
Apr 5, 2016, 11:27:19 AM4/5/16
to Ansible Project
Looks like we have crossed messages.

Ansible is pretty flexible, if that suits your need then that's good enough.

If you use a role you can do away with the include_vars but putting your serverlist var in a vars/main.yml under your role.  Roles are nice as they can magically load lots of stuff like variables - see http://docs.ansible.com/ansible/playbooks_roles.html#roles

You might find you want to pass in the list of servers with the -e trick too, just depends on how much re-usability you need from your playbook - see http://docs.ansible.com/ansible/playbooks_variables.html#passing-variables-on-the-command-line

HTH

Jon

Chun-Hung Huang

unread,
Jun 21, 2016, 8:57:47 AM6/21/16
to Ansible Project
Hi Mark Matthews and ALL

I meet the same problem with create Create multiple VMware guests with a Playbook.
Could your share / show your playbook with me?

Or help me to fix my playbook?

My playbook is


- name: Testing vsphere_guest module in VMware
  hosts
: localhost
  connection
: local
  vars_prompt
:
   
- name: "vcenter_hostname"
      prompt
: "Enter vcenter hostname"
     
private: no
     
default: "vcsa"
   
- name: "vcenter_user"
      prompt
: "Enter vCenter username"
     
private: no
     
default: root
   
- name: "vcenter_pass"
      prompt
: "Enter vcenter password"
     
private: yes
   
- name: "esxi_hostname"
      prompt
: "Enter esxi hostname"
     
private: no
  tasks
:
   
- name: Testing gater facts from vSphere
      vsphere_guest
:
        vcenter_hostname
: "{{ vcenter_hostname }}"
        validate_certs
: no
        username
: "{{ vcenter_user }}"
        password
: "{{ vcenter_pass }}"
        guest
: "{{ item }}"
        from_template
: yes
        template_src
: openSUSELeap42.1_Template
        esxi
:
          datacenter
: Lab
          hostname
: "{{ esxi_hostname }}"
        with_items
:
         
- server01
         
- server02


Error message is

fatal: [localhost]: FAILED! => {"failed": true, "msg": "'item' is undefined"}


item is undefined.
But I already have with_items ??


Thanks


Max

Mark Matthews於 2016年4月5日星期二 UTC+8下午11時16分15秒寫道:

James Tanner

unread,
Jun 21, 2016, 3:07:49 PM6/21/16
to Ansible Project
Your with_items line is indented too far. It should align with the first letter of the word "name".

Chun-Hung Huang

unread,
Jun 21, 2016, 9:30:05 PM6/21/16
to Ansible Project
Hi James

Thanks :)
It works now

Very thanks for your help


Max

James Tanner於 2016年6月22日星期三 UTC+8上午3時07分49秒寫道:
Reply all
Reply to author
Forward
0 new messages