The paradigm shift from "Never change a running application" to "Always run a changing application" has introduced new challenges in the release process.
The release management process handles the deployment of new software versions to its destination machine.
A classic scenario
There is a substantial set of activities going on here, so let’s start with a classic scenario: There already is a running instance of the application – the Production – but an issue emerges, calling for a software change.
Generally, this poses a challenge consisting of several tasks, which most often includes: update the source code, change configuration files, update the DB model and adjust some DB data, and sometimes, update the external DLL.
In a Release management context, we do not go into development of the change itself, but considering that the code and other source-controlled files have been updated, so all we need to do is just carry those changes out to the Test environment first, and then to Production itself.
Things are getting complicated
Here we already have two general environments, but things are going to get much more complicated – so just bear with me.
It is highly recommended to establish a set of gates, or criteria, that a change must fulfill prior to its departure towards the Test environment and Production itself.
For the purpose of this article, we will assume that the change at stake meets these criteria.
A change in source code typically triggers a new build that produces build artifacts. These build artifacts can be released towards a destination machine. Some of the build artifacts can be dependent on the release destination, most notably – configuration files.
These files often contain endpoint data, authentication data, DB connection strings, etc. This information is naturally different for Test and Production environments and poses a challenge to be resolved by a multistage configuration transformation process.
There are sometimes several steps – but most often a 2-step config transformation is enough. The first step is introduced by the build process, the second one by the release process. In essence, we are filling the placeholders or simply adding configuration lines to configuration files during the process once the destination itself has determined the content of these data.
So, we have our build artifacts; our destination-dependent data are managed by the build and release processes. In order to put them to work, we must perform deployment to Test and consequently, to Production.
Here we’ll establish a set of rules so that by using this automatic process, no change can ever reach Production without prior verification by Test, and final manual approval from the released personnel.
The deployment process must be reliable, reversible, fast, observable and retraceable. You want to archive several versions of the application in order to be able to perform a rollback to the previous version in case of an unsuccessful deployment attempt. In this case, you have to provide feedback information with the necessary data to your personnel, to increase situational awareness and maintain retractability.
There are several tricks to achieve fast deployment and to reduce critical application downtime to seconds. This is done by deploying the new version to the temporary folder, stopping the previous application version, renaming the folders, and starting the application again. In case of an error, or a smoke test failure, the process simply runs the previous version of the application and informs your personnel.
Zero downtime is possible by using distributed application architecture or by enabling more than one instance on the machine with load balancing usage. Here you need to work out the deployment scenarios. For instance, if you have ten load-balanced machines and deployment fails on the third one – do you continue or rollback? The answer highly depends on each application and the risk of running more than one application version at the same time.
The release management process is multithreaded in essence, as the changes in code often go hand in hand with the DB model and data updates, and sometimes also in pairs with OS, driver or DLL version changes. You want to be aware of these activities and support them through your release process, especially in a rollback context. There are many pitfalls here – for instance, you upgrade to a new driver manually, but deployment fails for some reason, and automatic rollback kicks in. However, your previous application version is incompatible with your new driver version, so rollback also fails, resulting in your application instance failing and many red lights.
You want your release process to be stable, safe, and resilient. By elegant orchestration, you can achieve a mixture of manual and automatic process steps that makes you comfortable with its outcomes – a release management process that increases the quality of your application on both the customer’s and developer’s side.