Automated VCF Deployment
Deploying VMware Cloud Foundation (VCF) on a Small Homelab – Is It Possible?
Looking at the official requirements for VMware Cloud Foundation (VCF), they seem excessive for a small homelab setup. But is it still possible? Let's give it a try—the automated way!
Automating the VCF Deployment
Deploying VCF manually is a time-consuming task. Preparing virtual ESXi hosts, configuring networking, and setting up storage can take hours. I wanted a more efficient solution—a script that could deploy VCF with just one click.
That's when I came across William Lam’s blog post about VCF deployment. His PowerShell script automates most of the setup, making the process much easier. However, there was one major limitation:
- The script requires a shared datastore between the ESXi hosts, typically a vSAN datastore.
- Since I only have two Intel NUCs, vSAN wasn't an option due to the missing third witness node.
- I also don’t have the necessary storage for an NFS or iSCSI share.
Adapting the Script for My Setup
To make this work, I had to modify the script to fit my environment. The first challenge was that the script requires several inputs, which wasn’t an issue—until it came to selecting a datastore. The script only allows specifying one datastore, which didn't work for my setup.
So lets see what changes needs to be done to get the script to work on our limited setup.
Changes I Made
To successfully deploy VCF on my two-node cluster, I modified the script in several ways:
- Reduced the NSX Manager size to small to save resources.
1$NSXManagerSize = "small"
- Lowered the nested ESXi CPU count from 12 to 8 to fit within my available hardware.
1$NestedESXiMGMTvCPU = "8"
- Modified the datastore variable to match my NUC-specific naming pattern, allowing me to use individual NVMe disks.
1$VMDatastorePattern = "*NVMe*" #pattern for local vmfs *NVMe*
- Removed workload domain input, as deploying additional workload domains is impractical for my small homelab.
- Adjusted the deployment logic for nested ESXi hosts:
- I distributed the four nested ESXi hosts across my two NUCs.
- Odd-numbered hosts go on
esxi01
, while even-numbered hosts go onesxi02
. - This ensures an even distribution of nested ESXi hosts across the two-node cluster.
1$counter = 0 #counter to track the deployments
2 $NestedESXiHostnameToIPsForManagementDomain.GetEnumerator() | Sort-Object -Property Value | Foreach-Object {
3 $VMName = $_.Key
4 $VMIPAddress = $_.Value
5
6 $evenorodd = $counter % 2 #check if counter is odd or even
7 $vmhost = ($cluster | Get-VMhost | Sort-Object)[$evenorodd] #select esxi host
8 $datastore = ($vmhost | Get-Datastore -Name $VMDatastorePattern) #select datastore with the pattern
- Ensure Cloudbuilder is also deployed on a local Datastore
1if($deployCloudBuilder -eq 1) {
2 $vmhost = ($cluster | Get-VMhost | Sort-Object)[0]
3 $datastore = ($vmhost | Get-Datastore -Name $VMDatastorePattern)
- Shutdown vCenter in order to save some extra resources ;)
1My-Logger "Going to wait 240 seconds then turning off vcenter to safe resources..."
2sleep 240
3
4Connect-VIServer -server $VIServer -user $VIUsername -password $VIPassword
5Get-VM -Name vcsa | Stop-VMGuest -Confirm:$false
6
7Disconnect-VIServer * -Confirm:$false
For instruction how to run the script and adjust it you can have a look at the original github repo from william lam. https://github.com/lamw/vcf-automated-lab-deployment
As we can see both NUCs are heavy loaded with the nested ESXi Hosts, but all good to get a overview and first touchpoints with VCF.
Cleanup Script for Easy Reset
To make experimenting with VCF deployments easier, I also created a cleanup script. This script allows me to completely remove the VCF installation, clean up the environment, and restart vCenter—ready for a fresh deployment.
The cleanup script performs the following tasks:
- Connects to the Intel NUCs.
- Stops and removes all nested ESXi hosts.
- Start the powered off vCenter.
- Removes any leftover vApp from the vCenter inventory.
1$vcentervm = "vcsa"
2$vcenterip = "10.10.5.10"
3$vcenterpw = "VMware1!"
4$esxis = @("10.10.5.250", "10.10.5.251")
5$esxipassword = 'VMware1!'
6
7foreach ($esxi in $esxis) {
8 Connect-VIServer -server $esxi -user root -password $esxipassword
9 Get-VM -Name vcf-* | Stop-VM -Confirm:$false -ErrorAction SilentlyContinue
10 Get-VM -Name vcf-* | Remove-VM -DeletePermanently -Confirm:$false
11 if (Get-VM -Name $vcentervm -ErrorAction SilentlyContinue) {
12 Get-VM -Name $vcentervm | Start-VM
13 }
14 Disconnect-VIServer -server $esxi -Confirm:$false -ErrorAction SilentlyContinue
15}
16
17sleep 600
18
19Connect-VIServer -server $vcenterip -user $vcenteruser -password $vcenterpw
20Get-VApp -Name 'Nested-VCF-*' | Remove-VApp -DeletePermanently -Confirm:$false
21Disconnect-VIServer * -Confirm:$false
Conclusion
By tweaking the script, I managed to work around the shared datastore requirement and adapt the deployment to my limited homelab resources. In an upcoming post, I'll dive deeper into the technical details of these modifications and share the full deployment process.
Feel free to have a look at the script and try it in your homelab :)
https://github.com/p3t35/vcf-automated-lab-deployment
Stay tuned! 🚀