Build automation using ESXi, Ansible, Pysphere

Hi,
I am newbie to Ansible.

I have gone through the online documentation and examples for creating new VM on Ansible Docs - vsphere_guest (http://docs.ansible.com/vsphere_guest_module.html).

I want to automate VM creation and OS installation process using Ansible.

Currently I have VMWare ESXi available which doesn’t support VM cloning, so I need to create a new VM every time from scratch and install OS(RHEL 6) into it.

Is there any way to provide kickstart file URL in Ansible Playbook (for example, static HTTP URL like http://192.168.0.1/ks/ks.cfg) so after newly built VM is powered on, OS will be installed into it ?

Thanks and regards,
Parimal

Parimal,

To use kickstart you first need to present a boot media which is configured to pull the kickstart file
See: http://www.centos.org/docs/5/html/5.2/Installation_Guide/s1-kickstart2-howuse.html

You can use ansible to present the VM with such bootable media by launching it in a VLAN with a PXE boot server which will present the media, or by presenting the VM with a CD image with the kickstart file built in.

I’ve gone the CD image route with ansible, you can specify a cd image to boot like this:

vsphere_guest:
vm_hardware:
vm_cdrom:
type: “iso”
iso_path: “DatastoreName/cd-image.iso”

Of course you need to give the vsphere_guest module all other required arguments, but this is the simplest way I’ve found to kiskstart a vm using ansible.

-earl

If you don’t want to bake in the ks.cfg (for instance, if you have different install profiles coming off the same OS), supplying the kernel argument ks=http://server.example.com/foo.ks also works.

Hello,

I’ve recently done just this - and I coupled the VM creation with PXE booting. I have two PXE menus in place, the default one just says ‘boot to HD’. The other one is the install menu, with a kickstart line. I control the use of this with Ansible by doing the following:

https://gist.github.com/phips/2777a564e10d53824df8

Hi Mark,

Thanks for posting that code, I’ve been unsure of how to extra the mac address for newly created VM’s. I can now parse that to cobbler to create/update vm’s.

Is anyone else using a similar workflow? I’m only using cobbler because we presently use it allows us to use our existing kickstart files.

Thanks!

We have recently setup a similar workflow for RHEL 6 and 7. Here are the steps if anyone is interested.

  1. We enter the server’s information into our custom database (MySQL) that we use to track our inventory. We also use this table to create our dynamic inventory for Ansible. The table contains the server’s name, IP and other server specific information.

  2. We kick off an Ansible playbook that does the following

  • Checks to see if the VM has already been created

  • Creates the VM using the vsphere_guest module. The VM is setup to boot on a network with DHCP.

  • Collects facts about the VM. We need this in order to get the MAC address of the newly created VM.

  • Updates our database with the MAC of the new VM.

  • Powers on the new VM.1. The server is powered on with a custom RHEL ISO attached. The custom ISO is pointing to web service that will dynamically build our kickstart file. (http://kickstart.example.com/ws/ks.php). The custom ISO also has the inst.ks.sendmac, ks.sendmac and kssendmac parameters set on the kernel line. This will send the VM’s MAC address to the web service which allow it to figure out the VM’s IP information.

  1. The kickstart script installs base packages, subscribes the VM with Satellite, installs VM tools and adds the server to our AD domain. The last thing the script does is send a web call to a web service that will change the VM’s network from the DHCP network to the network that the VM is supposed to be on.
  2. Once the VM is up it is ready to have our standard Ansible plays ran on it.

Our last deployment consisted of 4 servers, we had the entire environment up and running and ready to hand off to our customer in 15 minutes!

Ansible rocks, thanks to the Ansible team for such a great product!

Hiatt

Patel,
Have you had any luck on this yet? I have gone down this path about a month or so ago. I am in the process of sharing back on the processes that I have come up with. Below is the flow.

  1. Deploy TFTP server via Ansible which includes Ubuntu Netboot and configures all required services (TFTP,DHCP) and etc.
  2. Create a project folder which includes some shell scripts that run each process flow of the build.
  3. Provision VMs (VM PXE boots and auto installs Ubuntu from TFTP server)
  4. Bootstrap VMs
  5. Deploy apps

here is the link to my github repo that I will be populating over the next while with some of this.

https://github.com/mrlesmithjr/Ansible

Hope this helps. Let me know if you have any questions.

@Michael, thanks! This might be exactly what I am looking for in this stage, but I cannot find an example of how to insert the arguments at boot to point to the remote kickstart.

Mihai Satmarean

miercuri, 7 ianuarie 2015, 18:10:38 UTC+1, Michael DeHaan a scris:

If it’s from a CD boot Mihai just hit ‘tab’ then put ks= as Michael suggested.

Otherwise, with PXE boot you can specify the option on the kernel line, like:

kernel -n img http://ks.internal/centos/7/os/x86_64/images/pxeboot/vmlinuz ks=http://ks.internal/bootstrap/ks/7.ks

Thanks Mark,
We are already doing both, I thought that there is a module or an Ansible trick that you can specify the boot parameter in the vsphere boot :slight_smile: that would be helpful.

vineri, 6 noiembrie 2015, 18:33:56 UTC+1, Mark Phillips a scris:

Hello Mihai,

Well, it’s two other products there that are in effect needing control of. You need vSphere to interact with the Linux boot disc menu - so not easy, really.

See my earlier post in this thread - set up a network boot (PXE) and have two menu items. Or, alternatively, use something like iPXE (http://ipxe.org) to make a specific boot disc image which you ‘insert’ into the VMware VM CDROM to boot.

Cheers

Hi Mark,

I get your point. Sorry for not being very clear (I am working on that).
I am using this already based on what is out there,
what I only miss is a way from vSphere to tell back to Ansible that the VM was rebooted.
that would be the killer feature for now.
Thanks!

miercuri, 11 noiembrie 2015, 18:18:29 UTC+1, Mark Phillips a scris:

Not a problem Mihai! There is always a way.

There are choices here, as per usual - you could always use ‘wait_for’[1] in an Ansible play, or you could use a ‘phone home’ type solution - i.e. the newly provisioned virtual machine boots and the first thing it does is ‘look for’ a centralised Ansible point to tell it ‘hello, I’m booted’.

This is an example I did with Amazon earlier this year of a phone home - https://github.com/phips/tiad_demo/blob/master/plays/new.yml#L31 The actual script, highlighted in that line, is here: https://github.com/phips/tiad_demo/blob/master/scripts/ec2_bootstrap.sh All it is doing is a curl back an Ansible Tower instance, which runs a given job against the newly booted machine.

Hope that helps.

[1] http://docs.ansible.com/ansible/wait_for_module.html

Great Mark - There is always a way even if is the crazyest way :slight_smile:
I will investigate for now the wait for idea and ping the port or something.
Thanks a lot!

joi, 12 noiembrie 2015, 10:27:35 UTC+1, Mark Phillips a scris:

We do something similar with our builds. The last thing we do in the post section of our Kickstart script is make a web service call. The web service moves the VM to the correct network.

Hi Mark,

bit confusion, need your suggestion…

i made a play book to create vm machine and attached iso_path. when i run the playbook it creates a vm automatically boot from rhel6 iso.
if it is booting from iso automatically then why i need to use pxe ? can i install rhel6 OS by kickstart ? if yes then what more syntax i need to define in my script.
please find the below mentioned my playbook and suggest me the right way.

You will need to open up the ISO and add a few parameters to boot config.

I added the location of my dynamic kickstart web service (ks=http://example.com/ks.php) and the kssendmac parameter.

Once you modify that file recreate your ISO.
This link should help.

http://www.softpanorama.org/Commercial_linuxes/RHEL/Installation/Kickstart/modifing_iso_image_to_include_kickstart_file.shtml

Copy the new iso to your data store and reference it you Ansible play.

Hi Jason,

Thanks for your quick response…
Now i have made custom iso of linux. and upload it esxi datastore. do i need to add any parameter in ansible playbook for kickstart or just need to run same play book after define the customer iso path ?

vm_cdrom:
type: “iso”
iso_path: "datastore1/boot.iso"

boot.iso is a RHEL 7 iso file which i have customized…

Regards,
Afroz Khan

The kickstart path should be set in your ISO

It should look something like ks=http://example.com/ks.php kssendmac

The kssendmac parameter sends the VMs MAC address to the kickstart file.

Here is an example play and and scripts I use.

https://github.com/OneMainF/vmware-rhel-server-builder/blob/master/example_build.yaml

Hope this helps.

I have a question on this.
In the above example I see only one node that was used for deployment through custom boot iso but in case there are multiple nodes? the same kickstart iso cannot be used right. because the IP address for each node would be different. how to dynamically build VMs by reading IPs dynamically?