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

# NATS

> Deploy NATS on Control Plane using the Template Catalog. Covers configuration, multi-region super cluster, WebSocket support, gateway routing, and optional JetStream persistent storage.

## Overview

NATS is an open-source, high-performance, lightweight messaging system optimized for cloud-native architectures. It supports pub/sub, queueing, and request/reply patterns. This template deploys a NATS super cluster using the official NATS image across multiple regions, with each location running independent replicas. JetStream can be enabled for persistent streams, durable consumers, K-V store, and object store — each replica gets its own dedicated volume. By default it exposes a WebSocket interface on port 443 via Control Plane's TLS termination.

### What Gets Created

* **GVC** — A dedicated GVC spanning the configured locations.
* **Stateful NATS Workload** — A NATS super cluster using the official `nats` image, with per-location replica counts, exposing the client port (4222), cluster port (6222), gateway port (7222), and optionally the WebSocket port (8080).
* **Volume Set** *(optional, when JetStream is enabled)* — Persistent storage for JetStream data. Each replica gets its own volume, with optional autoscaling.
* **Secrets** — An opaque configuration secret containing the full NATS server config, and an opaque extra data secret used for the `nats_extra_config` block.
* **Identity & Policy** — An identity bound to the workload with `reveal` access to both secrets.

<Note>
  This template creates a GVC. If you plan to deploy multiple instances, you must assign a unique GVC name for each deployment.
</Note>

## Installation

This template has no external prerequisites. 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}
gvc:
  name: nats-gvc
  locations:
    - name: aws-us-east-1
      replicas: 2
    - name: aws-us-west-2
      replicas: 2
    - name: aws-eu-central-1
      replicas: 2

resources:
  cpu: 100m
  memory: 256Mi

image: nats:2.11.6-alpine # official NATS image tag — bump to upgrade NATS version

nats_defaults:
  port: 4222
  cluster:
    listen: "0.0.0.0:6222"
    port: 6222
    noAdvertise: false
  gateway:
    listen: "0.0.0.0:7222"
    port: 7222

  websocket:
    enabled: true
    port: 8080
    compression: false
    noTls: true # Control Plane handles TLS termination
    # allowedOrigins: []  # Uncomment and add origins if needed
    # advertise: "ws://example.com:8080"  # Uncomment if different from default

allowCIDR:
  - 0.0.0.0/0 # Allow all traffic. Change to specific CIDRs to limit exposure.
              # Only applicable to the WebSocket port. Control Plane exposes it on port 443.

jetstream:
  enabled: false # set to true to enable persistent JetStream streaming and storage

volumeset:
  capacity: 10 # initial capacity in GiB per replica (minimum is 10)
  autoscaling:
    enabled: false
    maxCapacity: 100
    minFreePercentage: 10
    scalingFactor: 1.2

# Add any additional valid NATS configuration here — appended to the server config at startup
nats_extra_config: ""

internalAccess: # Sets the internal firewall scope
  type: same-gvc # options: none, same-gvc, same-org, workload-list
  workloads: # Note: can only be used if type is same-gvc or workload-list
    #- //gvc/GVC_NAME/workload/WORKLOAD_NAME
```

### Image

* `image` — The NATS container image to use. Defaults to the official `nats:2.11.6-alpine` image. Bump the tag to upgrade the NATS version.

### GVC and Locations

* `gvc.name` — Name of the GVC to create. Must be unique per deployment if running multiple instances.
* `gvc.locations` — List of locations where NATS replicas will run. Each entry requires:
  * `name` — The location identifier (e.g. `aws-us-east-1`).
  * `replicas` — Number of NATS replicas in that location. Set to `0` to suspend a location without removing it.

### Resources

* `resources.cpu` / `resources.memory` — CPU and memory allocated to each NATS replica.

### JetStream

* `jetstream.enabled` — When `true`, enables NATS's built-in persistence layer, adding durable streams, consumers, K-V store, and object store on top of the core pub/sub model. Without it, NATS is purely in-memory.

When JetStream is enabled, each replica gets its own dedicated persistent volume (configured via `volumeset`).

<Note>
  Streams default to `num_replicas: 1`, meaning stream data lives on a single server. For streams that must survive a location outage, set `num_replicas` to 2 or higher in your application — this is configured per-stream, not in this template.
</Note>

### Volume Set

The `volumeset` block applies only when `jetstream.enabled: true`.

* `volumeset.capacity` — Initial volume size in GiB per replica (minimum 10).
* `volumeset.autoscaling.enabled` — Automatically expand the volume as it fills. When enabled:
  * `maxCapacity` — Maximum volume size in GiB.
  * `minFreePercentage` — Trigger a scale-up when free space drops below this percentage.
  * `scalingFactor` — Multiply the current capacity by this factor when scaling up.

### WebSocket

* `nats_defaults.websocket.enabled` — When `true`, exposes a WebSocket endpoint on the configured port. Control Plane handles TLS termination and serves it externally on port 443.
* `nats_defaults.websocket.port` — Internal WebSocket port (default: `8080`).

### External Access

* `allowCIDR` — CIDR ranges allowed to reach the WebSocket port from the internet. Defaults to `0.0.0.0/0` (open to all). Restrict this to limit exposure.

<Note>
  `allowCIDR` only applies to the WebSocket port. The NATS client port (4222), cluster port (6222), and gateway port (7222) are only accessible internally.
</Note>

### Internal Access

* `internalAccess.type` — Controls which workloads can reach NATS on the client (4222), cluster (6222), and gateway (7222) ports:

| Type            | Description                                                     |
| --------------- | --------------------------------------------------------------- |
| `none`          | No internal access allowed                                      |
| `same-gvc`      | Allow access from all workloads in the same GVC                 |
| `same-org`      | Allow access from all workloads in the same organization        |
| `workload-list` | Allow access only from specific workloads listed in `workloads` |

<Note>
  Do not set `internalAccess.type` to `none`. NATS replicas must be able to communicate with each other across the cluster and gateway ports for the super cluster to function.
</Note>

### Extra NATS Configuration

* `nats_extra_config` — Any additional valid NATS server configuration appended to the server config at startup. Use this to set `max_payload`, configure accounts, or add other NATS server options:

```yaml theme={null}
nats_extra_config: |
  max_payload: 8MB
```

### Connecting to NATS

**Internally** (from workloads in the same GVC), connect on the standard NATS client port:

```text theme={null}
nats://RELEASE_NAME-nats.GVC_NAME.cpln.local:4222
```

**Externally** via WebSocket, connect through the Control Plane endpoint on port 443:

```text theme={null}
wss://RELEASE_NAME-nats.GVC_NAME.cpln.app
```

## External References

<CardGroup cols={2}>
  <Card title="NATS Documentation" icon="book" href="https://docs.nats.io/">
    Official NATS documentation
  </Card>

  <Card title="JetStream" icon="database" href="https://docs.nats.io/nats-concepts/jetstream">
    NATS JetStream persistence and streaming
  </Card>

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