# Variable groups

A variable group is a set of secrets your team shares between apps: a Sentry address, a mail server, an API key several apps call. Change it once in the group, and every app that uses the group restarts with the new value.

## Create a group and use it

```sh
$ deplane groups create shared-config
Created the variable group shared-config.

$ deplane groups set shared-config SENTRY_DSN=https://key@sentry.example.com/1 MAIL_HOST=smtp.example.com
Set runtime variable(s) MAIL_HOST, SENTRY_DSN in shared-config.

$ deplane groups attach shared-config --app shop
shop now uses the variable group shared-config.
Created release v6.
```

In the dashboard: **Variable groups** in the menu creates groups and sets their variables; an app's **Variables** tab attaches and detaches them.

## How an app gets a group's variables

- An app uses only the groups attached to it.
- A group's variables are secrets like an app's own: encrypted, and never shown back.
- **The app's own variable wins.** If `shop` sets `MAIL_HOST` itself, it keeps its own value; the group's is a default. `deplane secrets list --app shop` shows each name with its source and marks a group's value the app overrides.
- Runtime and build variables stay apart, as for an app's own: `deplane groups set shared-config --build NPM_TOKEN=...` reaches builds only, never the running app.
- Two groups attached to one app cannot set the same name in the same scope. The attach, or the `groups set` that would do it, is refused and names the variable.

## When values change

- Setting or removing a **runtime** variable in a group rolls out a new release of every app that uses the group and already runs, with no downtime.
- Attaching or detaching a group rolls out a new release of the app when it changes a runtime value the app gets.
- **Build** variables are used by each app's next build: run `deplane deploy`.
- Pull request previews copy their app's variables, its groups' included, at each push, without production database addresses or passwords. A group change reaches a preview at its next push.

## Commands

| Command | What it does |
|---|---|
| `deplane groups list` | The team's groups, how many variables each has, and the apps that use it. |
| `deplane groups create NAME` | Create an empty group. |
| `deplane groups show NAME` | A group's variable names (never values) and apps. |
| `deplane groups set NAME KEY=VALUE... [--build]` | Set variables in a group. |
| `deplane groups unset NAME KEY... [--build]` | Remove variables from a group. |
| `deplane groups attach NAME --app APP` | Make an app use a group. |
| `deplane groups detach NAME --app APP` | Make an app stop using a group. |
| `deplane groups delete NAME` | Delete a group, after a confirmation with your passkey. Refused while an app uses it: detach it first. |

Each takes `--json`.

## Who can change groups

Any member of the team, from the dashboard or a CLI login (`deplane login`). CI tokens, agent tokens and AI tools connected to Deplane cannot read or change groups; a CI token still lists an app's variable names, groups included, with `deplane secrets list`. In an app's release history, an AI tool sees "Variable group change" instead of the group's name and variables.

## Limits

- 50 groups per team, and 10 groups per app.
- Names: 3 to 40 characters: lowercase letters, digits, and single hyphens, starting with a letter and not ending with a hyphen, such as `shared-config`.
- Variable names and values follow the [secret rules](secrets.md#names).
- `DATABASE_URL`, `REDIS_URL`, `MYSQL_URL` and `CLICKHOUSE_URL` cannot be in a group: they are set on each app, by attaching a database. The cPanel import's `SITE_IMPORT_*` variables belong to one app and cannot be either.
- A group can hold 200 runtime variables and 200 build variables, up to 256 KB of each, names included.
- An app gets at most 500 variables per kind and 512 KB per kind, its own and its groups' together.
