We have it good in this day and age. Environments are cheap. If you don't want to run a VM yourself, their are cloud based services. And if you don't want to go with VMs, Docker can allow for running multiple systems if the application fits.
How many environments does your product release go through? Dev, dev 2, installation, integration, QA, implementation, staging, pre-production, production? Dev, CI, production?
As a developer you'd probably only be concerned about the dev environments and the occasional location where a bug can be reproducted. Unless of course you are one of those unlucky developers who has been saddled with responsibility of maintaining the entire release process (something about bringing dev and operations together).
As quality assurance, environments are critical. They are a place for an expected package going to production to be evaluated for anything. But why do we have so many? What benefits do they provide?
That is an important question to ask. Not only for reducing the number of environments but to determine what testing occurs in the environments. Each environment should provide you with a new and interesting difference which allows for a different test to cover the application.
An indication of a poor release process is the ability to repeat an environment. If you are covering the same tests over and over again to check that the environment has been configured correctly.
One of the primary reasons for having environmental promotion is producing a more production like environment. It also helps to parallize work.
Production data provides the most valuable state information for driving testing. All of that data feeds into whether a code path will choke or happily progress. Let us look at a few points on this.
- Quantity of data will influence performance
- Data stored may come from arbitrary user input causing validation paths to execute (or be missing) for new functionality.
- prior code issues could have introduced bad data that is a problem for reports or new functionality
We want to take this problematic data and run it through the system. We don't want to take all of the production data and move it through to every environment. You don't want to require every change to run through the same tests just because it installed into a new environment.
I've heard of this environment as a dirty environment, and for good reason. This environment is a place the dev is adjusting configuration, installing debug builds (possibly a single dll), installing system tools, and if you're extra lucky modifying registry entries.
It is a necessary evil, but the more you tweak things that "don't matter" and deviate from production, the more likely your future development will be against a modification you forget you made. This is why it is critical to bring the environment back to a working and production like configuration.
Containers are of course a great way to solve this.
This environment is generally considered clean. QA is provided a package and it is installed like production. The thought here is that any issues found can be taken back to the developer to fix.
But recall what we learned about the development environment. So the issue can only be replicated in QA. So now QA has an installation not destin for production providing the opportunity for the next release to pull out an important configuration change.
Dev and QA environments are dirty. Containers can help with that.
OK now that we caught all of those broken builds we can finally test that the product works in an environment like production. In this environment we might have production data and production hardware. Why don't we just start testing here?
Since it is hard to return the system back to a "production" state, pre-production needs to be "protected" from all of those bad builds that never make it to production.
Containers can help with that.
Containers didn't fix that. Best practice has small applications in a container and not to create monolithic containers. This means production is made up of many containers and network configuration.
Kerbernetes can help with that.
All of this really helps to reduce the pain of managing the environment. And makes replicating production, excluding data and scale easier.
This means you're really working in two environments, production and a replica of production (or 20 replicas because why not).
You don't need to use containers to replicate production, you just need to put in more work to make recreating an environment as painless, and you need to recreate the environment frequently.