> ## Documentation Index
> Fetch the complete documentation index at: https://controlplanecorporation-majid-docs-content-expansion.mintlify.site/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.

The auth key is **not** a template value. Tailscale reads it from an opaque secret you create before installing, so the key never passes through Helm or lands in the release.

<Warning>
  **Template version 1.3.0 is a breaking change.** `AuthKey` was removed, and an install or upgrade that still sets it now fails at render. Two defaults also changed: the image tag is pinned, and `TS_HOSTNAME` no longer defaults to a leftover test name. If you are running 1.2.x, read [Upgrading From 1.2.x](#upgrading-from-1-2-x) before you touch the release.
</Warning>

### 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, then store it in an opaque secret — it is not a template value:

```bash theme={null}
printf '%s' 'tskey-auth-YOUR-KEY-HERE' | cpln secret create-opaque --name my-tailscale-authkey --encoding plain -f -
```

Set `authKeySecretName` to the name you used. Secret names are org-wide, so give each release its own.

If the secret does not exist at install time the deployment wedges silently — `cpln logs` returns **zero lines**. Read `status.versions[].message` via `cpln workload get-deployments RELEASE_NAME-tailscale --gvc GVC_NAME -o yaml`; plain `cpln workload get` has no `versions` key.

### 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>

## Upgrading From 1.2.x

Version 1.3.0 removes `AuthKey` and changes two defaults.

|               | 1.2.x                                              | 1.3.0                                             |
| ------------- | -------------------------------------------------- | ------------------------------------------------- |
| Auth key      | `AuthKey` value, written into a chart-owned secret | `authKeySecretName` → an opaque secret you create |
| `image.tag`   | `stable` — floating                                | `v1.102.3` — pinned                               |
| `TS_HOSTNAME` | `cpln-test-new`                                    | `cpln-tailscale`                                  |

<Warning>
  **Carrying `AuthKey` forward stops the upgrade.** It is rejected at render, so `cpln helm upgrade` fails and your existing gateway is left untouched and running:

  ```text theme={null}
  Error: execution error at (tailscale/templates/identity.yaml:1:4): tailscale: AuthKey was REMOVED
  — it is now an `opaque` secret you create, named by authKeySecretName, whose entire value is the
  auth key. Delete AuthKey from your values. See Prerequisites in the README.
  ```
</Warning>

Create the secret ([Prerequisites](#prerequisites)), delete `AuthKey`, and set `authKeySecretName`. You can reuse the same key or generate a new one — unlike a database password, a Tailscale auth key only authorizes the device at join time, so replacing it is safe for a node that has already joined.

<Note>
  **`TS_HOSTNAME` previously defaulted to `cpln-test-new`,** a leftover from testing that became the advertised tailnet name of every install that did not override it. If you see `cpln-test-new` in your Tailscale admin console, that is a pre-1.3.0 deployment. Changing it renames the device on your tailnet.
</Note>

## 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: v1.102.3 # pinned: `stable` floats, so installs are not reproducible

resources:
  cpu: 500m
  memory: 128Mi

extraEnv:
  - name: TS_HOSTNAME
    value: cpln-tailscale # the name this device advertises on your tailnet
  # - 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

authKeySecretName: my-tailscale-authkey # see Prerequisites — must exist before install
```

### Auth Key

* `authKeySecretName` — Name of the opaque secret holding your Tailscale auth key. The key must be created with the **Reusable** and **Ephemeral** options enabled. See [Prerequisites](#prerequisites).

### 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>
