Skip to main content

Overview

The Secret Env Var Syncer (SEVS) is a cron workload that keeps environment variables in step with Control Plane dictionary secrets. On every run it reads each configured entry, lists the keys of the named dictionary secret, and makes sure the target GVC or workload container has one environment variable per key whose value is the reference cpln://secret/SECRET_NAME.KEY_NAME. It then exits until the next scheduled run. SEVS writes references, not values. Adding a key to a secret gives every target a matching env var on the next run, but changing the value of an existing key changes nothing SEVS manages, so it does not redeploy anything when you rotate a secret (see Rotating a Synced Secret).
This template deploys into an existing GVC that you already have. It does not create a GVC. Its targets can be in that GVC or any other GVC in the same org.

What Gets Created

The three policies are org-wide, regardless of which entries you configure. Each one targets every resource of its kind in the org, not just the secrets and targets named in sevsConfig. Anything that can run as RELEASE_NAME-sevs-identity can read every secret and rewrite every GVC and workload in the org. Install it only where that blast radius is acceptable, and restrict who can edit the release, its configuration secret, and the workload.

Prerequisites

Three things must exist before a sync can succeed. SEVS creates none of them; it resolves them on every run.
1

Create the dictionary secret to sync

Only dictionary secrets are accepted as sources, and each one must have at least one key. Every key becomes an env var name on the target, so use names that are valid environment variables:
Set sevsConfig.entries[].secret to this name.
2

Make sure the target exists

A gvc target names an existing GVC. A workload target names an existing workload, the GVC it lives in, and the exact name of one of its containers. Set sevsConfig.entries[].target accordingly.
3

Let the target read the secret

SEVS writes cpln://secret/... references, and a reference is resolved by the target workload, not by SEVS. Each workload that receives one needs an identity with reveal on that secret. A policy shaped like the one this template creates, scoped to a single secret:
Save it to a file and apply it with cpln apply -f. IDENTITY_NAME is the identity already linked to the target workload.
A target that cannot reveal the secret stops rolling out, almost silently. Once SEVS adds the reference, a target workload without an identity, or whose identity lacks reveal on the secret, pauses its updates. The reason appears only in status.versions[].message:
Plain cpln workload get has no versions key. Grant the permission, then force a redeployment of the target to clear it:

Installation

The default sevsConfig points at placeholder names (my-gvc, my-dictionary-secret), so every run fails until you replace it. Install with your first entry set. Setting any field of sevsConfig.entries[0] replaces the whole default list, so set every field of the entry, including type:
For more than one entry, supply the full sevsConfig.entries list in your values instead of individual --set flags. To install, follow the instructions for your preferred method:

UI

Browse, install, and manage templates visually

CLI

Manage templates from your terminal

Terraform

Declare templates in your Terraform configurations

Pulumi

Declare templates in your Pulumi programs

Configuration

Image and Resources

resources.cpu and resources.memory are the limits for the syncer container. Leave image alone unless you are deliberately moving to another syncer release.

Schedule and Timeout

Runs never overlap: if the previous run is still active when the next tick fires, the new run is skipped.

Sync Entries

Each entry syncs every key of one dictionary secret into one target. The same secret can appear in several entries. A gvc target gets the env vars in the GVC’s own environment list. A workload target gets them in the named container’s env list only; other containers are left alone. For every key, SEVS sets an env var with that name and the value cpln://secret/SECRET_NAME.KEY_NAME. An existing env var with the same name is overwritten. Env vars with other names are kept, and the list is stored sorted by name. When the target already matches, SEVS does not write to it.

Connecting

There is no endpoint. SEVS is a scheduled job with no inbound access. You confirm it works from its logs and from the target. Check that runs complete, using a server-side filter:
An entry.success line carries updated: true when SEVS changed the target and updated: false when it was already in sync. Then confirm the env vars landed on a workload target:
For a gvc target, read the GVC’s environment list instead:

Operations

Changing the Entries

Changing schedule, timeoutSeconds or sevsConfig is a normal upgrade with the full values you want to keep:
The new configuration is used from the next run. Removing an entry does not remove the env vars it already wrote; delete those from the target yourself if you no longer want them.

Running a Sync Now

To run once without waiting for the schedule, start the cron job by hand:
List recent executions with cpln workload cron get RELEASE_NAME-sevs --gvc GVC_NAME.

Rotating a Synced Secret

Changing the value of an existing key does not change the reference SEVS wrote, so SEVS sees nothing to update and the targets keep running with the old value. Rotate the secret, then force a redeployment of every workload that uses it:
Adding a key is different: the next run adds a new env var, which changes the target’s spec and restarts it.

Removing a Key from a Secret

SEVS only adds and overwrites; it never deletes env vars. After you remove a key from a dictionary secret, the target still references cpln://secret/SECRET_NAME.KEY_NAME. Remove that env var from the target (or from the GVC for a gvc target) yourself.

Uninstalling

This removes the workload, its configuration secret, identity and policies. The env vars SEVS wrote stay on the targets.

Troubleshooting

Symptom: the logs show an entry.error line and no job.completed for that run.Cause: a run stops at the first entry that fails, so every entry after it is skipped too. The error field names the problem, for example Secret "SECRET_NAME" is not a dictionary secret, Secret "SECRET_NAME" did not expose any dictionary keys to sync, or Workload "WORKLOAD_NAME" does not contain a container named "CONTAINER_NAME".Fix: correct the entry (or create the missing secret or target) and upgrade the release. Find the error with a server-side filter:
Symptom: entry.error on every run against my-gvc or my-dictionary-secret.Cause: the release is still using the placeholder entry from the default values.Fix: upgrade with your real entries as shown in Changing the Entries.
Symptom: the run exits with entries[0].target.gvc must be provided for workload targets (or the same message for target.container).Cause: a workload target needs both gvc and container, even when the workload is in the same GVC as SEVS.Fix: add both fields to the entry and upgrade.
Symptom: the target workload keeps running an older version and status.versions[].message says it is not allowed to reveal the secret, or that the secret no longer exists.Cause: the target cannot resolve a reference SEVS wrote, either because its identity lacks reveal on the secret or because the key or secret was removed.Fix: grant reveal as in Prerequisites, or remove the stale env var from the target, then run cpln workload force-redeployment WORKLOAD_NAME --gvc GVC_NAME.
Symptom: the target still uses the old value after a rotation, and SEVS logs updated: false.Cause: expected. The reference did not change, so SEVS has nothing to write, and the platform does not restart running workloads on rotation.Fix: force a redeployment of the target, as in Rotating a Synced Secret.

Important Notes

  • The identity can reveal every secret and edit every GVC and workload in the org; treat the release as privileged.
  • Source secrets must be dictionary secrets with at least one key.
  • Every workload target needs both target.gvc and target.container.
  • Each target workload needs reveal on the synced secret, or it stops rolling out once the reference is added.
  • Rotating a value requires a forced redeployment of the targets; SEVS does not trigger one.
  • Env vars SEVS wrote are never removed by SEVS, by deleting an entry, or by uninstalling.

External References