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
DEMOenvironment for their downstream dependencies, for all of their non-production environments (DEV,QAandDEMO); and - Upstream dependencies depends on the
LIVEenvironment 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?