🚀 This Terraform project deploys F5 Distributed Cloud (XC) SMSV2 (Secure Mesh Site V2) Customer Edge (CE) nodes on AWS. This code is updated as per the latest release.
This is a unified and flexible configuration. This module allows you to select your desired architecture by changing variables in the terraform.tfvars file.
This single codebase can handle:
- "Cluster" Model: A standard 1-node or 3-node Cluster site.
- "vSite" Model: Deploys 1, 2, or 3 independent nodes that are grouped into a single Virtual Site. This is the vsite based HA model.
- Public IP: Can create new Elastic IPs, use existing EIPs, or assign no public IP at all.
- NICs: Supports both single-NIC (SLO only) and dual-NIC (SLO + SLI) deployments.
- Core Configuration Concepts
- Prerequisites
- File Structure
- How to Deploy
- How to Destroy
- Deployment Outputs
- Troubleshooting & FAQ
You control the entire deployment architecture using the variables in terraform.tfvars.
The deployment_model variable is the most important choice. It determines the F5 XC site topology.
-
"cluster": (Standard Cluster Model)- Creates one
volterra_securemesh_site_v2resource in F5 XC. - If
num_nodes = 1, it will be a single node cluster - If
num_nodes = 3, it will be a 3 node cluster - All nodes (1 or 3) use a single, shared registration token.
- Use this model for standard single-node or 3-node Cluster sites.
- Creates one
-
"vsite": (Virtual Site Model)- Creates one
volterra_securemesh_site_v2resource per node. (e.g.,num_nodes = 2creates 2 separate site objects). - Creates a
volterra_virtual_siteresource that groups all the individual sites together using a shared label. - Each node gets its own unique registration token.
- Use this model to deploy multiple, independent nodes but manage them as a single logical group in F5 XC as a Virtual Site.
- Creates one
The public_ip_mode variable controls how public IPs are (or are not) assigned to the SLO (eth0) interface.
-
"CREATE_EIP": (Default)- Terraform will create a new AWS Elastic IP (EIP) for each node and attach it.
- Use this for simple "greenfield" deployments where you want the nodes to be reachable from the internet (e.g., for Site-to-Site VPN).
-
"USE_EXISTING_EIP":- Terraform will use a list of EIP Allocation IDs you provide in
existing_eip_allocation_ids. The list count must matchnum_nodes. - Use this if you have already reserved specific EIPs for this purpose.
- Terraform will use a list of EIP Allocation IDs you provide in
-
"NONE": (NAT / Proxy Model)- No public IP will be assigned.
- This is the correct choice for "brownfield" deployments where nodes are in a private subnet and egress traffic is handled by an existing AWS NAT Gateway or an HTTP proxy.
- If you select
NONE, you must ensure your private subnet's route table has a route to the internet (e.g.,0.0.0.0/0via a NAT Gateway) so the node can register with F5 XC.
num_nodes: The number of EC2 instances to deploy.- If
deployment_model = "cluster", must be1or3. - If
deployment_model = "vsite", can be1,2, or3.
- If
num_nics: The number of network interfaces per node.1: Deploys only an SLO (eth0) interface.2: Deploys both an SLO (eth0) and an SLI (eth1) interface.
- Terraform (v1.3.0 or newer).
- AWS Account with credentials configured for Terraform (e.g., via AWS CLI
aws configure). - F5 Distributed Cloud Account and an API Credential (
.p12file).
main.tf: Contains the primary logic for creating all AWS (EC2, NICs, EIPs, SGs) and F5 XC (site, token, label, vsite) resources.variables.tf: Defines all input variables, including their types, descriptions, and validation rules.provider.tf: Declares theawsandvolterra(F5 XC) providers.terraform.tfvars: A template for you to copy and fill in with your specific values.outputs.tf: Defines outputs, such as the public IPs of the created nodes.README.md: This file.
-
Clone this Repository
git clone <your-repo-url> cd <your-repo-name>
-
Edit
terraform.tfvarsThis is the most important step. Fill in all the required values. If you want you can save the file from this repo, copy to a new file and use that as a template.- XC Credentials:
api_p12_file,api_url - Deployment Model:
deployment_model,cluster_name,num_nodes,num_nics - AWS Compute:
region,ami,instance_type,key_pair - AWS Networking:
vpc_id,az_names,slo_subnet_ids,sli_subnet_ids(ifnum_nics = 2) - IP Configuration:
public_ip_mode,existing_eip_allocation_ids(if needed) - Security Groups:
security_group_config
Note: The number of items in
az_namesandslo_subnet_ids(andsli_subnet_idsif used) must match yournum_nodesvalue. - XC Credentials:
-
Initialize Terraform
terraform init
-
Plan the Deployment Review the changes Terraform will make.
terraform plan
-
Apply the Configuration Type
yesto approve the deployment.terraform apply
To tear down all resources created by this project, run the destroy command.
terraform destroyAfter a successful terraform apply, this module provides structured outputs for you to easily see what was created.
To see a complete summary of all the resources you deployed, run:
terraform output deployment_summaryThis will display a structured object containing key information, such as:
- AWS Instance IDs and Availability Zones
- Public and Private IP addresses
- Created Security Group IDs (if any)
- F5 XC Site Names
- The F5 XC Virtual Site Name (if created)
- A summary of your chosen inputs (like
deployment_model,node_count, etc.)
Sample Output VSITE Model
deployment_summary = {
"aws_instance_azs" = [
"us-east-1a",
"us-east-1b",
"us-east-1c",
]
"aws_instance_ids" = [
"i-002f7b13f11905e3d",
"i-05165acf134c71212",
"i-0edc83f6c08811028",
]
"aws_region" = "us-east-1"
"cluster_name" = "my-aws-site"
"created_security_groups" = {
"sli" = "sg-04187191e68bb8eb5"
"slo" = "sg-02e8d161137c3ce2d"
}
"deployment_model" = "vsite"
"f5_xc_site_names" = [
"my-aws-site-1",
"my-aws-site-2",
"my-aws-site-3",
]
"f5_xc_virtual_site_name" = "my-aws-site-vsite"
"nic_count" = 2
"node_count" = 3
"private_ips_slo" = [
"10.0.1.79",
"10.0.2.139",
"10.0.3.54",
]
"private_ips_sli" = [
"10.10.1.100",
"10.10.2.100",
"10.10.3.100",
]
"public_ip_mode" = "CREATE_EIP"
"public_ips_slo" = [
"3.76.148.184",
"18.184.148.129",
"18.156.96.150",
]
}Sample Output CLUSTER Model
deployment_summary = {
"aws_instance_azs" = [
"eu-central-1a",
"eu-central-1b",
"eu-central-1c",
]
"aws_instance_ids" = [
"i-03b7a581c7142c3ff",
"i-02b320a6edb3a1449",
"i-040628d2e5f24c061",
]
"aws_region" = "eu-central-1"
"cluster_name" = "aws-ha-model-11"
"created_security_groups" = {
"sli" = "sg-095fe12d3ca44df13"
"slo" = "sg-09b568cf48d401ddc"
}
"deployment_model" = "cluster"
"f5_xc_site_names" = [
"aws-ha-model-11",
]
"f5_xc_virtual_site_name" = "N/A (Cluster Model)"
"nic_count" = 2
"node_count" = 3
"private_ips_sli" = [
"10.0.11.72",
"10.0.12.212",
"10.0.13.47",
]
"private_ips_slo" = [
"10.0.1.105",
"10.0.2.192",
"10.0.3.94",
]
"public_ip_mode" = "CREATE_EIP"
"public_ips_slo" = [
"35.156.248.106",
"3.76.239.28",
"63.180.128.168",
]
}Q: terraform plan fails with a "Invalid value" error from a check block.
- A: This is by design. We use
checkblocks to validate your variable combinations before creating resources. Read the error message carefully. It will tell you exactly what is wrong.- Example 1:
Invalid EIP configuration: ... 'existing_eip_allocation_ids' must contain exactly 3 ID(s).- Fix: You set
num_nodes = 3andpublic_ip_mode = "USE_EXISTING_EIP", but yourexisting_eip_allocation_idslist does not contain 3 items. Add the correct number of EIP IDs.
- Fix: You set
- Example 2:
Invalid node count: For 'cluster' model, num_nodes must be 1 or 3.- Fix: You set
deployment_model = "cluster"andnum_nodes = 2. This is an invalid combination. Changenum_nodesto1or3.
- Fix: You set
- Example 1:
Q: terraform apply fails with an error about element() or count.index.
- A: This almost always means your lists in
terraform.tfvarsdo not have the same number of items asnum_nodes. - Fix: Ensure that the number of items in
az_names,slo_subnet_ids, and (if used)sli_subnet_idsexactly matches the value ofnum_nodes.
Q: My EC2 instances were created, but the site never comes "Online" in the F5 XC Console.
- A: This means the CE node cannot communicate with the F5 XC global network to register. This is an egress connectivity problem.
- Fix:
- Check your
public_ip_mode:- If
"CREATE_EIP"or"USE_EXISTING_EIP": Ensure your SLO Security Group (security_group_config) allows outbound (egress) traffic on TCP port 443. If you usedcreate_slo_sg = true, this is done for you. If you used an existing SG, you must add this rule. - If
"NONE": This is the most common cause. Your private subnet (where the SLO NIC lives) must have a route table entry that directs internet-bound traffic (e.g.,0.0.0.0/0) to an AWS NAT Gateway. Without this, the node has no way to call home.
- If
- Test Connectivity: SSH into the EC2 instance using your
key_pair. Once inside, runcurl -v https://google.com. If this fails or times out, your AWS networking (Route Tables, Security Groups, or NAT Gateway) is not configured correctly for egress.
- Check your
Q: terraform plan fails with an "Invalid cluster_name" error.
- A: Your
cluster_namedoes not meet the DNS-1035 label standard. - Fix: The name must be all lowercase, can contain numbers and hyphens (
-), must start with a letter, and must end with a letter or number.- Good:
my-f5-site-1 - Bad:
My-Site,1-site-f5,my-site-
- Good: