A Terraform-based solution to generate manifests for connecting F5 Distributed Cloud to multiple Tailscale networks using containerized proxies.
- Multi-Tailnet Support: Connect to multiple Tailscale networks simultaneously
- Proxy-Based Routing: High-performance L4 proxy containers with advanced traffic management
- Kubernetes Native: Utilise native Kubernetes objects and deployment
- Dynamic Configuration: Automatic port allocation and service discovery
- Origin Pools: Define backend services for load balancing
- Health Checks: Monitor service availability and service monitoring
- Traffic Distribution: Route requests based on routing policies
- Security Policies: WAF, DDoS protection, and security controls
- Global Load Balancer: Multi-region traffic distribution
- Analytics: Traffic insights and monitoring
- Service: Exposes multiple ports (10000+)
- RBAC: ServiceAccount, Role, and RoleBinding for secure access
- ConfigMaps: Proxy configuration templates
- Secrets: Secure storage of Tailscale authentication keys
- StatefulSet: Main application deployment containing proxy containers
- Proxy Container(s): L4 TCP proxy with tunneling support
- Listeners: One per service port (10000 + tailnet_index * 1000 + service_index)
- Backend Routing: Route traffic directly to Tailscale network services
- Userspace Mode: Containers capable of running in userspace mode for enhanced security and isolation
- Tailscale Nodes: Nodes can live across multiple tailnets
- Tailscale MagicDNS: Services accessible via Tailscale hostnames
- Port Mapping: Internal service ports preserved through the proxy chain
- Protocol Support: TCP tunneling through Tailscale mesh VPN
- Service Examples:
app.tailnet0.ts.net:80api.tailnet1.ts.net:3000db.tailnet2.ts.net:5432monitoring.tailnet3.ts.net:9090
Note: The deployment script uses kubectl to apply configuration. Make sure it has been initialised within your console with the appropriate KubeConfig. https://docs.cloud.f5.com/docs-v2/administration/how-tos/user-mgmt/Credentials.
-
Clone the repository:
git clone <repository-url> cd f5xc-tailnet-egress
-
Configure your tailnets:
cp terraform.tfvars.example terraform.tfvars # Edit terraform.tfvars with your tailnet configurationstailnets = [ { tailnet_name = "tailnet0" tailnet_key = "tskey-auth-..." # Tailscale authentication key use_k8s_secret = true # Enable RBAC and secret management services = [ { endpoint = "app.tailnet0.ts.net" protocol = "tcp" # "tcp" or "udp" port = 80 connection_timeout = 10 # Optional: connection timeout in seconds f5xc_origin_pool = "tailnet0-web-pool" # F5 XC origin pool name } ] }, { tailnet_name = "tailnet1" tailnet_key = "tskey-auth-..." # Different key for tailnet1 use_k8s_secret = true # Enable RBAC and secret management services = [ { endpoint = "api.tailnet1.ts.net" protocol = "tcp" port = 3000 f5xc_origin_pool = "tailnet1-api-pool" } ] }, { tailnet_name = "tailnet2" tailnet_key = "tskey-auth-..." use_k8s_secret = true services = [ { endpoint = "db.tailnet2.ts.net" protocol = "tcp" port = 5432 connection_timeout = 30 # Longer timeout for database f5xc_origin_pool = "tailnet2-db-pool" } ] }, { tailnet_name = "tailnet3" tailnet_key = "tskey-auth-..." use_k8s_secret = true services = [ { endpoint = "monitoring.tailnet3.ts.net" protocol = "tcp" port = 9090 f5xc_origin_pool = "tailnet3-monitoring-pool" } ] } ]
-
Deploy the egress service:
./deploy.sh
- Initialize Terraform - Set up working directory and providers
- Validate Configuration - Verify Terraform syntax and configuration
- Apply Infrastructure - Generate all configuration files and manifests
- Generate Files:
- Kubernetes manifests in
outputs/envoy/k8s/ - F5 XC origin pool JSONs in
outputs/envoy/f5xc/ - Configuration summary
- Start kubectl Proxy - Establish connection to Kubernetes cluster
- Create F5 XC Origin Pools - Deploy origin pools via F5 XC API
- Apply Kubernetes Manifests - Deploy all Kubernetes resources
- Verify Deployment - Check resource status and health
- Origin Pool - with unique suffix names
- Namespace
- ServiceAccount
- ConfigMap - proxy configuration
- Service: - ClusterIP with neccessary ports mappings
- StatefulSet: main application with proxy containers
If Using Secrets,
- Role - RBAC permissions
- RoleBinding - bind role to service account
- Secrets - Tailscale authentication keys for each tailnet
The egress service uses a systematic port allocation scheme that works with any L4 proxy container:
- Service Ports:
10000 + (tailnet_index * 1000) + service_index
Example:
- Tailnet 0: ports 10000-10999
- Tailnet 1: ports 11000-11999
- Tailnet 2: ports 12000-12999
- RBAC Integration: Automatic ServiceAccount, Role, and RoleBinding generation
- Secret Management: Secure storage of Tailscale authentication keys
The current default implementation uses Envoy proxy containers, but the architecture is designed to support other proxy solutions. You can modify the container images and configurations in the templates to use alternative proxies like socat, gost, tail4ward, or other custom solutions. The port allocation and routing logic is proxy-agnostic. More proxy configurations will be added to the project soon.
- Envoy Solution - Envoy proxy implementation details
- Terraform >= 1.0
- Kubernetes cluster with RBAC enabled
- Tailscale authentication keys
- F5 Distributed Cloud access
These solutions are designed for can also be deployed on other standard Kubernetes distributions.
On F5 Distributed Cloud (F5 XC), these solutions can be deployed on:
- Regional Edges (RE): For centralized, multi-region traffic management
- Customer Edges (CE): For local, on-premises or edge deployments
This flexibility allows you to choose the optimal deployment model based on your network architecture and requirements.
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests and documentation
- Submit a pull request
This project is licensed under the MIT License. See LICENSE.md for full details.
For issues and questions:
- Open an issue on GitHub
- Review the example configurations