A pattern I keep running into (and used to do myself): a CI/CD pipeline starts small, so all its variables just live at the top of the YAML file. It works. Then you add a second environment, and a third pipeline, and suddenly you've got the same connection string, API URL, or secret pasted into half a dozen files.
Nothing about this breaks on day one. That's what makes it a trap — it works fine right up until someone needs to change a shared value, and now they're hunting through every pipeline file to find every copy of it, hoping they didn't miss one. In the meantime, if one file gets updated and another doesn't, your environments have quietly drifted apart without anyone deciding that should happen.
The fix is small: stop copying variables, reference them instead.
In Azure DevOps this means using a variable group:
yaml
variables:
- group: shared-vars
instead of hardcoding the values in every pipeline that needs them. (Most CI/CD platforms have an equivalent — GitHub Actions has reusable/organization variables and secrets, GitLab CI has group/project-level CI/CD variables, and so on. The mechanism differs, the principle doesn't.)
What you get out of it:
One source of truth. Update the value once, and every pipeline that references it picks up the change.
No silent drift. Environments can't quietly disagree with each other because there's nothing left to disagree — there's only one copy.
Readable pipelines. The YAML file goes back to describing what the pipeline does, not a mix of build logic and duplicated config.
It's a small change, but it's the kind of thing that's much cheaper to fix early than after you've got a dozen pipelines all holding slightly different copies of the same values. If your pipeline YAML has grown a block of hardcoded variables at the top and you've got more than one pipeline that needs them, that's usually the sign it's time to pull them out into a shared group.
Top comments (1)
Hit this exact trap on a multi-env pipeline: the same connection string pasted into three YAML files, quietly drifted apart by the time a fourth env appeared.
The variable group fixes the copy problem, but what stuck for me was owning each shared value in exactly one place and adding a grep in CI for duplicated literals, so a copy-paste gets caught at review instead of on the third environment. Did you end up templating the whole pipeline from those groups, or only referencing them? On my side the group reference alone still left drift in everything the group didn't cover.