We have a lot of apps and web services (some public facing products, some internal and part of a private "backend") that are interdependent on one another. Each one of these components has 4 environments (clusters of servers/nodes serving specific purposes):
- Non-Production
DEV
- Integrated development environment where CI builds push changes; useful for engineers to troubleshoot hard-to-find bugs that are not locally reproducibleQA
- Isolated QA/Testing environmentDEMO
- Stable UAT environment for business stakeholders
- Production
LIVE
- Our live/production environment
Code promotion goes: LOCAL
(developer's machine) => DEV
=> QA
=> DEMO
=> LIVE
.
Say we have an application called myapp
that is backed by a RESTful web service called myws
, which itself is backed by a DB called mydb
.
Currently, we have what I would call "orchestrated" promotion amongst these dependencies: the myapp-dev
points to myws-dev
which uses mydb-dev
. Similarly, myapp-qa
points to myws-qa
which uses mydb-qa
. Same for DEMO
and LIVE
.
The problem with this is that anytime I make a change to, say, myapp
, this requires me to make changes to myws
and mydb
as well. But because each DEV
environment points to its dependencies' DEV
environments, it means I have to schedule and rollout these changes all at the same time. Furthermore, if one build becomes unstable/broken, it often brings down other upstream components; for instance if a developer breaks something when changing mydb-dev
, the myws-dev
and myapp-dev
clusters usually also become unstable.
To solve this, I am putting together a proposal for what I would call a "siloed" promotion strategy: all inter-component dependencies follow this guideline:
- Upstream dependencies depend on the
DEMO
environment for their downstream dependencies, for all of their non-production environments (DEV
,QA
andDEMO
); and - Upstream dependencies depends on the
LIVE
environment for their downstream dependencies for their production environment
Using this convention, myapp-dev
would actuall point to myws-demo
, which would use mydb-demo
. Similarly, myapp-qa
would also point to myws-demo
and mydb-demo
.
The advantage here that I can find is build stabilization: it is much less likely that the DEMO
environment for a particular component will become unstable, because code can't make it to DEMO
without rigorous testing both on DEV
and QA
.
The only disadvantage I can find to this method is that, if DEMO
does break for a particular component, all the non-production environments for all upstream dependencies will suddenly be broken. But I would counter that this should happen extremely rarely because of the testing performed on DEV
and QA
.
This has got to be a problem that many developers (much smarter and experienced than myself) have solved, and I wouldn't be surprised if this problem and its solutions already have names to them (besides what I am calling orchestrated/siloed). So I ask: Do the merits of a siloed promotion strategy outweigh any cons, and what are the cons that I may be overlooking here?