Migration & Modernization
Deploying VCF 9.1 on Amazon EVS with End-to-End Automation
Introduction
Amazon Elastic VMware Service (Amazon EVS) lets you run VMware Cloud Foundation (VCF) directly on AWS bare-metal EC2 instances within your Amazon VPC. With EVS, you get the operational consistency of the VMware stack you already know, combined with the elasticity, security, and breadth of AWS cloud services.
VCF 9 is the latest release of VMware Cloud Foundation, and it works fundamentally differently with Amazon EVS than the previous VCF 5.2 release. With VCF 5.2, the EVS service handled the entire deployment end-to-end: VLAN subnet deployment, EVS environment with hosts, and the full VCF stack were all provisioned and configured automatically by the service. With VCF 9, Amazon EVS operates exclusively in what is called Self Deployed Mode.
What is Self Deployed Mode?
In Self Deployed Mode, Amazon EVS provisions the foundational AWS infrastructure for you: the VLAN subnets required by VCF and the bare-metal EC2 hosts running the ESXi version you select (9.0 or 9.1). However, the service stops there. EVS does not install or configure VCF itself. There is no option for EVS to deploy VCF 9 on your behalf.
This means that after EVS delivers your hosts and networking, you are responsible for installing VCF. You can do this manually by following VMware documentation, or you can use automation to handle the process programmatically. That is exactly what this blog post covers: an AWS-published, end-to-end automation toolkit that handles the entire workflow, from provisioning the prerequisite AWS infrastructure and the EVS environment itself, through to installing and configuring VCF. The toolkit supports both VCF 9.0 and 9.1.
Why automate VCF deployment?
Since VCF 9 installation is your responsibility in Self Deployed Mode, automation becomes especially valuable. Installing VCF manually involves dozens of configuration steps, carefully crafted JSON specs, password generation, and multi-hour wait times. The automation toolkit presented here reduces that to three CLI commands:
- Repeatability: Deploy identical environments across regions and accounts
- Speed: Reduce a multi-hour manual process to three commands
- Auditability: Every configuration decision is captured in version-controlled code
- Error reduction: Eliminate manual typos in DNS records, VLAN CIDRs, and bringup specs
- Security: Passwords generated automatically and stored in AWS Secrets Manager
What you will build
Although the automation toolkit supports both VCF 9.0 and 9.1, this blog focuses solely on deploying VCF 9.1. By the end of this walkthrough, you will have:
- A VPC with Route 53 DNS, Route Server with BGP, and all required networking
- An Amazon EVS environment with 3 bare-metal hosts running ESXi 9.1
- A fully operational VCF 9.1 stack: vCenter, SDDC Manager, NSX Manager, VCF Operations, VCF Cloud Proxy, and two NSX Edges
- Tier-0 and Tier-1 gateways with dynamic route propagation between NSX overlay segments and your VPC route tables
- Ops Manager Connector within the EVS service
Cost consideration
The resources deployed by this automation carry significant monthly costs, including EC2 bare-metal compute, the Amazon EVS control plane, VPC Route Server, Transit Gateway (if enabled), NAT Gateway, EBS volumes, Route 53 hosted zones, etc. We recommend reviewing the Amazon EVS pricing page and using the AWS Pricing Calculator before deploying to understand the full cost profile for your environment.
Architecture Overview
The automation deploys a complete Amazon EVS environment with VCF 9 in three stages, one stage per layer. The user fills in an initial set of configuration details at the start, and from there, those values along with resource ARNs and other metadata generated during each stage are automatically passed forward to the next. Nothing is entered by a human twice, which significantly reduces configuration errors. Those stages are as follows:
- AWS prerequisites and underlay: VPC, service-access subnet, Route 53 (forward + reverse zones), Route Server with two BGP endpoints, security groups, optional Transit Gateway, optional Windows jumpbox, optional public or private HCX connectivity, and more.
- EVS layer: The EVS environment, which creates 10 VLAN subnets used for management, vMotion, vSAN, vTEP, edge uplink, etc. Then, 3 bare-metal hosts (i4i.metal or i7i.metal-24xl, specified by the user) that boot up with ESXi 9.1. Finally, an EBS volume is created and mounted to one of the hosts as a datastore to stage the VCF Installer.
- VCF installation and NSX routing: Configures the VCF Installer depot and automatically triggers binary downloads based on the target VCF version. Then deploys vCenter, SDDC Manager, NSX Manager, VCF Operations, VCF Cloud Proxy, and two NSX Edges in active/standby. The edges peer BGP with AWS Route Server to advertise NSX segment routes into the VPC.
Three-phase automation approach
The automation is organized into three sequential phases, each with its own tooling and purpose:
| Phase | Stack | What is does |
| 1 | Terraform | VPC, Route 53, Route Server, security groups, optional Transit Gateway, optional jumpbox, optional public connectivity, and more |
| 2 | Python (boto3) | Creates EVS environment and VLAN subnets, provisions bare-metal hosts with ESXi 9.1, creates and attaches EBS volume for installer staging |
| 3 | Python (VCF SDK + boto3) | Configures depot, downloads binaries, VCF bringup, installer cleanup, NSX Edge Cluster and routing deployment, creates Ops Manager Connector |
Phases 1 and 2 run locally from a Mac, Linux, or Windows workstation. Phase 3 runs from a jumpbox within the VPC (needed for direct connectivity to the VCF Installer and NSX Manager). The only manual steps are two brief ESXi configurations and deploying the VCF Installer OVA between Phases 2 and 3. Total deployment time is approximately 3.5 to 6 hours, with the majority spent on the VCF bringup process in Phase 3.
Prerequisites
AWS account and permissions
- An AWS account with
- AWS Business Support or better
- Host count per EVS environment service quota set to 3 or greater
- Running On-Demand Standard (A, C, D, H, I, M, R, T, Z) instances service quota is set to 256 or greater
- IAM user or role that can be assumed with the permissions policy defined in the
iam_policy.jsonfile under Phase 1 in the code repository
Local workstation tools
- Terraform 1.7 or later
- Python 3.12 or later
- AWS CLI v2, configured with credentials (via AWS_PROFILE or environment variables)
- pip (for installing Python dependencies)
- git (for cloning the code repository)
Broadcom depot token
Phase 3 downloads VCF component binaries from the Broadcom depot. You need a download token, which you can generate in the Broadcom Support Portal under My Dashboard, Quick Links, Generate Download Token. This token is set as the VCF_DEPOT_TOKEN environment variable before running Phase 3.
VCF Installer OVA
Download the VCF 9.1 Installer OVA from the Broadcom download portal. This appliance is deployed manually between Phases 2 and 3 onto one of the ESXi hosts.
Clone the repository
Clone the automation repository to your local workstation (this command works for both Linux and Windows):
git clone https://github.com/aws/solutions-for-amazon-evs.git
cd solutions-for-amazon-evs/Deploy/VCF9-Phased-Deployment
Phase 0: Measure Twice, Deploy Once
Before running any automation, you need to carefully plan and populate your configuration files. This step is critical: once the infrastructure is deployed, many of these values cannot be changed without a full tear-down and rebuild of the entire environment. Take the time to get these right.
The automation uses two configuration files that you populate once at the start. All subsequent phases read from these files and pass values forward automatically.
terraform.tfvars (Phase 1 inputs)
This file defines the AWS infrastructure foundation. Copy terraform.tfvars.example to terraform.tfvars and set the following (Linux):
cd Phase_1_Base_Infrastructure
cp terraform.tfvars.example terraform.tfvars
For Windows:
cd Phase_1_Base_Infrastructure
copy terraform.tfvars.example terraform.tfvars
Now update the following with your values:
region: The AWS region to deploy into (e.g., us-east-2). Must be a region where Amazon EVS is available.availability_zone: The specific AZ within your region (e.g., us-east-2a). All resources deploy into a single AZ. If you have an EC2 capacity reservation, ensure this matches the AZ where your reservation is located.fqdn: The fully qualified domain name for your environment (e.g., mylab.evs.aws). This becomes the Route 53 forward hosted zone and is used in all DNS records. Choose carefully.cidr_prefix: The first two octets of your VPC CIDR (e.g., “10.0.”). The automation derives all VLAN subnet CIDRs from this prefix. Ensure it does not overlap with any networks you plan to connect via Transit Gateway or Direct Connect.- DNS hostnames: Short DNS names for each VCF appliance and ESXi host (esxi01_name through vcf_fleet_name).
create_tgw: Set to true if you need Transit Gateway connectivity to other VPCs or on-premises networks.create_jumpbox: Set to true to create the Windows jump host. Required for Phase 3, which must run from within the VPC. We recommend enabling this flag.enable_public_hcx: Set to true to allocate public IP space for HCX internet connectivity. When false, HCX uses a private VLAN (suitable for HCX over Direct Connect or Transit Gateway).
How the VPC CIDR is carved up
You supply only the first two octets via cidr_prefix (e.g., “10.0.”). The automation then creates a /16 VPC and carves it into /24 VLAN subnets using hardcoded third octets:
- <prefix>0.0/24 — Service access subnet
- <prefix>10.0/24 — Host vmkernel management (vmkManagement)
- <prefix>20.0/24 — vMotion
- <prefix>30.0/24 — vSAN
- <prefix>40.0/24 — Host TEP (vTep)
- <prefix>50.0/24 — Edge TEP (edgeVTep)
- <prefix>60.0/24 — VM management (vmManagement)
- <prefix>70.0/24 — HCX
- <prefix>80.0/24 — NSX uplink (nsxUplink)
- <prefix>90.0/24 — Expansion VLAN 1
- <prefix>100.0/24 — Expansion VLAN 2
If you modify any of these VLAN subnet CIDRs in config.json, ensure the changes do not conflict with the downstream hardcoded IP addresses that get configured within those subnets, such as the NSX Edge IPs, Route 53 Inbound Resolver endpoints (<prefix>0.100 and <prefix>0.101), and BGP uplink addresses.
config.json (Phase 2 inputs)
This file defines the EVS environment and VCF deployment parameters. Copy config.example.json to config.json and set the following (Linux):
cd Phase_2_evs_env/python
cp config.example.json config.json
For Windows:
cd Phase_2_evs_env/python
copy config.example.json config.json
Now update the following with your values:
environmentName: A descriptive name for your EVS environment. This appears in the AWS Console and is used in resource tagging.vcfInstallerProductVersion: The VCF Installer product version number only (do not include the build string). For example: “9.1.0.0”. Check the OVA filename or the installer UI Settings page for the exact value.simpleDeployment: Set to true for a single rack, simple deployment (3-host minimum), or false for a single rack, HA deployment (4-host minimum). This setting affects the number of NSX Managers and VCF Operations nodes deployed. See Single-Rack vSphere Cluster Model documentation for details.vcfSizing: Appliance sizing for vCenter (vmSize, storageSize), NSX (nsxSize), and VCF Operations (operationsApplianceSize, operationsCollectorApplianceSize). Defaults of “medium” are appropriate for most deployments.
Tip: Take the time to validate your FQDN, CIDR prefix, and hostname choices before proceeding. Also validate everything after Phase 1 deploys, because tearing down Phase 1 and redeploying takes only minutes and changes are still easy to make. Once Phase 2 deploys the EVS environment with these values baked in, changing them requires tearing down and redeploying everything from scratch.
Phase 1: Base AWS Infrastructure (Terraform)
What Phase 1 creates
Phase 1 provisions all the AWS networking and supporting resources that EVS requires. After terraform apply completes (typically 3-5 minutes), you will have:
- Matching Route 53 private hosted zones for VCF appliances and ESXi hosts
- Forward hosted zone (A records)
- Matching reverse hosted zone (PTR records)
- Inbound resolver endpoint with 2 IPs
- Amazon VPC
- Private service access subnet associated to a dedicated service access route table
- Public access subnet associated to a dedicated public access route table
- NAT Gateway with an Elastic IP
- Internet Gateway
- DHCP Option Set with your FQDN, Route 53 Inbound Resolver IPs, and NTP set to 169.254.169.123 (AWS NTP server)
- Dedicated EVS Service Access Security Group allowing ingress from the VPC CIDR
- VPC Route Server
- Associated to the VPC
- 2 Route Server Endpoints, each with a respective peer IP, peer ASN set to 65000, and BGP keepalive liveness
- 2 Route Server Propagations, one to the service access route table, the other to the public access route table
- EC2 keypair for the EVS hosts
- (Optional) Transit Gateway with a VPC attachment to the underlay VPC
- (Optional) Windows jump host in the VPC
- Public subnet in the VPC for the jump host
- Dedicated route table for the jump host public subnet with a route to the Internet Gateway
- Route Server propagation to this dedicated route table
- Dedicated Security Group associated to the jump host allowing all traffic from the VPC CIDR and the EVS Service Access Security Group
- t3.2xlarge EC2 instance running Windows Server 2025 with a 50 GB encrypted gp3 root volume and public IPv4 address
- Dedicated EC2 keypair for the jump host
- Note: This keypair is called “Jumpbox-KeyPair”, if you have an existing keypair with this name, this code will fail. Therefore you must rename the keypair within this code.
- (Optional) Public HCX Connectivity
- IPv4 IPAM Pool
- /28 of contiguous public IP space
- Appending the public /28 to the VPC CIDR
Running the deployment (Linux):
export AWS_PROFILE=your-profile-name
terraform init
terraform plan
terraform apply
For Windows:
$env:AWS_PROFILE = "your-profile-name"
terraform init
terraform plan
terraform apply
Terraform will output the VPC ID, subnet IDs, Route Server endpoint IPs, security group IDs, and other values that Phase 2 reads directly from the terraform.tfstate file. Phase 1 deployment completes in approximately 5-10 minutes.
Verifying the infrastructure
After Phase 1 completes, verify in the AWS Console:
- VPC created with the expected CIDR
- Route 53 hosted zones contain A and PTR records for all VCF appliances and ESXi hosts
- Route Server shows two endpoints in “Available” state
- If using a jumpbox: the instance is running and has a public IP
If you deployed a jumpbox, complete the following steps to establish RDP access:
- Add an inbound rule to the Jumpbox-SG Security Group allowing RDP (TCP 3389) from your IP address
- Retrieve the EC2 keypair and decrypt the Windows Administrator password. Download the PEM file (Linux):
KEY_PAIR_ID=$(terraform output -raw jumpbox_key_pair_id)
aws ssm get-parameter --name /ec2/keypair/$KEY_PAIR_ID --with-decryption \
--region us-east-2 --query 'Parameter.Value' --output text > jumpbox.pem
chmod 400 jumpbox.pem
- For Windows:
$KEY_PAIR_ID = terraform output -raw jumpbox_key_pair_id aws ssm get-parameter --name "/ec2/keypair/$KEY_PAIR_ID" --with-decryption ` --region us-east-2 --query 'Parameter.Value' --output text | Out-File -Encoding ascii jumpbox.pem icacls jumpbox.pem /inheritance:r /grant:r "$($env:USERNAME):(R)"
Then use this PEM file in the EC2 console (Connect > Get Windows Password) to decrypt the Administrator password.
Finally, download or copy the VCF Installer OVA to the jump host. You will need this file during the manual pre-work step between Phases 2 and 3.
Phase 2: EVS Environment Deployment (Python)
What Phase 2 does
Phase 2 is a Python CLI that orchestrates EVS deployment via the AWS API and builds the SDDC bringup spec and NSX deployment spec. With a single CLI command, it launches the following six substeps in sequence:
pre-evs-sync-config: Reads Phase 1 Terraform state and generates the initial VCF bringup spec and edge cluster speccreate-environment-and-hosts: Calls the AWS API to create the EVS environment and upon completion, provisions the bare-metal hosts (15-20 minutes)- Waits for all hosts to reach CREATED status (20-40 minutes)
post-evs-sync-config: Finalizes the SDDC spec with environment and host ID-derived names and provisions the corresponding VCF passwords in Secrets Managerassociate-vlan-subnets: Associates all 10 EVS VLAN subnets with the service-access route tablecreate-and-attach-ebs: Creates a 256 GB gp3 EBS volume and attaches it to one host for the VCF Installer VMFS
Running deploy-environment
Set up the Python environment and run the full Phase 2 pipeline with a single command (Linux):
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
python -m src.main deploy-environment \
--profile your-aws-profile \
--config config.json \
--tfstate ../../Phase_1_Base_Infrastructure/terraform.tfstate \
--instance-type <INSTANCE_TYPE> # 'i4i.metal' or 'i7i.metal-24xl'
For Windows:
py -m venv .venv
.venv\Scripts\Activate.ps1
pip install -r requirements.txt
python -m src.main deploy-environment `
--profile your-aws-profile `
--config config.json `
--tfstate ..\..\Phase_1_Base_Infrastructure\terraform.tfstate `
--instance-type <INSTANCE_TYPE> # 'i4i.metal' or 'i7i.metal-24xl'
This command chains all six substeps automatically. Total runtime is approximately 30-45 minutes, with the majority spent on host realization (the time it takes for bare-metal instances to be provisioned and reach CREATED status). Individual substeps can also be run separately for debugging, though the single-command approach is strongly recommended.
Password management with Secrets Manager
During the Phase 2 build out, the post-evs-sync-config substep automatically generates complex passwords for all VCF appliances and stores them in AWS Secrets Manager. The naming pattern is evs-<environment-id>_<role>.
VCF accounts include: vcenterRoot, vcenterSso, nsxRoot, nsxAdmin, nsxAudit, sddcManagerRoot, sddcManagerSsh, sddcManagerLocal, operationsAdmin, operationsMaster, operationsCollector, and edgeAppliance.
The bringup spec references these passwords via placeholder tokens. Phase 3 resolves them at runtime from Secrets Manager, so no plaintext passwords are ever written to disk.
Manual Pre-Work: ESXi Configuration and Installer OVA
Between Phase 2 and Phase 3, a few brief manual steps are required. These are the only non-automated parts of the entire deployment and take approximately 30 minutes. All of the following steps are performed on the single ESXi host that received the EBS volume from Phase 2.
Create VMFS datastore on the EBS volume
Phase 2 attached a 256 GB EBS volume to one of your ESXi hosts. The Phase 2 console output identifies which host received the volume. You need to format it as a VMFS datastore to host the VCF Installer appliance:
- Log into the ESXi host UI (
https://<esxi-host-ip>) as root. Retrieve the root password from AWS Secrets Manager (the secret name follows the patternevs-<environment-id>_<role>). - Navigate to Storage, then New Datastore
- Select the NVMe device (the 256 GB EBS volume) and create a VMFS datastore
Tag the VM Network port group
On the ESXi host with the EBS volume, the default "VM Network" port group needs to be tagged with VLAN ID 20 so the VCF Installer can communicate on the VM management network:
- In the ESXi UI, go to Networking, then Port groups
- Edit the "VM Network" port group
- Set VLAN ID to 20
Deploy the VCF Installer OVA
Deploy the VCF Installer appliance on the host that has the VMFS datastore:
- In the ESXi UI, go to Virtual Machines > Create/Register VM > Deploy OVF template
- Upload the VCF 9.1 Installer OVA file
- Place it on the 256 GB VMFS datastore created above
- Attach it to the "VM Network" port group
- Set the management IP to the SDDC Manager IP address from your DNS configuration
- Set the netmask to 255.255.255.0
- Set the admin@local password. This is the only password you must manually choose; you can create your own or there is a password generated for you in Secrets Manager should you choose to use it. Note down your password, as you will need it for Phase 3.
- Power on the appliance and wait for it to boot (verify access at
https://<sddcm_name>.<your-fqdn>)
Phase 3: VCF Bringup and NSX Edge Cluster (Python)
What Phase 3 does
Phase 3 must be run from a jump host within the VPC hosting the EVS environment. It uses the official VMware VCF Python SDK (vcf-installer, vcf-nsx) plus pyvmomi for vCenter operations along with the AWS boto3 library for corresponding AWS operations. With a single CLI command, it runs the following six substeps in sequence:
- Secrets Manager precheck: Verifies all required Secrets Manager secrets exist before starting. If any are missing, the pipeline fails fast with a clear error listing the absent VCF accounts.
prepare-depot: Configures the Broadcom download token on the installer, syncs the depot catalog, and downloads all required component binaries (~30-60 min)start-bringup --wait: Submits the bringup spec to the VCF Installer and polls until the workflow completes. Deploys vCenter, NSX managers, SDDC Manager, and VCF Operations (~2-4 hours)remove-installer-datastore: Storage-vMotions any VMs off the 256 GB VMFS datastore we manually created earlier to vSAN, then unmounts the datastore (~5-10 min)destroy-ebs-volume: From the AWS side, detaches and deletes the EBS volume that hosted the now-unmounted VMFS datastore (~30 sec)deploy-edge-cluster: Deploys two NSX edge appliances, creates an edge cluster, configures Tier-0/Tier-1 routing, and establishes BGP peering with AWS Route Server (~30-50 min)create-connector: Registers the VCF Operations Manager connector with EVS via CreateEnvironmentConnector. Polls untilACTIVE. (~2-5 min)
The following subsections provide a more detailed, step-by-step view of what Phase 3 does under the hood. The section titled Running deploy-vcf-and-edge contains the single command to execute the full Phase 3 workflow.
Depot and bundle management
The prepare-depot substep replaces the manual process of logging into the VCF Installer UI to configure your Broadcom depot. It:
- Stores your depot token on the installer via the VCF SDK
- Triggers a metadata sync to refresh the bundle catalog
- Identifies all INSTALL-type bundles matching your target version
- Downloads all required component binaries (vCenter, NSX, SDDC Manager, VCF Operations, ESXi)
- Polls until all downloads complete before proceeding to bringup
Tip: If you need to debug depot issues, individual actions like list-bundles, get-depot-settings, and sync-depot are available as standalone CLI commands.
VCF bringup workflow
The start-bringup action submits the typed SddcSpec to the VCF Installer and monitors the workflow. During bringup, the installer:
- Commissions the ESXi hosts into the VCF management domain
- Deploys and configures vCenter Server
- Deploys NSX Managers and clusters them behind a virtual IP address
- Deploys SDDC Manager
- Deploys VCF Operations
- Configures vSAN ESA across all hosts
- Creates the distributed virtual switch with all required port groups
Tip: The CLI polls the installer every 10 minutes and reports progress. If bringup fails, check the installer UI at https://<sddcm_name>.<your-fqdn> for detailed per-task error information.
Installer cleanup
After bringup completes successfully, the automation performs two cleanup steps:
remove-installer-datastore: Storage-vMotions any VMs that landed on the local VMFS datastore to vSAN, then unmounts the datastore from the host. This frees the EBS volume for deletion.destroy-ebs-volume: Detaches the EBS volume from the EC2 instance and deletes it. The volume is identified by itsManagedByandEnvironmentIdtags to prevent accidental deletion of other volumes.
NSX Edge Cluster deployment
The next substep deploys the NSX Edge Cluster directly via the NSX Manager and vCenter APIs. It runs seven stages:
prep-edge-cluster: Creates DVS TRUNK port group, IP pool, uplink profile, VLAN transport zonedeploy-edge-nodes: Creates two large-form-factor edge transport nodes (triggers OVA deployment)create-edge-cluster: Creates edge cluster grouping both transport nodescreate-tier0: Creates tier-0 gateway with locale service and BGP enabledcreate-tier1: Creates tier-1 gateway attached to Tier-0 and edge clusterconfigure-routing: Creates uplink segments, interfaces, BGP neighbors, prefix lists, static routes, redistributioncreate-anti-affinity: Creates vCenter DRS anti-affinity rule for edge VMs
Each edge appliance peers BGP with one AWS Route Server endpoint using ASN 65000 (NSX side) and 65022 (AWS side). Once peering is established, NSX overlay segments are automatically advertised as routes in your VPC route tables.
Ops Manager Connector
The final substep registers the VCF Operations Manager connect to Amazon EVS. This is used for downstream actions such as creating Windows Server license entitlements for your virtual machines.
Setting environment variables
Phase 3 requires two secrets that are not stored in Secrets Manager: the VCF_INSTALLER_PASSWORD that you set during the manual steps above, and the VCF_DEPOT_TOKEN from the Broadcom portal. The following commands set them as environment variables (Linux):
# The admin@local password you set when deploying the installer OVA:
read -rs VCF_INSTALLER_PASSWORD ; export VCF_INSTALLER_PASSWORD
# Your Broadcom depot download token:
read -rs VCF_DEPOT_TOKEN ; export VCF_DEPOT_TOKEN
For Windows:
# The admin@local password you set when deploying the installer OVA:
$env:VCF_INSTALLER_PASSWORD = Read-Host -MaskInput "VCF Installer Password"
# Your Broadcom depot download token:
$env:VCF_DEPOT_TOKEN = Read-Host -MaskInput "VCF Depot Token"
All other passwords (vCenter, NSX, SDDC Manager, etc.) are resolved automatically from Secrets Manager.
Running deploy-vcf-and-edge
Create the Python environment, then run the single CLI command to run the entire Phase 3 pipeline end-to-end (Linux):
cd Phase_3_VCF9/python
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
python -m src.main deploy-vcf-and-edge \
--installer-host sddcm.<your-fqdn> \
--target-version 9.1.0 \
--nsx-manager-host nsx.<your-fqdn> \
--vcenter-host vc.<your-fqdn> \
--aws-profile your-aws-profile
For Windows:
cd Phase_3_VCF9\python
python -m venv .venv
.venv\Scripts\Activate.ps1
pip install -r requirements.txt
python -m src.main deploy-vcf-and-edge `
--installer-host sddcm.<your-fqdn> `
--target-version 9.1.0 `
--nsx-manager-host nsx.<your-fqdn> `
--vcenter-host vc.<your-fqdn> `
--aws-profile your-aws-profile
Individual substeps can also be run separately for debugging, though the single-command approach is strongly recommended.
Verification and Next Steps
Once deploy-vcf-and-edge returns successfully, verify end-to-end connectivity via the following.
Verify Route Server BGP peers
In the AWS Console, navigate to VPC, then Route Servers, then Peers. Both BGP peers should show BGP Status "Up". The learned routes tab should display NSX-originated CIDRs (any segments you create later will appear here automatically).
Create a test NSX segment
Log into NSX Manager (https://nsx.<your-fqdn>) and create a new overlay segment attached to the Tier-1 gateway:
- Go to Networking > Segments >Add Segment
- Name the segment test-segment.
- Attach the segment to your Tier-1 gateway
- Set a subnet (e.g., 172.16.1.0/24 with gateway 172.16.1.1)
- Deploy a test VM on this segment and confirm it receives an IP
Confirm overlay-to-underlay connectivity
From the test VM on your NSX segment:
- Ping the jumpbox in the public subnet (if deployed)
- Ping an EC2 instance in the service-access subnet
- Verify that the segment CIDR (172.16.1.0/24) appears as a learned route in the VPC route table
If all three checks pass, your EVS environment is fully operational with dynamic route propagation between the NSX overlay and the AWS underlay.
Next steps:
- Migrate workloads from on-premises using VMware HCX or other migration tools
- Configure AWS Transit Gateway for hybrid connectivity to your data center (this is if you didn't optionally create this in Phase 1)
- Set up Amazon FSx for NetApp ONTAP as supplemental storage
- Integrate AWS Systems Manager for operational monitoring
- Deploy additional workload domains via SDDC Manager
Troubleshooting
Here are the most common failure modes and where to look for resolution:
Phase 1 and 2: AWS resource errors
- Check the AWS Console for the affected resource. The Terraform or boto3 error text usually points to a specific resource that did not provision correctly (wrong AZ, missing subnet, throttled API call).
- Verify service limits: EVS service quotas, Dedicated Host allocations, VPC Route Server quotas, and EBS volume limits.
- If host realization times out (>90 min), check the EVS environment status in the console. A FAILED state indicates a capacity or configuration issue.
Phase 3: Depot sync issues
- Verify your Broadcom depot token is valid and not expired
- Ensure the installer appliance has outbound internet access (port 443) to depot.broadcom.com
- If downloads stall, the automation retries with exponential backoff. After 5 failed attempts, it will report the failure and you can retry manually with
download-all-product-binaries --wait
Phase 3: Bringup failures
- The VCF Installer UI (
https://<sddcm_name>.<your-fqdn>) provides per-task progress and detailed error messages that are more informative than the API error body. - Check
/var/log/vmware/vcf/domainmanager/domainmanager.logon the installer appliance for stack traces. - If bringup fails with "VMwareProductVersion can not be null or empty," the depot does not have the required binaries cached. Re-run
prepare-depotand retry.
Phase 3: Edge cluster deployment
- Edge node deployment can fail if the vSAN datastore does not have enough free space (each edge VM requires ~200 GB)
- BGP peering issues: verify the Route Server endpoint IPs in the edge cluster spec match those from Phase 1 Terraform outputs
- If configure-routing fails, check that both edge nodes reached
Successstate before the cluster was created
Tip: Every individual action in the automation is idempotent. If a step fails, fix the underlying issue and re-run the same command safely without side effects.
Cleanup
Should you wish to tear down what we have built here, follow these steps:
- If you wish to preserve your virtual machines within EVS, first migrate them elsewhere.
- Via the AWS Console, delete each of the EVS hosts one by one.
- Via the AWS Console, delete the EVS environment.
- From your original workstation where you ran Phase 1, navigate to the
Phase_1_Base_Infrastructuredirectory and runterraform destroy. Terraform will use the existing state file to identify and remove all Phase 1 resources.
Conclusion
In this walkthrough, we deployed VMware Cloud Foundation 9.1 on Amazon EVS using a three-phase automation toolkit. Starting from a bare AWS account, we provisioned all prerequisite AWS infrastructure with Terraform, deployed an EVS environment and bare-metal hosts with the Python CLI via the AWS API, and on the VMware side, brought up the full VCF stack with NSX Edge Cluster routing using the official VCF Python SDK.
The entire deployment, from terraform apply to verified BGP peering, takes approximately 3.5 to 6 hours of wall-clock time. The automation reduces the manual effort to three CLI commands plus a brief 30-minute manual interlude for ESXi configuration and OVA deployment.
Key benefits of this approach:
- Infrastructure as code: Every resource is defined in Terraform or generated by the Python automation
- Security by default: All VCF passwords are generated to strict complexity requirements and stored in AWS Secrets Manager
- Safe reruns: Phases 1 and 3 are fully idempotent, meaning any step can be safely re-run for debugging or recovery without side effects
- SDK-driven: Phase 3 uses the official VMware VCF Python SDK, eliminating manual REST payload construction
- Modular design: Run the full pipeline with one command, or run individual steps for debugging and partial reruns
Whether you are setting up a development environment, a production deployment, or a repeatable lab for customer demonstrations, this automation provides a solid foundation that you can version-control, customize, and extend.