> ## Documentation Index
> Fetch the complete documentation index at: https://docs.controlplane.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Tailscale

> Deploy Tailscale on Control Plane using the Template Catalog. Covers configuration, scaling, and mesh VPN gateway setup for routing Tailscale clients to GVC workloads.

## Overview

Tailscale is a mesh VPN built on WireGuard. This template deploys a Tailscale gateway workload on Control Plane that joins your Tailscale network and advertises internal Control Plane routes, allowing any connected Tailscale client to reach your GVC workloads via their `cpln.local` internal endpoints.

The gateway runs in a single configured location. Other locations are suspended so only one Tailscale node is active at a time.

### What Gets Created

* **Standard Workload** — The Tailscale gateway (`RELEASE_NAME-tailscale`), active in the configured location only. Advertises Control Plane's internal network CIDRs and the location's internal DNS server to Tailscale.
* **Secret** — A dictionary secret storing the Tailscale auth key, injected into the container at startup.
* **Identity & Policy** — An identity bound to the workload with `reveal` access to the auth key secret.
* **Serverless Workload** *(optional)* — An httpbin test workload (`RELEASE_NAME-httpbin`) accessible only from the Tailscale workload, useful for verifying connectivity.

<Note>
  This template does not create a GVC. You must deploy it into an existing GVC.
</Note>

## Prerequisites

Complete the following in your Tailscale account before installing:

### 1. Create an Auth Key

In the Tailscale [Admin UI → Settings → Keys](https://login.tailscale.com/admin/settings/keys), create a new auth key with **Reusable** and **Ephemeral** enabled. Save the key value — you will set it as `AuthKey` in your values.

### 2. Update the Tailscale ACL

Add `autoApprovers` to your [Tailscale ACL](https://login.tailscale.com/admin/acls/file) so that advertised routes are approved automatically:

```json theme={null}
{
  "autoApprovers": {
    "routes": {
      "192.168.0.0/16": ["autogroup:member"],
      "240.240.0.0/16": ["autogroup:member"],
      "10.0.0.0/16": ["autogroup:member"],
      "172.20.0.10/32": ["autogroup:member"],
      "10.1.0.10/32": ["autogroup:member"],
      "10.194.112.10/32": ["autogroup:member"]
    }
  }
}
```

If your location uses a DNS IP not listed above, add its `/32` entry here as well.

### 3. Configure Tailscale DNS

In the Tailscale [Admin UI → DNS tab](https://login.tailscale.com/admin/dns), add a custom nameserver scoped to the `cpln.local` domain. Use the DNS IP for your selected location from the `locationDNS` map in values (e.g. `172.20.0.10` for most AWS locations).

If you need to reach per-replica stateful workload endpoints, add an additional custom nameserver scoped to `<GVC_NAME>.svc.cluster.local` using the same DNS IP.

## Installation

To install, follow the instructions for your preferred method:

<CardGroup cols={2}>
  <Card title="UI" href="/template-catalog/install-manage/ui" icon="laptop">
    Browse, install, and manage templates visually
  </Card>

  <Card title="CLI" href="/template-catalog/install-manage/cli" icon="terminal">
    Manage templates from your terminal
  </Card>

  <Card title="Terraform" href="/template-catalog/install-manage/terraform" icon={<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128"><g fill-rule="evenodd"><path d="M77.941 44.5v36.836L46.324 62.918V26.082zm0 0" fill="#5c4ee5"/><path d="M81.41 81.336l31.633-18.418V26.082L81.41 44.5zm0 0" fill="#4040b2"/><path d="M11.242 42.36L42.86 60.776V23.941L11.242 5.523zm0 0M77.941 85.375L46.324 66.957v36.82l31.617 18.418zm0 0" fill="#5c4ee5"/></g></svg>}>
    Declare templates in your Terraform configurations
  </Card>

  <Card
    title="Pulumi"
    href="/template-catalog/install-manage/pulumi"
    icon={<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" id="Pulumi-Icon--Streamline-Svg-Logos" height="24" width="24">
    <desc>
        Pulumi Icon Streamline Icon: https://streamlinehq.com
    </desc>
    <path fill="#f26e7e" d="M4.683025 13.3318c0.869125 -0.5018 0.870575 -2.1264 0.003225 -3.62865s-2.27504 -2.313275 -3.1441725 -1.811475C0.672945 8.3935 0.6715 10.0181 1.53885 11.52035c0.86735 1.502275 2.27505 2.313275 3.144175 1.81145Zm0.0052 3.2167c0.86735 1.502275 0.865925 3.126875 -0.003225 3.628675 -0.86915 0.5018 -2.2768275 -0.309225 -3.144175 -1.81145 -0.8673525 -1.50225 -0.8659075 -3.126875 0.003225 -3.628675 0.8691325 -0.5018 2.276825 0.309225 3.144175 1.81145Zm5.922875 3.4243c0.86735 1.50225 0.8659 3.126775 -0.003225 3.62875 -0.869125 0.501775 -2.27685 -0.309325 -3.1442 -1.81155 -0.867325 -1.50225 -0.865875 -3.12685 0.00325 -3.628675 0.869125 -0.5018 2.276825 0.309225 3.144175 1.811475Zm-0.001925 -6.845275c0.86735 1.50225 0.8659 3.12685 -0.003225 3.628675 -0.869125 0.5018 -2.276825 -0.309225 -3.144175 -1.811475 -0.86735 -1.50225 -0.8659 -3.12685 0.003225 -3.62865 0.869125 -0.501825 2.276825 0.3092 3.144175 1.81145Z" stroke-width="0.25"></path>
    <path fill="#8a3391" d="M22.45775 11.524125c0.86725 -1.502225 0.865925 -3.12685 -0.003225 -3.62865 -0.869125 -0.501825 -2.276825 0.3092 -3.144175 1.811475 -0.86735 1.50225 -0.8659 3.126825 0.003225 3.62865 0.869125 0.501825 2.276825 -0.3092 3.144175 -1.811475Zm0.000175 3.2151c0.869075 0.5018 0.870625 2.1264 0.003225 3.62865 -0.86735 1.50225 -2.27505 2.313275 -3.144175 1.81145 -0.869125 -0.5018 -0.870575 -2.126425 -0.003225 -3.62865 0.86735 -1.50225 2.27505 -2.313275 3.144175 -1.81145ZM16.536225 18.157875c0.86915 0.501825 0.8706 2.126425 0.00325 3.628675 -0.86735 1.502125 -2.275075 2.313225 -3.1442 1.81145 -0.869125 -0.50175 -0.870575 -2.126425 -0.003225 -3.62865 0.867375 -1.502275 2.27505 -2.3133 3.144175 -1.811475Zm-0.003325 -6.843775c0.869125 0.5018 0.870575 2.126425 0.003225 3.628675s-2.27505 2.313275 -3.1442 1.811475c-0.869125 -0.501825 -0.870575 -2.126425 -0.003225 -3.628675 0.86735 -1.502275 2.27505 -2.313275 3.1442 -1.811475Z" stroke-width="0.25"></path>
    <path fill="#f7bf2a" d="M15.138225 2.06721c0 1.003615 -1.40625 1.817215 -3.14095 1.817215 -1.7347 0 -3.14095 -0.8136 -3.14095 -1.817215C8.856325 1.06359 10.262575 0.25 11.997275 0.25c1.7347 0 3.14095 0.81359 3.14095 1.81721ZM9.2166 5.482375c0 1.003625 -1.40625 1.8172 -3.14095 1.8172 -1.7347 0 -3.14095 -0.813575 -3.14095 -1.8172s1.40625 -1.817225 3.14095 -1.817225c1.7347 0 3.14095 0.8136 3.14095 1.817225Zm8.71005 1.8172c1.7347 0 3.14095 -0.813575 3.14095 -1.8172s-1.40625 -1.817225 -3.14095 -1.817225c-1.7347 0 -3.14095 0.8136 -3.14095 1.817225s1.40625 1.8172 3.14095 1.8172Zm-2.788425 1.605625c0 1.003625 -1.40625 1.8172 -3.14095 1.8172 -1.7347 0 -3.14095 -0.813575 -3.14095 -1.8172 0 -1.0036 1.40625 -1.8172 3.14095 -1.8172 1.7347 0 3.14095 0.8136 3.14095 1.8172Z" stroke-width="0.25"></path>
    </svg>}
  >
    Declare templates in your Pulumi programs
  </Card>
</CardGroup>

## Configuration

The default `values.yaml` for this template:

```yaml theme={null}
# The single location where the Tailscale gateway will be active
location: aws-us-east-1

image:
  repository: tailscale/tailscale
  tag: stable

resources:
  cpu: 500m
  memory: 128Mi

extraEnv:
  - name: TS_HOSTNAME
    value: cpln-test-new
  # - name: TS_EXTRA_ARGS
  #   value: --advertise-exit-node

# Internal DNS server IPs per location — used to advertise a DNS route to Tailscale clients
locationDNS:
  aws-us-west-2: 172.20.0.10
  aws-us-east-1: 172.20.0.10
  aws-us-east-2: 172.20.0.10
  aws-sa-east-1: 172.20.0.10
  aws-eu-west-2: 172.20.0.10
  aws-eu-central-1: 172.20.0.10
  aws-il-central-1: 172.20.0.10
  gcp-us-west1: 10.67.224.10
  gcp-us-east1: 10.194.112.10
  gcp-us-central1: 10.228.48.10
  gcp-me-west1: 10.110.48.10
  azure-centralus: 10.1.0.10
  azure-eastus2: 10.1.0.10

deployHttpbinExample: true

AuthKey: replaceWithYourTailscaleAuthKey
```

### Auth Key

* `AuthKey` — Your Tailscale auth key. **Replace this before deploying.** The key must be created with the **Reusable** and **Ephemeral** options enabled.

### Location

* `location` — The single Control Plane location where the Tailscale gateway will run. All other locations in the GVC are suspended. Must match one of the locations configured in your GVC.

The Tailscale workload will appear as `Partially Suspended` in the console — this is expected behavior.

### Advertised Routes

The gateway automatically advertises the following routes to Tailscale:

| Route                        | Purpose                                       |
| ---------------------------- | --------------------------------------------- |
| `192.168.0.0/16`             | Control Plane internal network                |
| `240.240.0.0/16`             | Control Plane internal network                |
| `<locationDNS[location]>/32` | Internal DNS server for the selected location |

The `/32` DNS host route allows Tailscale clients to resolve `cpln.local` endpoints after configuring a custom nameserver in Tailscale DNS.

### Location DNS

* `locationDNS` — A map of Control Plane location names to their internal DNS server IPs. The IP for the selected `location` is advertised as a host route (`/32`) to enable `cpln.local` name resolution on Tailscale clients.

If your location is not listed, add it to the map with the correct DNS IP for that location.

### Resources and Image

* `resources.cpu` / `resources.memory` — CPU and memory for the Tailscale gateway container.
* `image.repository` / `image.tag` — Tailscale container image. Defaults to `tailscale/tailscale:stable`.

### Extra Environment Variables

* `extraEnv` — Additional environment variables passed to the Tailscale container. Common options:
  * `TS_HOSTNAME` — The hostname the gateway registers under in your Tailscale network.
  * `TS_EXTRA_ARGS` — Additional Tailscale daemon flags, e.g. `--advertise-exit-node` to use the gateway as an exit node.

### Example Workload

* `deployHttpbinExample` — When `true`, deploys an httpbin test workload that only accepts internal connections from the Tailscale gateway. Use it to verify connectivity after setup.

## Accessing GVC Workloads

Once the gateway is running and connected to Tailscale:

1. Ensure your local machine is connected to the same Tailscale network.
2. Any GVC workload that grants internal access to the Tailscale workload can be reached via its `cpln.local` address:

```text theme={null}
WORKLOAD_NAME.GVC_NAME.cpln.local:PORT
```

To grant access, add the Tailscale workload to a target workload's internal firewall:

```yaml theme={null}
firewallConfig:
  internal:
    inboundAllowType: workload-list
    inboundAllowWorkload:
      - //gvc/GVC_NAME/workload/RELEASE_NAME-tailscale
```

## External References

<CardGroup cols={2}>
  <Card title="Tailscale Documentation" icon="book" href="https://tailscale.com/kb/">
    Official Tailscale documentation
  </Card>

  <Card title="Tailscale Admin UI" icon="globe" href="https://login.tailscale.com/admin/">
    Manage your Tailscale network, keys, ACLs, and DNS
  </Card>

  <Card title="Tailscale Template" icon="github" href="https://github.com/controlplane-com/templates/tree/main/tailscale">
    View the source files, default values, and chart definition
  </Card>
</CardGroup>
