- Home
- Multi-Cloud Networking (MCN)
- Multi-cloud networking CE-HA demo
- Engineering Specification
Engineering Specification
This document serves as the human-readable Engineering Specification for the Active/Active
eBGP/ECMP F5 XC Customer Edge (Secure Mesh v2) architecture on Microsoft Azure.
It functions as both an architectural specification and an execution prompt for xcsh -p.
Evidence scope
Section titled “Evidence scope”The SMSv2 guide is the operator reference for current AWS Transit Gateway Connect behavior: three independent sites, six physical interfaces, six Connect peers, and twelve BGP sessions. PR #1103 proves AWS failover and serial upgrades. Azure observations below retain their dates; the final provider-v8 acceptance did not mutate or re-prove Azure end-to-end.
1. System Overview & Objective
Section titled “1. System Overview & Objective”Observed 2026-08-05. Architectural specification:
The deployment provisions an Active/Active eBGP/ECMP F5 Distributed Cloud (XC) Customer Edge (CE) Secure Mesh v2 topology on Microsoft Azure with an Amazon Web Services (AWS) extension, a parallel Canadian regional extension, and an On-Premise KVM extension.
- Routing Fabric: CEs originate host routes (
/32) via eBGP (ASN64512) to an Azure Route Server, AWS Transit Gateway Connect, or containerized ToR BGP router (ASN65515). The VNets, VPCs, and local libvirt networks use native ECMP for active/active traffic distribution. - Four Network Paths:
- Rest of World (ROW): Serves
mcn-ce-ha.f5-sales-demo.comvia 3 CEs ineastus(10.0.0.0/16VNet) with global Public Regional Edge advertisement. - Canada Extension: Serves
mcn-ce-ha.f5-sales-demo.cavia 3 CEs incanadacentral(10.200.0.0/16VNet) advertised strictly through Canadian Regional Edges (Toronto and Montreal) and Canadian CEs. - AWS Customer Edge Extension: Serves
aws.mcn-ce-ha.f5-sales-demo.comvia 3 EC2 CEs (m5.2xlarge) in AWS VPC (10.150.0.0/16inap-northeast-1) with dual NICs (public SLO / private SLI) and eBGP/ECMP routing. - On-Premise KVM Extension: One CE (
onprem-ce-01,10.100.0.11) peers with FRR (10.100.0.2, ASN65515) on the local libvirt network (10.100.0.0/24). The NAT gateway is10.100.0.1, the workload is10.100.0.100, and one BGP peer imports198.51.100.0/24.
- Rest of World (ROW): Serves
2. Provider Requirements & Tenant Guardrails
Section titled “2. Provider Requirements & Tenant Guardrails”Provider Specifications (versions.tf, providers.tf)
Section titled “Provider Specifications (versions.tf, providers.tf)”- Terraform CLI:
>= 1.16.1 - Providers:
f5-sales-demo/xcsh(= 11.0.2):api_urlis dynamically derived fromvar.expected_xc_tenant(https://${var.expected_xc_tenant}.console.ves.volterra.io).hashicorp/azurerm(~> 4.0): Declaresfeatures {}andsubscription_id = var.subscription_id.hashicorp/aws(~> 5.0): Configures AWS regionvar.aws_location(ap-northeast-1).hashicorp/azuread(~> 3.0): Resolves deployer identity for resource naming and tagging.hashicorp/external(~> 2.3): Executes environment tenant guard script.hashicorp/random(~> 3.0): Generates per-CE Site Console admin passwords.dmacvicar/libvirt(~> 0.8.0/v0.8.3): Manages local KVM domains, volumes, seed ISOs, and network bridges for on-premise Customer Edge nodes.
- Backend: Partial Azure Blob storage backend (
backend "azurerm" {}withbackend.hcl.example).
Tenant Guard & CIDR Safety Checks (data.tf, main.tf, scripts/xc-env-tenant.sh)
Section titled “Tenant Guard & CIDR Safety Checks (data.tf, main.tf, scripts/xc-env-tenant.sh)”- Tenant Guard: Executable script
scripts/xc-env-tenant.sh(chmod +x) outputs JSON{"tenant":"<label>","api_url_set":"<bool>"}fromXCSH_API_URL. Alifecycle { postcondition }block ondata.external.xc_env_tenantasserts the ambient tenant matchesvar.expected_xc_tenant(f5-sales-demo), failing the plan if pointed at the wrong tenant. - CIDR Safety Checks:
check "vip_outside_vnet_cidrs"andcheck "ca_vip_outside_vnet_cidrs"assert that VIPs (10.250.0.10and10.250.1.10) sit strictly outside all hub and spoke VNet CIDRs to prevent VNet system routes from overriding BGP host routes.
3. Appliance Bootstrapping (cloud-init/ce-node.yaml)
Section titled “3. Appliance Bootstrapping (cloud-init/ce-node.yaml)”Each Azure CE virtual machine renders this Azure-specific #cloud-config template on first boot.
AWS uses the separate site-bound JWT and certified-image flow,
which preserves /etc/vpm/config.yaml and injects /etc/vpm/user_data:
- VPM Configuration: Writes
/etc/vpm/config.yaml(0600,root:root) containing:Vpm:ClusterType: ce,ClusterName: ${cluster_name},Token: ${token}MauriceEndpoint: https://register.ves.volterra.ioMauricePrivateEndpoint: https://register-tls.ves.volterra.ioCertifiedHardwareEndpoint: https://vesio.blob.core.windows.net/releases/certified-hardware/azure.ymlKubernetes:EtcdUseTLS: true,Server: vip,CloudProvider: disabled
- SSH Access: Writes operator public SSH key to
/var/home/admin/.ssh/authorized_keys(0600,admin:admin) for Site Console CLI access.
4. Modular Infrastructure Topologies (modules/)
Section titled “4. Modular Infrastructure Topologies (modules/)”Topology Expansion (modules/ce-topology)
Section titled “Topology Expansion (modules/ce-topology)”Pure-computation module expanding ce_count (1..3) into per-CE node maps:
hostname:<hostname_prefix>-0<n>site_name:<site_prefix>-<region_short>0<n>slo_ip:cidrhost(mgmt_subnet_prefix, 4 + i)az: Availability zones1,2,3interface_name:ves-io-securemesh-site-v2-<site_prefix>-<region_short>0<n>-network-<hostname_prefix>-0<n>-eth0-0
Azure Hub Infrastructure (modules/azure-hub)
Section titled “Azure Hub Infrastructure (modules/azure-hub)”- Resource Group:
rg-<component>-<deployer>where<deployer>resolves from Azure AD via 4-tier fallback logic inlocals.tf. - VNet & Subnets: Hub VNet (
hub-vnet) withsnet-hub-management,snet-hub-external,snet-hub-internal,RouteServerSubnet(/27, no NSG), and optionalAzureBastionSubnet(/26). - Azure Route Server:
<component>-rswith Standard Public IP and ASN65515. - Azure Bastion:
<component>-bastion(Standard SKU,tunneling_enabled = true,ip_connect_enabled = true).
Customer Edge Nodes (modules/ce-node)
Section titled “Customer Edge Nodes (modules/ce-node)”- User-Assigned Identity per CE node.
- 3 NICs per VM (mgmt/SLO with
private_ip_address_allocation = "Static", externalDynamic, internalDynamic) withip_forwarding_enabled = trueandaccelerated_networking_enabled = false. azurerm_linux_virtual_machine: Admin usernameazureuser(Azure blocks reserved nameadmin). Uses marketplace imagevolterraedgeservices/volterra-node/volterra-nodewith requiredplanblock, 64 GBStandardSSD_LRSOS disk, andcustom_data = base64encode(cloud_init).
F5 XC Site & BGP Binding (modules/xc-site)
Section titled “F5 XC Site & BGP Binding (modules/xc-site)”- XC Site: Resource
xcsh_securemesh_site_v2with expliciteth0interface inazure.not_managed.node_list.interface_listwithethernet_interfaceandnetwork_option.site_local_network = {}bound to mgmt NIC MAC. - Node Rebuild Lifecycle Coupling: Contains
terraform_data.ce_vmparking the Azure VM instance ID withlifecycle { replace_triggered_by = [terraform_data.ce_vm] }insidexcsh_securemesh_site_v2. Rebuilding the VM destroys the site object, releasing its stale registration index and preventingUniqueSecondaryIndexViolationon re-boot. - Registration Approval: Data source
data.xcsh_site_registrationresolves runtimer-<uuid>registration name, approved automatically byxcsh_registration_approvalwithname = data.xcsh_site_registration.this.nameandnamespace = "system". - eBGP Peering: Resource
xcsh_bgpconfigures CE ASN64512to Azure Route Server ASN65515on port 179 bound to interfacevar.interface_nameinsystemnamespace, usingwhere.site.ref(network_type = "VIRTUAL_NETWORK_SITE_LOCAL",disable_internet_vip = {}),bgp_parameterswithasn = var.ce_asnandlocal_address = {}, and dynamicpeers(externalblock withasn = var.rs_asn,address = var.rs_peer_ips[peers.value],port = 179,interfacereference tovar.interface_nameinsystemnamespace,disable_v6 = {},passive_mode_disabled = {},bfd_disabled = {}).
Route Server Peering & Test Client
Section titled “Route Server Peering & Test Client”modules/azure-route-server-bgp: Resourceazurerm_route_server_bgp_connectionconnecting Route Server to CE management private IP.modules/client-vm: Test client Ubuntu VM insnet-hub-internalwith NSG, public IP,admin_username = "azureuser", andprivate_ip_address_allocation = "Dynamic".
On-Premise KVM Infrastructure (kvm.tf, onprem_kvm.tf, providers_libvirt.tf)
Section titled “On-Premise KVM Infrastructure (kvm.tf, onprem_kvm.tf, providers_libvirt.tf)”- libvirt Provider:
provider "libvirt"targeting local QEMU hypervisor (qemu:///system). - Network Bridge:
libvirt_network.ce_bgp_netcreates a generation-named NAT bridge from the declared MAC/IP reservation map, with DHCP and DNS enabled. - Base Image & Storage:
libvirt_volume.base_cloudimports only the F5-issued KVM appliance URL fromxcsh_site_image;libvirt_volume.ce_diskprovisions one 100 GiB root overlay disk (onprem-ce-01). The pinned v11.0.2 provider resolves the image by the uniquely owned Site UID, checks its exact response mapping, HTTPS URL and MD5, and rechecks ownership before libvirt mutation. - Cloud-Init ISO Seed:
libvirt_cloudinit_disk.ce_cloudinitinjects the site-bound SMSv2 token into/etc/vpm/user_datafor the generated${local.site_prefix}-kvmsite. - KVM Domain:
libvirt_domain.ce_nodedefines one 8 vCPU / 32 GiB RAM CE with autostart enabled, attached toce-bgp-netat10.100.0.11. - F5 XC Site & eBGP:
xcsh_securemesh_site_v2.onprem_kvmcreates the non-AppStack Secure Mesh Site v2 site, andxcsh_bgp.onprem_ebgppeers CE ASN64512with the Terraform-owned FRR router (10.100.0.2, ASN65515) overeth0;10.100.0.1remains the libvirt NAT gateway.
5. Application Tier & Regional Extension (main.tf)
Section titled “5. Application Tier & Regional Extension (main.tf)”Rest of World App Tier
Section titled “Rest of World App Tier”- Azure Registration Token: Tenant-scoped
xcsh_token.ce(mcn-ce-registrationinsystemnamespace, notypeargument). - Namespace Lookup: Read-only lookup
data.xcsh_namespace.mcn(var.xc_app_namespacedefaulting tomulti-cloud-networking,namespace = ""). - Origin Pool:
xcsh_origin_pool.thistargetingvar.origin_ip:var.origin_portwithROUND_ROBINandDISTRIBUTEDselection. - HTTP Load Balancer:
xcsh_http_loadbalancer.this(mcn-ce-ha-f5se) servingvar.lb_domainwithadvertise_customadvertising VIP10.250.0.10onSITE_NETWORK_OUTSIDEper CE site, with explicitdepends_on = [module.xc_site].
Canada Regional Extension (enable_canada = true)
Section titled “Canada Regional Extension (enable_canada = true)”- Parallel Hub VNet (
10.200.0.0/16incanadacentral), 3 Canadian CE VMs, Canada Route Server, Canadian eBGP connections, Client VM. - Canadian Virtual Sites:
xcsh_virtual_site.canada_re: Targets Regional Edge citiestorontoandmontreal(ves.io/city in (toronto, montreal)).xcsh_virtual_site.canada_ce: Targets Canadian CE site names (ves.io/siteName).
- Canadian Origin Pool & Load Balancer:
xcsh_origin_pool.canadaandxcsh_http_loadbalancer.canadaservingmcn-ce-ha.f5-sales-demo.caadvertising VIP10.250.1.10/32.
6. Deployment Artifacts & Outputs (outputs.tf)
Section titled “6. Deployment Artifacts & Outputs (outputs.tf)”Exports operational metrics required for verification:
- Node maps, private/public IPs, Route Server IDs and peer IPs, BGP peer addresses.
- Domain names, advertised VIPs, client NIC names.
- Sensitive
ce_registration_tokenand per-CE Site Console admin passwords (site_console_admin_passwords).