Overview
Tailscale is a mesh VPN built on WireGuard. This template runs a Tailscale subnet router inside your GVC: it joins your tailnet, advertises Control Plane’s internal network routes plus the internal DNS server of one location, and lets any device on your tailnet reach GVC workloads by theircpln.local addresses without giving those workloads a public endpoint.
The gateway runs in exactly one location, set by location. The auth key is not a template value; the gateway reads it from a secret you create before installing, so the key never passes through Helm or lands in the release.
location must already be one of that GVC’s locations. Every other location on the GVC runs nothing for this workload.What Gets Created
Prerequisites
You need a Tailscale account with admin access to its tailnet, plus one secret in your Control Plane org. Secrets are org-level, so no GVC flag is involved.Generate a Tailscale auth key
Store the auth key in an opaque secret
authKeySecretName to this name. Secret names are org-wide, so give each release its own.Let Tailscale approve the advertised routes
192.168.0.0/16, 240.240.0.0/16, and a /32 host route to the internal DNS server of the selected location (looked up in locationDNS). Add an autoApprovers block to your tailnet policy file so they are approved automatically. This example covers the default aws-us-east-1 location, whose DNS server is 172.20.0.10:172.20.0.10/32 with that location’s entry from locationDNS. Without autoApprovers you can still approve the routes by hand after install (see Connecting).Add split DNS for cpln.local
cpln.local, and set its address to the locationDNS IP of your selected location (172.20.0.10 for the default aws-us-east-1).Installation
Install with the secret name from Prerequisites. Add--set location=... if the gateway should run somewhere other than aws-us-east-1:
UI
CLI
Terraform
Pulumi
Configuration
Auth Key
Location
Partially Suspended. The location must already be on your GVC and must have an entry in locationDNS.
Location DNS
location becomes the advertised /32 route and is the address you give Tailscale split DNS. Leave the map as shipped unless your location is missing from it.
Image and Resources
Extra Environment Variables
TS_HOSTNAME so gateways are easy to tell apart in the Tailscale admin console. The commented exit-node example is not part of the default install and has not been verified with this template.
Example Workload
RELEASE_NAME-httpbin, a small HTTP service that only the gateway may reach. Use it to prove the tailnet path works, then set it to false.
Connecting
autoApprovers, open the gateway on the Machines page, choose Edit route settings, and approve all three advertised routes. Until they are approved, the gateway shows as connected but carries no traffic to the GVC.
Allow the gateway on each target workload. Traffic from tailnet devices reaches a workload from the gateway, so the target’s internal firewall must admit RELEASE_NAME-tailscale. For example:
Operations
Upgrading from 1.2.x
Version 1.3.0 removes theAuthKey value and changes two defaults.
Create the auth key secret
RELEASE_NAME-tailscale, because the upgrade removes that chart-owned secret. You can reuse your current key or generate a new one.Update your values
AuthKey and set authKeySecretName. If you relied on the old cpln-test-new device name, set TS_HOSTNAME in extraEnv explicitly; otherwise the device appears on your tailnet as cpln-tailscale.Upgrade
Rotating the Auth Key
An auth key only authorizes the device when it joins, but the gateway rejoins with the key on every container start, so keep a valid key in the secret. To replace it, apply the whole secret with the new value:Scaling and Availability
The gateway is a single replica in a single location. Do not run it in several locations: a subnet router advertising the same routes from several places gives Tailscale competing paths. If that location is unavailable, tailnet access to the GVC stops until it returns. The workloads themselves are unaffected.Troubleshooting
The gateway never starts and cpln logs returns nothing
The gateway never starts and cpln logs returns nothing
authKeySecretName does not exist, so the deployment is paused before the container starts.Fix: read status.versions[].message with cpln workload get-deployments RELEASE_NAME-tailscale --gvc GVC_NAME -o yaml. It names the missing secret, for example The secret SECRET_NAME no longer exists. Workload updates are paused until the secret is added or the reference to the secret removed. Create the secret as in Prerequisites.The gateway is online in Tailscale but workloads are unreachable
The gateway is online in Tailscale but workloads are unreachable
autoApprovers as in Prerequisites. Then allow //gvc/GVC_NAME/workload/RELEASE_NAME-tailscale in the target’s firewallConfig.internal, as shown in Connecting. Test against RELEASE_NAME-httpbin first, since it already allows the gateway.cpln.local names do not resolve on a tailnet device
cpln.local names do not resolve on a tailnet device
cpln.local is missing, points at the wrong address, or the /32 DNS route is not approved.Fix: set the custom nameserver for cpln.local to the locationDNS entry for your location, and confirm that same address appears as an approved /32 route on the gateway.The advertised routes end in a bare /32 with no address
The advertised routes end in a bare /32 with no address
location has no entry in locationDNS, so TS_ROUTES renders as 192.168.0.0/16,240.240.0.0/16,/32.Fix: add your location and its internal DNS server address to locationDNS, then upgrade the release.No replica runs in any location
No replica runs in any location
location names a location that is not on your GVC. The workload is suspended everywhere else, so nothing runs.Fix: compare location with spec.staticPlacement.locationLinks from cpln gvc get GVC_NAME -o yaml, set it to one of those locations, and upgrade.The gateway dropped off the tailnet after running fine for weeks
The gateway dropped off the tailnet after running fine for weeks
Important Notes
- Create the auth key secret before installing; a missing secret wedges the deployment with no logs.
- Generate the key as Reusable and Ephemeral, and replace it before it expires.
- Approve the three advertised routes and add
cpln.localsplit DNS, or tailnet devices cannot reach anything. - Every workload you want to reach must allow
RELEASE_NAME-tailscalein its internal firewall. - After rotating the key in the secret, force a redeployment of
RELEASE_NAME-tailscale. - Never upgrade from 1.2.x with
AuthKeystill in your values; follow Upgrading from 1.2.x.