workers-sdk icon indicating copy to clipboard operation
workers-sdk copied to clipboard

Support Environment Variables/Secrets in `wrangler versions upload`

Open axmav opened this issue 5 months ago • 9 comments

Describe the solution

Problem Statement

Currently, there's no practical way to upload Worker code and environment variables/secrets together in a single atomic operation with wrangler versions upload. This creates challenges for complex deployment scenarios, particularly when coordinating multiple Workers.

Current Limitations

1. --var Flag Issues:

  • Requires complex scripting to extract variables from .env files
  • Variables are stored as plain text, not as encrypted secrets
  • Not suitable for sensitive data (API keys, tokens, etc.)

2. wrangler secret bulk Separation:

  • Creates a separate version for secrets vs code
  • Makes atomic deployments and rollbacks more complex
  • Doesn't align with versioning workflow for coordinated deployments

Use Case: Atomic Multi-Worker Deployment

We deploy API and frontend Workers together using this workflow:

# Phase 1: Upload both workers (code only)
wrangler versions upload --name api-worker
wrangler versions upload --name frontend-worker

# Phase 2: Deploy both versions atomically  
wrangler versions deploy <api-version-id>@100% --name api-worker
wrangler versions deploy <frontend-version-id>@100% --name frontend-worker

Problem: Environment variables using secrets must be managed separately, breaking atomicity and complicating rollbacks.

Current Workaround

We've implemented complex TypeScript scripts that:

  1. Parse .env files
  2. Extract key-value pairs
  3. Pass them via multiple --var arguments
  4. Hide sensitive values in logs
// Example of current complexity
const envVars = parseEnvFile('.env.production')
const args = ['versions', 'upload', '--var']
envVars.forEach(({ key, value }) => {
  args.push(`${key}:${value}`) // Plain text, not encrypted
})

Proposed Solution

Option A: Environment File Support

wrangler versions upload --env-file .env.production
wrangler versions upload --env-file .env.staging --env staging

Option B: Secrets File Support

wrangler versions upload --secrets-file .secrets.production

Option C: Mixed Approach

wrangler versions upload --env-file .env.production --secrets-file .secrets.production

Benefits

  1. 🔒 Security: Secrets stored encrypted, not as plain text
  2. ⚡ Simplicity: No complex scripting required
  3. 🎯 Atomicity: Code + environment in single version
  4. 🔄 Rollbacks: Single version contains everything
  5. 📦 Consistency: Aligns with existing .env ecosystem

Alternative Considerations

If file-based approach isn't feasible, consider:

  • Bulk secret upload with version targeting:

    wrangler secret bulk --target-version <version-id> .secrets.env
    
  • Environment inheritance:

    wrangler versions upload --inherit-env production
    

Related Issues

This would greatly improve developer experience for:

  • Multi-service deployments
  • Environment parity
  • CI/CD pipelines
  • Blue-green deployments

Workaround Impact

Current workarounds require significant custom tooling and don't provide the security or atomicity that Cloudflare's versioning system otherwise enables.


Would love to hear the team's thoughts on this! Happy to provide more details about our use case or help test any proposed solutions. 🙏

axmav avatar Jul 25 '25 10:07 axmav

+1

chz avatar Jul 25 '25 12:07 chz

hitting the same problem would definitely go for for Option C if possible

mohamnag avatar Aug 28 '25 14:08 mohamnag

+1

It would be great to have atomic deploy.

Because right now I'm using a workaround:

"scripts": {
  "cf-typegen": "wrangler types",
  "check-types": "tsc --noEmit",
  "versions-secret-bulk": "wrangler versions secret bulk .dev.vars",
  "deploy": "pnpm run cf-typegen && pnpm run check-types && pnpm run versions-secret-bulk && wrangler deploy"
}

Koshkinks avatar Sep 09 '25 16:09 Koshkinks

Are you aware of the wrangler versions secret command?

https://developers.cloudflare.com/workers/wrangler/commands/#secret-put-1

petebacondarwin avatar Oct 06 '25 13:10 petebacondarwin

@petebacondarwin as stated in the very first comment, it is about doing it atomically: code + secrets + env variables. the way it is now does not make an atomic version for all of these hence has the overhead of keeping multiple related versions

mohamnag avatar Oct 06 '25 15:10 mohamnag

Ah right, I was confused because the comment doesn't mention wrangler versions secret only wrangler secret which is not designed to support the version upload flow.

One thing to note is that non-secret vars should be stored in the Wrangler config file (e.g. wrangler.jsonc) and are already uploaded alongside the Worker code when doing a wrangler versions upload.

I think we should indeed support effectively combining wrangler versions upload and wrangler versions secret bulk into a single command. This may need an update to the backend API to have a single entry-point. Otherwise, if we only do this in Wrangler, then the two API calls will still result in two items in your version history.

petebacondarwin avatar Oct 07 '25 10:10 petebacondarwin

I personally currently still use wrangler.jsonc for all env vars (secret or not) which is not a good practice but for this exact reason because now I can run a CI pipeline and get reverted to any previous version with a single command and atomically.

mohamnag avatar Oct 07 '25 10:10 mohamnag

OK - talked to the backend API team. It looks like we already have the pieces in place to do a bulk upload of secrets alongside a version upload.

Adding this to our backlog to implement when we have capacity.

If anyone wanted to have a crack at this the code in

https://github.com/cloudflare/workers-sdk/blob/436e254d8ef876c661a636be9367c23e3174f3d6/packages/wrangler/src/versions/secrets/bulk.ts#L44

and

https://github.com/cloudflare/workers-sdk/blob/436e254d8ef876c661a636be9367c23e3174f3d6/packages/wrangler/src/versions/secrets/index.ts#L98

would need to be combined into the code in

https://github.com/cloudflare/workers-sdk/blob/436e254d8ef876c661a636be9367c23e3174f3d6/packages/wrangler/src/versions/upload.ts#L361

in other words, the vars property passed to versionsUpload() should include the secrets parsed from the bulk secrets file where the type is either inherit or secret_text.

petebacondarwin avatar Oct 07 '25 10:10 petebacondarwin

Would love to see this being possible without necessarily using an intermediary file, allowing something like wrangler deploy --secrets $(fetch-and-spit-out-secrets)

theoephraim avatar Dec 03 '25 00:12 theoephraim