Secrets Management in deploy-stack
Managing .env files across a team and syncing them to the cloud is a notorious pain point. deploy-stack solves this by natively integrating with AWS Secrets Manager, ensuring zero plaintext secrets ever touch your GitHub repository or CI/CD pipelines.
The Secrets Lifecycle
Section titled “The Secrets Lifecycle”To maintain zero-secret Git repositories and safe infrastructure provisioning, secrets follow a strict 4-step lifecycle:
1. Scaffold ───▶ 2. Provision Vault ───▶ 3. Push Secrets ───▶ 4. Deploy to App(deploy-stack) (deploy-stack apply) (secrets push .env) (git push)Generates Terraform Creates empty vault Uploads encrypted keys ECS container boots& secret_keys.json in AWS Secrets Mgr & updates secret_keys with injected envStep 1: Provision the Vault (Day 1)
Section titled “Step 1: Provision the Vault (Day 1)”Your Secrets Manager vault is declared in terraform/secrets.tf. Provision the base infrastructure first:
npx deploy-stack applyThis creates an empty, secure secret vault named <project-name>-secrets in your AWS account.
Step 2: Push Secrets to AWS
Section titled “Step 2: Push Secrets to AWS”Once the vault exists, push your local .env values directly to AWS:
npx deploy-stack secrets push .envWhat happens under the hood?
- The CLI reads your local
.envfile. - It encrypts the key-value pairs and pushes them securely into AWS Secrets Manager under your project’s namespace (e.g.,
my-project-secrets). - It generates a local
terraform/secret_keys.jsonfile containing only the names of your keys (e.g.,["API_KEY", "STRIPE_SECRET"]), not the values.
💡 Tip: The
secrets pushcommand takes the file path as the first argument. If you need to use other flags, ensure they are appended at the end of the command:npx deploy-stack secrets push .env --any-other-flags
Step 3: Map Secrets into the Container
Section titled “Step 3: Map Secrets into the Container”Commit the updated terraform/secret_keys.json and push to GitHub:
git add terraform/secret_keys.jsongit commit -m "chore: map new secrets to ECS"git push origin mainTerraform reads secret_keys.json during the GitHub Actions deployment and maps each key directly into your ECS Task Definition. When your Fargate container boots up, AWS injects the secret values into process.env (Node) or os.environ (Python) in memory.
⚠️ Commit this file.
secret_keys.jsonholds key names only — never values — so it is safe for version control, and deployment depends on it. The generator does not gitignore it. If your project was scaffolded by an older CLI, remove theterraform/secret_keys.jsonline from.gitignoreand rungit add -f terraform/secret_keys.json.
Day-2: Pull, Audit, and Rotate (no redeploy)
Section titled “Day-2: Pull, Audit, and Rotate (no redeploy)”Secrets don’t stand still — teammates join, keys rotate, local .env files get lost. Two commands close the loop:
npx deploy-stack secrets pull # merge remote values into local .envnpx deploy-stack secrets audit # diff local .env vs AWS, change nothingpull appends missing remote keys after your existing entries, keeps local-only variables, and asks before overwriting conflicting values (automatic in --headless mode). audit prints a colored drift report: + missing locally, ~ mismatched values, - never pushed to AWS.
Which flow do I need?
| Situation | Command |
|---|---|
| New variable name added/removed | secrets push, then commit secret_keys.json + git push (task definition must be rebuilt) |
| Only a value changed (same keys) | secrets push, then accept the rolling ECS restart prompt — live in seconds, no redeploy |
New machine / lost .env |
secrets pull |
| “Why doesn’t my app see the new value?” | secrets audit first, then push or restart accordingly |
See the secrets CLI reference for flags, merge rules, and prerequisites.