Tailscale Networking Overview¶
Tailscale provides the primary access layer for CWIQ.IO infrastructure — replacing VPN concentrators, bastion hosts, and per-instance SSH key management with identity-based WireGuard mesh networking.
What Tailscale Provides¶
Tailscale is a zero-configuration mesh VPN built on WireGuard. For CWIQ.IO it delivers:
| Capability | How Used |
|---|---|
| Developer SSH access | Engineers connect to any server by Tailscale hostname without public IPs or bastion hosts |
| Cross-VPC service connectivity | Services in the dev VPC reach shared-services (Authentik, Vault) via Tailscale mesh |
| Cross-account access | Shared-services servers reach dev servers and vice versa |
| Managed service access | Subnet routers make RDS, ALB, and other AWS managed services reachable from Tailscale clients |
| Identity-based ACLs | Access controlled by user/tag identity, not IP whitelists |
Architecture¶
TAILSCALE CONTROL PLANE
(Auth, Key Exchange, ACLs)
│
┌────────────────────┼─────────────────────┐
│ │ │
▼ ▼ ▼
┌──────────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ Shared-Services │ │ Dev VPC │ │ Developer │
│ VPC (10.0.0.0/16)│ │ (10.1.0.0/16) │ │ Laptops │
│ │ │ │ │ (100.64.x.x) │
│ Subnet Router │◄─┼►Subnet Router │ │ │
│ 10.0.12.x │ │ 10.1.40.x │ │ Tailscale │
│ (advertises │ │ (advertises │ │ client │
│ 10.0.0.0/16) │ │ 10.1.0.0/16) │ │ │
└──────────────────┘ └──────────────────┘ └─────────────────┘
Subnet Routers¶
Each VPC has one EC2 instance running the Tailscale client with subnet routing enabled:
| VPC | Subnet Router | Advertises | Subnet |
|---|---|---|---|
| Shared-Services | tailscale-shared |
10.0.0.0/16 |
10.0.12.0/26 (vpn-access-1a) |
| Dev | tailscale-dev |
10.1.0.0/16 |
10.1.40.0/26 (vpn-access-1a) |
Subnet routers use SNAT mode by default. Traffic from Tailscale clients (100.64.x.x) appears to VPC resources as originating from the router's VPC IP (10.0.12.x or 10.1.40.x). This means VPC security groups only need to allow the router subnet CIDR, not the full Tailscale CGNAT range.
Tailscale vs AWS Native Networking¶
Is traffic going to/from the public internet?
├── YES → AWS (NAT Gateway, ALB, Internet Gateway)
└── NO → Is source an EKS runner pod?
├── YES → VPC peering (pods have no Tailscale)
└── NO → Tailscale mesh
| Scenario | Use | Why |
|---|---|---|
| Developer SSH to any server | Tailscale | No public IPs, no bastion |
| Dev server → Authentik SSO | Tailscale | Cross-VPC, subnet router handles routing |
| EKS pod → Nexus | VPC peering + private Route53 | Pods cannot run Tailscale |
| CI job → dev server (deploy) | VPC private IP (10.1.35.46) |
EKS pods have no Tailscale |
| Alloy agent → Loki/Prometheus | Tailscale hostname | Cross-VPC log/metric push |
| GitLab runner (host) → CI/CD targets | Tailscale | Host-level Tailscale available |
Key Benefits for CWIQ.IO¶
- No bastion hosts — Direct developer access to any server by Tailscale hostname
- No per-instance public IPs — All application servers are in private subnets
- Cross-VPC without Transit Gateway — Saves ~$88/month vs AWS Transit Gateway
- Managed service access — Subnet routers make RDS, ALBs, ElastiCache reachable from Tailscale
- ACL-based access control —
tag:devopsgets access to everything;tag:dev-appsgets access to shared-services only
Terraform Management¶
Tailscale ACLs are managed by the Terraform Tailscale provider in terraform-plan/. Changes to ACLs require:
- TAILSCALE_AUTH_KEY from .claude-env
- CREATED_BY variable
cd terraform-plan/organization/tailscale
terraform plan -var="tailscale_auth_key=$TAILSCALE_AUTH_KEY" -var="created_by=$CREATED_BY"
Related Pages¶
- MagicDNS & Hostname Conventions — Critical: use dashes not dots
- ACL Tags & Access Control — Tag structure and key rules
- Cross-VPC Connectivity — When to use Tailscale vs VPC peering
- SSH Access Patterns — SSH to any server