Skip to main content

Inject a secret into an App

Available

Deployed and supported. The fields and commands described here are stable within version v1alpha1.

Your services read secrets as environment variables, without network calls or libraries: you name the secret and the key in the App manifest, StackNGO does the rest. This guide shows the two forms, env for one variable at a time and envFrom for all keys at once.

Prerequisites​

1. One variable, one key: env​

shop.yml
apiVersion: deploy.stackngo.io/v1alpha1
kind: App
metadata:
name: shop
spec:
services:
api:
image: registry.gitlab.com/acme/shop-api:1.4.2
ports: ["8080"]
env:
LOG_LEVEL: info
DB_PASSWORD: { secret: db-password, key: value }
sng apply shop.yml

secret is the name of the secret, key the key inside it. Both are required. A secret set without --data has a single key, named value.

With a multi-key secret:

sng secret set shop-db --data host=db --data user=shop --data password=S3cr3t
env:
DB_HOST: { secret: shop-db, key: host }
DB_USER: { secret: shop-db, key: user }
DB_PASSWORD: { secret: shop-db, key: password }

2. All keys at once: envFrom​

When the secret is designed for it, name its keys like the variables expected by your application and inject it as a whole:

sng secret set shop-api \
--data DATABASE_URL=postgres://shop:S3cr3t@db:5432/shop \
--data SMTP_HOST=smtp.example.net \
--data SMTP_PASSWORD=xyz
api:
image: registry.gitlab.com/acme/shop-api:1.4.2
envFrom: [shop-api]
env:
LOG_LEVEL: info

Each key of the secret becomes an environment variable with the same name. envFrom accepts up to 10 secrets. A variable defined in env wins over the same key coming from envFrom.

3. Check​

sng app describe shop

As long as a referenced secret does not exist or has no value, the corresponding service does not start and the App state says so:

reason: SecretNotFound
message: Secrets absents (…) : shop-api

sng app describe is being enabled gradually on tenants; without it, sng secret describe shop-api tells you whether the secret has a value (version_id other than "0").

Set the value (sng secret set shop-api …): the service starts in the following minutes, without reapplying the App.

What you can expect​

  • Your containers receive the current version of the secret at startup. The keys of the secret are the ones you can name in key and that envFrom turns into variables.
  • A referenced secret that does not exist yet is created for you, pending, without a value. It appears in sng secret list; sng secret describe shows it at version_id: "0". It is a free inventory: deploy first, set the values afterwards.
  • When the value changes (new set, rotation), the deployment services that use it are restarted gracefully within 5 minutes, with the new value. See Rotation — how an App sees the new value.
  • When the secret is deleted, running containers keep their value in memory, but a container that restarts no longer starts as long as the secret is not recreated.

If it doesn't work​

SymptomCauseFix
The App switches to Invalid: "secret et key sont requis"{ secret: db-password } without key, or the reverseGive both: { secret: db-password, key: value }
The App switches to Invalid: "objet attendu de la forme {secret, key}"Another key in the object (name, from…)Only secret and key are accepted. sng apply accepts the manifest, the error appears in the App state
The service stays pending with SecretNotFoundThe secret has no value (declared empty or created automatically)sng secret set NAME …
The service starts but the variable is empty or the container fails on key not foundThe key does not exist in the secret (value expected, password given, or the reverse)sng secret describe NAME lists the exact keys
With envFrom, the variables have unexpected namesThe keys of the secret are not variable names (password rather than DB_PASSWORD)Set the secret again with --data DB_PASSWORD=…, or use env key by key
An env variable does not have the value of the envFrom secretenv wins over envFrom for the same keyRemove the definition in env

Going further​

  • One secret, several services: nothing prevents two services (or two Apps) from referencing the same secret. A rotation restarts all those that use it.
  • Private images: imagePullSecrets does not read secrets created with sng secret (only env and envFrom do); registry credentials come from the OCI registry.
  • Jobs and cronjobs: they read the secret when each run starts and are not restarted by a rotation.
  • No file mount: in this version, secrets are exposed as environment variables only; there is no option to mount them as files in an App service.
  • Why the secret is created pending rather than ignored: the service cannot start without it, and the wait is visible (SecretNotFound); a silently ignored secret would give a service that starts with an empty variable.

See also​