Deployment Environments

Deployment Environments

In this post you will read about what deployment environments are, common types of them, and how, when and why to use them.

TL;DR

Imagine a relatively complex software system which is available for its users online, via a website, for instance (e.g. social platform or email service provider).

During a lifecycle of the system multiple versions of its codebase exist at a single moment of time: a stable version used by real-world people, development versions with arising new functionalities, candidate versions awaiting for testing and qualifying as stable. Please pay attention on the plural form of the development and candidate versions, because multiple new functionalities of a system are usually being developed at a same time (in parallel).

Since all these versions coexist in time, they have to be split in space. This is exactly what deployment environment are used for. Each environment is a hosting space for a version of the software system or its part. All deployment environments are separated from each other (with rare exceptions), thus end users can benefit from the stable version of the system while developers are adding new things.

Types of Deployment Environments

There are several types of them. Each type has its own purpose, therefore has special characteristics and features. Now let's take a look at the most common deployment environment types.

Development

Development (or dev) environment is used for creating new functionalities of a software system. It contains raw codebase of a new functionality, which gradually evolves from bare copy of latest stable version to complete candidate version with newly implemented functionality. Typically only one new functionality of a system is being developed within single development environment.

Development environment is hosted and run on developers' local machines.

Existing unit and integration test (those from the stable version) are run in the dev environment during development process. New unit and integration tests are created and instantly run alongside. End-to-end test of the functionality can be run in the environment when possible and necessary.

In a version control system (VCS) the development environment represents a dedicated dev branch of the future functionality. This branch is named in accordance with the new functionality (e.g. "auth" or "profile") and is initially created from latest stable version of the codebase, i.e. by branching from the "master".

New functionality being developed on a dev environment may involve processing some data which doesn't exist yet (e.g. future database tables, image files etc). In this case developers during they work create instant data prototypes for initial testing, usually manual. This is meaningless data, often incomplete and incorrect. During development process the data structure evolves until initial stable data scheme emerges. On early development stages the dev environment data is often hardcoded and/or stubbed out.

If the new functionality involves interacting with other service nodes (first-party) and/or external providers (third-party), then the dependency services are deployed or configured on their demo environment.

After the development environment functionality in completed, it is awaiting to be merged into staging environment.

Staging

Staging (or stage) environment is a mirror of production system. It contains a candidate version of the codebase awaiting for top-level testing. The staging environment is primarily used to verify how the system will behave in production.

Staging environment deployment infrastructure fully imitates the production infrastructure, however, it may be less powerful, protected or optimized for performance than the production one.

In a VCS the staging environment represents a special branch called "staging" branch, which contains the candidate version of a codebase. When new functionality of a dev branch is completed, the dev branch is merged into the "staging" branch. The "staging" branch is usually integrated with a CI/CD service, thus the local tests (unit and integration) are instantly run after merging, and if they are passed, the codebase from the "staging" branch is automatically deployed to staging infrastructure.

After the candidate version is deployed to the staging infrastructure, top-level tests (such as end-to-end, performance, security or manual tests) are run. Those are the tests that either cannot be run on development environment, or when running them there doesn't make sense. If the top-level tests are passed, the staging codebase is qualified as a new stable version of the software system, the "staging" branch is merged into the "master" branch in the VCS.

Staging environment data represents data fixtures, which are meaningfully composed in advance and are unified throughout the system architecture. The data fixtures are used for automated testing run on the staging environment. Although it is not a real-world data, it is required to keep it ordered and accurate throughout all the staging environment to ensure correctness of the automated tests. It is also recommended to compose the fixtures of some close to real world data to improve development and testing experience.

Production

As its name claims, the production (or prod) environment is a production deployment of latest stable version of a software system, which is actually used by real-world people.

The production deployment infrastructure is similar to the staging one, but it is much more powerful, with additional security (e.g. anti-DDoS firewalls) and performance (e.g. clustering) setup.

On the production environment no tests are run, neither automated nor manual, however, constant logging and system activity monitoring is performed. Additional critical state notification services may be involved as well, for example notifying administrators about security or performance issues via email or SMS.

In VCS the prod environment represents the "master" branch, which always contains the latest stable version of the codebase. When the staging environment codebase passes all tests and is qualified as a new stable version, the "staging" branch is merged into the "master" branch. After that, the codebase from "master" is manually deployed to the production deployment infrastructure with graceful restart. After new stable codebase version is merged to the "master" branch, all existing dev branches must merge the current "master" codebase into themselves.

The production environment data is created and used by end users of the system. It is a real-world data which requires the highest security level for its privacy and integrity, direct access to it is highly restricted. The production data often has very large size, sometimes hundreds of terabytes within a single software system.

Demo

Demo environment is a replication of the production environment used to support development of new architecture nodes and/or functionalities. It contains the latest stable version of the software system, but is not deployed nor meant to be used by real-world users. When a new functionality to be developed is dependent on some existing services, the latter are deployed to their demo environment to provide such dependency for the new functionality for initial testing. Thus the latest version of services and interfaces is available for developers' needs.

No tests are run on the demo environment as there is no need of that.

Demo environment data is used for initial (usually manual) testing of new functionalities being developed on their dev environments. Thus the demo data has similar characteristics as the dev data. However, the service application deployed to the demo environment may enforce the data to comply to the latest stable data scheme. It is recommended, however, to keep the demo data meaningful and accurate to improve development experience. It would also be a good practice to reuse the staging fixtures in the demo environment. Developers of new dependent functionalities may have direct access to the demo data.

In Conclusion

We have walked through the most popular deployment environments used in a lifecycle of software systems. Usage of these environments may differ for some systems. There may also be other types of deployment environments with their special purposes and characteristics. All of this depends on project and system needs. Thanks for reading!

Photo by @cjoudrey from Unsplash