Deploy VCF 9 on One Physical Host: Lab-Only Guide

HOMELAB JOURNAL

Deploy VCF 9 on One Physical Host: Lab-Only Guide

Explore a single-host VCF 9 lab deployment with a sample JSON configuration and vSAN policy notes. This is an unsupported lab-only approach.

Overview

I deployed VCF 9 on a single physical host as an unsupported lab experiment. This post records the JSON-based deployment approach and vSAN policy issue I encountered; the design has no host redundancy and is not a production deployment model.

JSON validation and placeholder rules

The formatted example below is valid JSON syntax, not a vendor-schema or deployment validation. It remains an unsupported single-host lab design with zero host-failure tolerance. Use a spec exported by your own target-version installer as the baseline.

  • Replace every REPLACE_* value, hostname, subnet, VLAN, uplink, password and certificate thumbprint with reviewed values for your environment. The example deliberately cannot deploy unchanged.
  • The thumbprint-validation bypass is disabled in this revised example. Verify actual host fingerprints through a trusted channel instead of copying the original bypass.
  • Parse locally, then run the installer’s complete validation. JSON parsing does not establish hardware compatibility, correct field types, address availability or supportability.
  • Protect the completed file as a secret: it includes administrator passwords. Do not attach an unredacted deployment spec to a public issue.

Unsupported lab configuration

Deploying VCF 9.0 on a single host

Prepare the JSON deployment

One caveat to running this type of deployment is that it must be a JSON install, I initially used the VCF GUI deployment and add 2 nested hosts to my initial install to build out the JSON I need. There are many ways to accomplish this and I have been working on a JSON builder for 9.0 but its slow going so far as time allows.

Example deployment specification

Below is a sample JSON for VCF management domain deployment if you wanted to build your own

The download contains the same placeholder JSON displayed below. If scripting is unavailable, copy the code into a .json file.

{
  "sddcId": "vcf",
  "vcfInstanceName": "vcf-mgmt",
  "workflowType": "VCF",
  "version": "9.0.0.0",
  "skipEsxThumbprintValidation": false,
  "ceipEnabled": false,
  "dnsSpec": {
    "nameservers": [
      "REPLACE_NETWORK.xxx",
      "REPLACE_NETWORK.xxx"
    ],
    "subdomain": "local"
  },
  "ntpServers": [
    "time.google.com"
  ],
  "vcenterSpec": {
    "vcenterHostname": "vcm.example.com",
    "rootVcenterPassword": "REPLACE_ROOTVCENTERPASSWORD",
    "vmSize": "small",
    "storageSize": "",
    "adminUserSsoPassword": "REPLACE_ADMINUSERSSOPASSWORD",
    "ssoDomain": "vsphere.example.com",
    "useExistingDeployment": false
  },
  "clusterSpec": {
    "failuresToTolerate": 0,
    "clusterName": "vcf-mgmt-cl01",
    "datacenterName": "vcf-mgmt"
  },
  "datastoreSpec": {
    "vsanSpec": {
      "esaConfig": {
        "enabled": true
      },
      "datastoreName": "vcf--mgmt-vsan01"
    }
  },
  "nsxtSpec": {
    "nsxtManagerSize": "medium",
    "nsxtManagers": [
      {
        "hostname": "nsxm1.example.com"
      }
    ],
    "vipFqdn": "nsxm.example.com",
    "useExistingDeployment": false,
    "nsxtAdminPassword": "REPLACE_NSXTADMINPASSWORD",
    "nsxtAuditPassword": "REPLACE_NSXTAUDITPASSWORD",
    "rootNsxtManagerPassword": "REPLACE_ROOTNSXTMANAGERPASSWORD",
    "skipNsxOverlayOverManagementNetwork": true,
    "ipAddressPoolSpec": null,
    "transportVlanId": "510"
  },
  "vcfOperationsSpec": {
    "nodes": [
      {
        "hostname": "ops.example.com",
        "rootUserPassword": "REPLACE_ROOTUSERPASSWORD",
        "type": "master"
      }
    ],
    "adminUserPassword": "REPLACE_ADMINUSERPASSWORD",
    "applianceSize": "small",
    "useExistingDeployment": false,
    "loadBalancerFqdn": null
  },
  "vcfOperationsFleetManagementSpec": {
    "hostname": "fleet.example.com",
    "rootUserPassword": "REPLACE_ROOTUSERPASSWORD",
    "adminUserPassword": "REPLACE_ADMINUSERPASSWORD",
    "useExistingDeployment": false
  },
  "vcfOperationsCollectorSpec": {
    "hostname": "collector.example.com",
    "applicationSize": "small",
    "rootUserPassword": "REPLACE_ROOTUSERPASSWORD",
    "useExistingDeployment": false
  },
  "vcfAutomationSpec": {
    "hostname": "auto.example.com",
    "adminUserPassword": "REPLACE_ADMINUSERPASSWORD",
    "ipPool": [
      "REPLACE_NETWORK.51",
      "REPLACE_NETWORK.52"
    ],
    "nodePrefix": "vcfa",
    "internalClusterCidr": "198.18.0.0/15",
    "useExistingDeployment": false
  },
  "hostSpecs": [
    {
      "hostname": "dell1.example.com",
      "credentials": {
        "username": "root",
        "password": "REPLACE_PASSWORD"
      },
      "sslThumbprint": "REPLACE_VERIFIED_HOST_THUMBPRINT"
    }
  ],
  "networkSpecs": [
    {
      "networkType": "MANAGEMENT",
      "subnet": "REPLACE_NETWORK.0/27",
      "gateway": "REPLACE_NETWORK.1",
      "subnetMask": null,
      "includeIpAddress": null,
      "includeIpAddressRanges": null,
      "vlanId": "110",
      "mtu": 1500,
      "teamingPolicy": "loadbalance_loadbased",
      "activeUplinks": [
        "uplink1",
        "uplink2"
      ],
      "standbyUplinks": [],
      "portGroupKey": "vcf-mgmt"
    },
    {
      "networkType": "VM_MANAGEMENT",
      "subnet": "REPLACE_NETWORK.0/25",
      "gateway": "REPLACE_NETWORK.1",
      "subnetMask": null,
      "includeIpAddress": null,
      "includeIpAddressRanges": null,
      "vlanId": "201",
      "mtu": 1500,
      "teamingPolicy": "loadbalance_loadbased",
      "activeUplinks": [
        "uplink1",
        "uplink2"
      ],
      "standbyUplinks": [],
      "portGroupKey": "vcf-vm-mgmt"
    },
    {
      "networkType": "VMOTION",
      "subnet": "REPLACE_NETWORK.32/27",
      "gateway": "REPLACE_NETWORK.33",
      "subnetMask": null,
      "includeIpAddress": null,
      "includeIpAddressRanges": [
        {
          "startIpAddress": "REPLACE_NETWORK.34",
          "endIpAddress": "REPLACE_NETWORK.62"
        }
      ],
      "vlanId": "111",
      "mtu": "9000",
      "teamingPolicy": "loadbalance_loadbased",
      "activeUplinks": [
        "uplink1",
        "uplink2"
      ],
      "standbyUplinks": [],
      "portGroupKey": "vcf-vmotion"
    },
    {
      "networkType": "VSAN",
      "subnet": "REPLACE_NETWORK.64/27",
      "gateway": "REPLACE_NETWORK.65",
      "subnetMask": null,
      "includeIpAddress": null,
      "includeIpAddressRanges": [
        {
          "startIpAddress": "REPLACE_NETWORK.66",
          "endIpAddress": "REPLACE_NETWORK.94"
        }
      ],
      "vlanId": "112",
      "mtu": "9000",
      "teamingPolicy": "loadbalance_loadbased",
      "activeUplinks": [
        "uplink1",
        "uplink2"
      ],
      "standbyUplinks": [],
      "portGroupKey": "vcf-vsan"
    }
  ],
  "dvsSpecs": [
    {
      "dvsName": "vcf-mgmt-vds01",
      "networks": [
        "MANAGEMENT",
        "VM_MANAGEMENT",
        "VMOTION",
        "VSAN"
      ],
      "mtu": 9000,
      "nsxtSwitchConfig": {
        "transportZones": [
          {
            "transportType": "OVERLAY",
            "name": "vcf-mgmt-overlay-tz"
          }
        ]
      },
      "vmnicsToUplinks": [
        {
          "id": "vmnic2",
          "uplink": "uplink1"
        },
        {
          "id": "vmnic3",
          "uplink": "uplink2"
        }
      ],
      "nsxTeamings": [
        {
          "policy": "FAILOVER_ORDER",
          "activeUplinks": [
            "uplink1",
            "uplink2"
          ],
          "standByUplinks": []
        }
      ],
      "lagSpecs": null
    }
  ],
  "sddcManagerSpec": {
    "hostname": "sddc.example.com",
    "useExistingDeployment": false,
    "rootPassword": "REPLACE_ROOTPASSWORD",
    "sshPassword": "REPLACE_SSHPASSWORD",
    "localUserPassword": "REPLACE_LOCALUSERPASSWORD"
  }
}

Resolve the vSAN policy issue

After running through the JSON deployment in the VCF installer, the only other issue I ran into was the vSAN storage policy caused any error but my original JSON file didn’t have the “failuresToTolerate” option listed and was trying to build a policy with redundancy enabled which doesn’t work for a single host deployment.

I simply changed the vSAN storage policy manually in the vCenter and restarted the deployment.

Related lab guides

Leave a Reply

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.