Tailscale as a Private Network Layer for Multi-Cloud Infrastructure
Written on October 17th, 2025 by Cody SniderConnecting resources across AWS, your office server, and a home lab used to mean VPN configurations that would make anyone question their career choices. IPsec tunnels, routing tables, firewall rules, the constant threat of misconfiguration locking you out. Tailscale removes that complexity entirely.
The Problem with Traditional VPNs
Traditional VPNs require central infrastructure. You need a VPN server, careful network planning, manual routing configuration, and prayer. Want to add a new cloud region? More configuration. Need to give a developer access from their laptop? Hope you documented the process.
The fundamental issue is that traditional VPNs treat networking as hub-and-spoke. Everything routes through a central point, creating a bottleneck and a single point of failure. When that VPN gateway goes down, your entire multi-cloud setup becomes unreachable.
How Tailscale Works
Tailscale builds on WireGuard, the modern VPN protocol that actually makes sense. Instead of routing all traffic through a central server, Tailscale creates direct peer-to-peer connections between devices. Your laptop talks directly to your AWS instance. Your office server connects directly to your home lab. The control plane coordinates which devices can talk to each other, but traffic flows point-to-point.
WireGuard itself is fast, secure, and simple. The entire protocol specification fits on a few pages. Tailscale adds the coordination layer, handling NAT traversal, key distribution, and access control. You get the security and performance of WireGuard without manually managing keys or network configuration.
Real-World Architecture
Here’s a practical setup: services running across AWS, a bare metal server in a data center, and development environments on laptops.
Install Tailscale on an AWS EC2 instance:
curl -fsSL https://tailscale.com/install.sh | sh
tailscale up --advertise-routes=10.0.0.0/16
That last flag tells Tailscale to advertise the entire VPC CIDR range. Other devices on your Tailscale network can now reach any resource in that VPC, not just the instance running Tailscale.
On your bare metal server:
curl -fsSL https://tailscale.com/install.sh | sh
tailscale up --advertise-routes=192.168.1.0/24
Now your AWS resources can reach services on your physical network, and vice versa. No VPN gateways, no complex routing, no firewall gymnastics.
On your development laptop:
tailscale up
That’s it. You can now SSH to any server, access internal databases, hit private APIs, all as if everything was on the same local network.
Access Control
The Tailscale admin console uses ACLs defined in JSON. Here’s a practical example:
{
"acls": [
{
"action": "accept",
"src": ["group:devs"],
"dst": ["tag:aws-prod:22", "tag:aws-prod:443"]
},
{
"action": "accept",
"src": ["tag:aws-prod"],
"dst": ["tag:database:5432"]
}
],
"groups": {
"group:devs": ["user@example.com"]
},
"tagOwners": {
"tag:aws-prod": ["group:devs"],
"tag:database": ["group:devs"]
}
}
This grants developers SSH and HTTPS access to production instances, while allowing those instances to reach the database server. The database itself is not directly accessible from developer laptops.
Tags get applied when you bring up a device:
tailscale up --advertise-tags=tag:aws-prod
Access control becomes declarative. You define who can reach what in version-controlled JSON. Changes apply immediately across your entire network.
Subnet Routing for Entire Networks
The --advertise-routes flag turns a Tailscale node into a gateway. Approve the routes in the admin console, and suddenly your entire cloud network is accessible.
On AWS, run this on a small instance in each VPC:
echo 'net.ipv4.ip_forward = 1' | sudo tee -a /etc/sysctl.conf
echo 'net.ipv6.conf.all.forwarding = 1' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
tailscale up --advertise-routes=10.0.0.0/16 --accept-routes
The IP forwarding configuration lets Linux route traffic between interfaces. Tailscale handles everything else.
Now any resource in that VPC is reachable from your laptop without giving it a public IP or configuring a bastion host. Your databases, internal APIs, monitoring dashboards, all accessible through the Tailscale network.
Exit Nodes for Internet Traffic
Tailscale nodes can act as exit nodes, routing all internet traffic through them. Useful when working from untrusted networks.
On a trusted server:
tailscale up --advertise-exit-node
Approve it in the admin console, then on your laptop:
tailscale up --exit-node=trusted-server
All your traffic now routes through that server. Your ISP sees encrypted WireGuard traffic to Tailscale. The websites you visit see the IP of your exit node. Works globally, no per-region configuration.
Service Authentication Without Exposing Ports
Services that only need to be reachable by your infrastructure don’t need to listen on public IPs. Bind them to the Tailscale interface instead.
PostgreSQL configuration on a database server:
listen_addresses = '100.64.0.5'
That’s the Tailscale IP of the database server. PostgreSQL is now unreachable from the public internet, only accessible through Tailscale. No security groups to configure, no allowlist of IP ranges to maintain.
Same approach works for Redis, internal APIs, admin panels, monitoring tools. If it doesn’t need public access, bind it to Tailscale.
Container Integration
Running services in Docker? Tailscale provides an official sidecar container.
version: '3'
services:
tailscale:
image: tailscale/tailscale:latest
container_name: tailscale
hostname: api-server
environment:
- TS_AUTHKEY=${TS_AUTHKEY}
- TS_STATE_DIR=/var/lib/tailscale
- TS_EXTRA_ARGS=--advertise-tags=tag:api
volumes:
- ./tailscale:/var/lib/tailscale
- /dev/net/tun:/dev/net/tun
cap_add:
- NET_ADMIN
- SYS_MODULE
restart: unless-stopped
api:
image: your-api:latest
network_mode: "service:tailscale"
depends_on:
- tailscale
The API container shares the Tailscale container’s network namespace. It’s reachable via Tailscale but invisible to the public internet.
Generate an auth key in the Tailscale admin console, store it in .env:
TS_AUTHKEY=tskey-auth-xxxxxxxxx
The container authenticates automatically on startup.
Multi-Cloud Without Complexity
I run services across AWS, Hetzner, and a home server. Before Tailscale, connecting them meant site-to-site VPN configurations that broke whenever a public IP changed. Now it’s a single command on each host.
AWS instance needs to query a database on the home server? It just connects. Home server needs to backup to S3 through a specific AWS instance? Route it through Tailscale. Developer needs to test against the production database clone on the Hetzner instance? SSH tunnel through Tailscale.
The networking layer is invisible. Services connect using Tailscale IPs. Traffic routes peer-to-peer when possible, through relay servers when direct connection isn’t available. It just works.
The Practical Benefits
No firewall rules for inter-service communication. Resources are either on the Tailscale network or they’re not. Access control happens in the ACL, not scattered across security groups and iptables.
No bastion hosts. Developers connect to internal resources through Tailscale. Their devices are authenticated, access is logged, no shared jump boxes.
No VPN server maintenance. Tailscale runs the coordination server. You run the clients. Updates are automatic, reliability is their problem, not yours.
No complex routing. Subnet routes advertise entire networks. Traffic flows directly between nodes. Adding a new cloud region is a single command.
When Not to Use Tailscale
If you’re running everything in a single cloud provider and never need external access, you don’t need Tailscale. Use the cloud provider’s private networking.
If you need guaranteed bandwidth or specific latency SLAs, direct connections or dedicated circuits make more sense. Tailscale routes traffic peer-to-peer when possible, but NAT traversal and relay servers add overhead.
If your compliance requirements prevent using third-party coordination servers, Headscale is a self-hosted alternative. It implements the Tailscale control protocol, giving you the same functionality with infrastructure you control.
Implementation Approach
Start small. Install Tailscale on a single development server and your laptop. Verify you can reach it. Add ACLs restricting access by user and port.
Add a production server, tag it differently, adjust ACLs to enforce separation. Verify developers can reach development but not production.
Enable subnet routing on a gateway instance in your cloud VPC. Verify you can reach internal resources. Gradually migrate services to bind on Tailscale IPs instead of public addresses.
Once the pattern works, expand it. Every new server gets Tailscale installed. Every new service binds to its Tailscale interface. VPN configurations get deleted.
The network layer stops being something you think about. Resources are reachable, access is controlled, traffic is encrypted. Build infrastructure, not network configurations.