Skip to content

Secrets

2 min read · main part only; folded sections are optional

After this you can answer: How does the API get the database password without it being in the code or the image?

flowchart TB
TD["api task definition<br/>secrets: ARNs only"] --> ECS["ECS starts a task"]
ECS -->|"execution role:<br/>GetSecretValue"| SM["Secrets Manager"]
SM --> C["container env:<br/>DB_USER, DB_PASSWORD, REDIS_URL"]
  1. The value is stored once, in Secrets Manager, encrypted. Pulumi state and the code only ever see the ARN.
  2. The task definition maps a secret to an env var. For JSON secrets it can pick one key: <arn>:password:: becomes DB_PASSWORD.
  3. At task start, ECS reads it with the execution role, which may call secretsmanager:GetSecretValue on exactly those ARNs.
  4. The value is read once. A running task keeps the value it started with, even if the secret changes later.
SecretHoldsRead by
rds!db-…Postgres user and password (JSON)api execution role, at task start
minitickets/dev/redis-urlrediss://:<auth token>@<endpoint>:6379api execution role
minitickets/dev/revalidate-secret64 random charactersapi and web execution roles
minitickets/dev/ticket-signingthe HMAC key for ticket QR codesthe tickets Lambda, at run time

The database secret is made by RDS itself (manageMasterUserPassword), so the password never exists in our code, config or Pulumi state. RDS rotates it every 7 days by default. The Redis URL is built in infra/src/data/secrets.ts → createSecrets.

From → toWhat happensWhat allows it
API ECS service → RDS master password secretonly when computeEnabled = trueECS reads the database user and password when a task starts
  • iam api execution role, policy read-secrets: secretsmanager:GetSecretValue on this secret's ARNcreateIamRoles
  • route public route table: 0.0.0.0/0 → minitickets-dev-igw. The task has a public IP; there is no NAT gateway and no VPC endpoint.createNetwork
See the database secret on the map →

Secrets Manager → Secrets → minitickets/dev/redis-url → Overview. Do not press “Retrieve secret value”.

SymptomCauseWhere to look
Tasks stop with ResourceInitializationErrorWrong ARN or JSON key, or the role may not read itECS → stopped task → Stopped reason
“password authentication failed” after a rotationRunning tasks hold the old passwordRotation date; restart the service
API cannot connect to ValkeyURL starts with redis://, but TLS is requiredThe URL format in secrets.ts
How would you handle rotation without restarts?

Read the secret in code with a short cache and reconnect on an auth error. That needs the task role to have GetSecretValue, which widens what the code may do. Today a restart is the simpler fix.

Why is the origin secret for CloudFront not in Secrets Manager?

No running code reads it. Only two configurations hold it, CloudFront and the ALB listener, so Pulumi keeps it as an encrypted secret in its state.

Why must the book never show get-secret-value?

It prints the secret in plain text into your terminal and its history. describe-secret answers every debugging question (does it exist, when was it rotated) without the value.

Advanced: Details per secret

The Redis and revalidate secrets use recoveryWindowInDays: 0, so switching a layer off and on does not collide with a name still scheduled for deletion. The ticket signing key has no rotation on purpose: replacing it would make every issued ticket invalid (infra/src/tickets/storage.ts → createTicketStorage).

Answer these without scrolling up. If one feels hard, reread that section.

  1. What does the task definition hold instead of the password?
  2. Which role reads the secrets, and when?
  3. What happens to a running task when RDS rotates the password?
  4. Which secret is read at run time instead of at start, and by what?
  5. Why does the Redis URL start with rediss://?

Redraw it from memory: task definition (ARNs) → ECS with the execution role → Secrets Manager → container env vars

Try this: on the map, select the RDS master password secret and open 'Who can touch me' in the Permissions tab

Read this book online: https://book.theversehub.in/