Tutorial: Shared Env Vars Across Five Services
A hands-on walkthrough of one problem: five services share a few environment variables, one of them changes, and you want to change it without missing a service or surprising its owner. You will do it first with plain files and a script (no OneEnv), then with OneEnv, and compare. The scenario is invented for illustration; the OneEnv steps follow the real app.
The scenario
Services: web, api, worker, scheduler, reports. They share three variables: DATABASE_HOST, DATABASE_PORT and CACHE_URL. The database is moving to a new host. reports is owned by another team and has a reporting freeze this week.
The problem
- Five copies of DATABASE_HOST exist. Missing one means a service that fails on its next restart, possibly weeks later.
- Nobody wrote down which services read the variable.
- The reports owner needs to accept the change on their own schedule, and you need evidence of who accepted.
Prerequisites
- For part A: a repository containing one directory per service. For part B: a OneEnv account and a workspace you can create services in.
- Shell with grep and sed.
Part A: without OneEnv
config/
web/.env
api/.env
worker/.env
scheduler/.env
reports/.env- Create a branch and a ticket naming the change. List consumers by searching for the key.
grep -rn "^DATABASE_HOST=" config/for s in web api worker scheduler; do
sed -i 's/^DATABASE_HOST=.*/DATABASE_HOST=db-new.internal.example/' "config/$s/.env"
done
git diff --stat- Open a pull request. Tag the owner of each service as reviewer. Leave reports unchanged and note why in the description.
- After merge, deploy each service. Record in the ticket when each finished.
- When the freeze lifts, repeat for reports.
grep -H "^DATABASE_HOST=" config/*/.envExpected result: four files show db-new.internal.example, reports shows the old host until its follow-up change.
Failure scenarios: a service stored its value in a CI variable rather than the file, so the grep never saw it; a new service copied the old value later; the reviewer approved a diff without knowing a sixth service read the key. The approach works, and everything depends on the grep being complete and people reading the PR.
Part B: with OneEnv
- Log in, Create workspace, then New service five times.
- In Env Master choose New Env Master for
DATABASE_HOST,DATABASE_PORTandCACHE_URL(the.envimport can load existing values at once). - In each service's Variables tab choose Inherit Env Master and pick the three keys. The consumer list now exists as data.
- In the top bar choose New branch, name it
move-db-host. - Edit DATABASE_HOST to the new host in Env Master and save. It is staged; the master is unchanged.
- Open Branches, open
move-db-host, check the diff and the impact preview listing the five services, then Submit for review. - As Owner or Admin, open Notifications and choose Approve & merge.
- Each service has a pending decision. The owners of web, api, worker and scheduler approve. The reports owner rejects for now.
Expected results: the exports of the four approving services show the new host; the Export tab of reports still shows the old host, because a service's export moves only when that service approves. History lists the branch and each decision with who made it. When the freeze ends, the reports owner can approve a later change; if you stage another change to the same variable before then, their older pending decision is superseded so they decide only on the latest value.
Failure scenarios: if someone else edited DATABASE_HOST while your branch was a draft, submitting shows MERGE_CONFLICT and you rebase; if a member lacks service_admin on their service they cannot approve (an Owner or Admin can); invited teammates must log in with their invited email because no invitation email is sent.
Verification
- For each service, open Export, choose dotenv, and confirm DATABASE_HOST matches what that service's owner approved.
- Open History and confirm one merge and five impact decisions.
- Optionally fetch an export with a CI token from the Export tab's CI / API tokens panel.
Comparison
- Part A needs no new tool, keeps config in Git, and gives you code-review history. It depends on search completeness and manual coordination.
- Part B records consumers explicitly and gives each one a decision with an audit trail. It adds a system to run and learn, does not touch your deploy by itself, and has no environment tiers.
