Site-to-Site Networking with Tailscale: Part 3 — Two Regions, One Tailnet
- Shannon
- 4 minutes ago
- 3 min read
All code for this blog post can be found here.
By now you’ve probably figured out I like to make things harder on myself before I make them easier. The first blog post was about beating the UDM Pro into submission so it would finally run Tailscale as a subnet router. The second post was teaching Azure East US how to speak Tailscale and act as a router for that VNet. This third post is where the whole picture comes together: adding West US and proving that Tailscale can replace my old Azure site-to-site VPNs.
Step 1: Build the Router VM in West US
This looks a lot like East US instructions, except I no longer bothered with a public IP. My site-to-site VPN was still in place during build, so I could SSH via private IP. When I flipped it off later, I kept Tailscale as the only way in (notice I'm using AzCLI):
# Variables
RG=sbkWusHub
VNET=sbkWusHubVnet
SUBNET=sbkWusHubSub1
NIC=sbk-wus-ts-router01-nic
VM=sbk-wus-ts-router01
LOCATION=westus
# NIC
az network nic create \
--resource-group $RG \
--name $NIC \
--vnet-name $VNET \
--subnet $SUBNET
# VM
az vm create \
--resource-group $RG \
--name $VM \
--location $LOCATION \
--size Standard_B1ms \
--nics $NIC \
--image Ubuntu2204 \
--admin-username azureuser \
--generate-ssh-keys
I made the NIC static to avoid future headaches and stripped out the public IP since I didn’t want open exposure.
Step 2: Install Tailscale
SSH in over the old VPN, then install Tailscale:
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up \
--authkey tskey-auth-YOUR-KEY-HERE \
--advertise-routes=10.10.0.0/16 \
--accept-routes \
--hostname sbk-wus-router01
Keep in mind, the /16 was my end state. I started with /32 training wheels, then /24, and once everything looked stable, I widened it out. I'm a big believer of inching forward vs. blowing things up and spending more time troubleshooting.
Step 3: Approve the Routes
Head into the Tailscale admin console and approve the 10.10.0.0/16 route on sbk-wus-router01. At this point my East US router was already advertising 10.5.0.0/16 and my UDM Pro was covering 192.168.1.0/24. Now West US joined the party.
Step 4: Create a Route Table in Azure
Just like East US, workloads in West US needed to know how to get back to on-premises and to the other region. I built a UDR:
az network route-table create \
--resource-group sbkWusHub \
--name rt-wus-to-onprem
az network route-table route create \
--resource-group sbkWusHub \
--route-table-name rt-wus-to-onprem \
--name to-onprem \
--address-prefix 192.168.1.0/24 \
--next-hop-type VirtualAppliance \
--next-hop-ip-address 10.10.1.5
az network vnet subnet update \
--resource-group sbkWusHub \
--vnet-name $VNET \
--name $SUBNET \
--route-table rt-wus-to-onprem
That router IP is the private address of the VM. With that in place, packets could flow out of the VNet and find their way back to my on-premises domain controllers.
Step 5: Validate End to End
The final checklist looked like this:
From my laptop, I could ping and SSH into VMs in East US (10.5.0.0/16) and West US (10.10.0.0/16) using only Tailscale.
From an Azure VM, I could resolve and reach my on-premises DNS servers (192.168.1.194 and .196).
Tailscale status showed all three routers (UDM, East US, West US) as active with the right routes advertised and approved.
The old site-to-site VPN was shut down without loss of connectivity.
Lessons Learned
Training wheels are fine. Advertising /32 at first is like wobbling around on a tricycle until you’re ready for a full-sized bike. Once you prove traffic flows correctly, widen the scope.
Route approval matters. Forgetting to approve routes in the Tailscale console is the fastest way to think nothing works.
Azure SKUs are different. East US had the old Basic VPN Gateway, West US used Standard. The Standard SKU forced me to be more deliberate with UDRs and security, which turned out to be a good thing.
Relays aren’t evil. Sometimes you’ll see “relay sfo” in tailscale status. That just means you’re hair-pinning through Tailscale’s relay. Performance drops, but it still works.
Wrap Up
Two regions, one tailnet, no pricey Azure VPN Gateway. The routers in East and West US are humming, and my UDM Pro handles the home side. It was messy at times, but the end result is clean: a mesh VPN spanning on-premises and Azure without having to install Tailscale on every VM.
Next up: layering in some automation to make the router deployment completely hands-off. For now, I’ll just enjoy the ride (especially because I have other things to tend to in the immediate).
Comments