Poor Man’s AutoDeploy Using Custom Kickstart, and Python

I recently encountered a situation where I needed to provision hundreds of ESXi hosts. The thing is, there was no vSphere Autodeploy, or HPE Synergy Image Streamer, and no ability to (long story, trust me here) spin them up. No way I’m going to manually provision all of those hosts by hand, so what’s a guy to do?!

This solution will automatically provision ESXi hosts and “get them on the network” so you can add them to vCenter just by using tools that VMware gives us, and a little bit of creativity.

While I designed this solution to work with hundreds of production ESXi hosts, there’s nothing from preventing you from using this method in smaller production environments, or even your own home lab.

Overview

At a very high level, the process works as follows.. The physical server boots from an ISO, USB Image, or even CD/DVD, if you’re into that sort of thing. The ESXi image on this media will contain a slightly customized ESXi image that looks for a kickstart file pulls the rest of the install instructions from a kickstart file on a web server. This kickstart fill will handle the silent install of ESXi, reboot into the newly installed OS, set a few settings, then download a CSV that contains ESXi host configuration info (such as host name, IP, and Default Gateway), and a python script that will send esxcli commands to the host in order to configure networking.

Diagram

Modified Boot.cfg file

First and foremost, I need to emphasize the fact that there are two places you need to put your boot.cfg file. One in the root of the filesystem you have on your media, and one in the efi folder. This file is read during the boot process and instructs ESXi on how to boot. We care about the line that begins with kernelopt=. By default, this line tells ESXi to start with the traditional GUI installer which we definitely don’t want. Instead, we’ll modify it to tell the installer to look for a kickstart file on a web server, and will set static networking for the host.

At a high level, the modifications here accomplish the following:

  1. Instruct the ESXi host to find a kickstart file on a web server
  2. Set a static IP, netmask, default gateway, and nameserver to use prior to automatically configuring the host

boot.cfg code

Here’s a link to the code

Kickstart file (ks.cfg)

The kickstart file provides the ESXi installer with all the information it needs to perform the installation without manual intervention. We are handling this in two stages by using the firstboot parameter.

Stage 1

Handles the installation of ESXi to physical hardware. The following tasks are completed:

  1. Accept EULA
  2. Select disk for ESXi to be installed to
  3. Set root password
  4. Set IP to be used on first boot (Default is DHCP, but the code to use static is included/commented in the code)

Stage 2

All of stage two is executed in the newly installed ESXi OS using the firstboot parameter. The following tasks are completed:

  1. Enable SSH and ESXi Shell
  2. Disable warnings for #1
  3. Disable ESXi Firewall so we can use wget
  4. Using wget, download the following files
    1. ListOfHosts.csv
    2. configurehost.py
  5. Set the execution bit on the python script
  6. Execute the python script

ks.cfg code

Here’s a link to the code

Host Detail Spreadsheet

I like to have all, or as much configuration as possible defined in a document, and consume that as a part of the provisioning process. In this case, since I’m executing this on an ESXi host using the version of python that is available to the host, I’m simply using a CSV file. This strikes a healthy balance between usability and functionality.

Here’s a link to the CSV on my github account

The columns are as follows:

Column A ESXi Hostname
Column B MAC Address of vmnic0
Column C Desired Management IP Address (vmk0)
Column D Subnet Mask for vmk0
Column E Default Gateway for vmk0
Column F VLAN Assigned to vmk0
Note: Columns have been converted to rows in this table. The actual representation is shown in the image below.

configureHost.py

Here’s where the magic comes in… Since ESXi is deployed with python, we can use it to parse a CSV file that has a list of all details for an ESXi host, and set the relevant details for the host.
Here’s a link to the code

In this very basic example, we are doing the following based on input in the CSV file:

  1. Set the hostname
  2. Set the IP Address and Netmask of vmk0
  3. Set the default gateway for the host
  4. Set the VLAN for the management port group on vSwitch0

configureHost.py code

Web Server

Since none of this works without a web server, we’ll need to make sure we have one available. My goal in creating this was to have the whole project be as portable as possible. To that effort, I use a small docker container I can start/stop on my laptop or workstation that hosts the required files, but there’s nothing preventing you from doing this on a production server as well. I’m using a container that has a nice graphical directory browser, but also allows for direct downloading of files. Here’s a link to more information about this container

As a side note, in a previous blog post, I spoke about deploying VCSA based on properties in an Excel file. One of the prerequisites for this to work is to have a web server that hosts the ISO file. I use this same container to serve the files for that project.

Docker Container

The following snippet can be used to create a docker container to host the files required by this project.

Directory structure

Web Server In Action

Create ISO

This is the process to create a custom ISO

References

  • I owe a big thank you to Andrew Dauncey (twitter, blog, github). He created a post back in 2016 that accomplished something similar to this, but was no longer working with modern versions of vSphere. I updated the code to work with vSphere, and added some additional functionality. Thanks again Andrew!
  • As always, the VMware documentation is a good place to start. Here’s the documentation for 6.7 (link) and here’s the documentation for 7.0 (link)

One thought on “Poor Man’s AutoDeploy Using Custom Kickstart, and Python

  1. Very clever! Very similar to how I’ve mass-deployed linux hosts for nearly 30 years (not always as VMs), and Solaris even longer than that, everything old is new again!

Leave a Reply

Your email address will not be published. Required fields are marked *

Copyright VirtJunkie.com ยฉ 2024