Deployment from Source Code VS Deployment Packages
The article covers the major difficulties and problems which may appear during deployment of complex applications using source code and why and when the use of packages assures more effective workflow and proves to be better devops practice. Any aspects of source code management is beyond consideration here and is a topic for another discussion.
Problems of deployment from source code
Build and release processes may differ drastically depending, among other things, on a used programming language. Though not obvious, almost every programming language is able to fulfill the concept of packaging by means of providing a set of objects build out of raw source code and packed together with their metadata information. Sometimes it can seem confusing, as for some languages there exist no traditional compile (Ruby, Python) or package (Go) phases, and a package may be represented by some source code labels only, such as a tag or a branch name. Release to production from source code in the cases looks quite logical, but may lead to difficulties and problems:
- It might be tricky to set up proper access level to the sources during deployment: e.g. having read only access for specific subset(s) of the sources.
Deployment becomes a complicated process when the application source code is just one of constituent parts of the system and requires a bunch of configuration files, environment settings and some scripts. The use of such configuration management tools like Chef, Puppet or Ansible helps to increase the consistency between the different sources, however, since they are also represented in the form of source code, they tend to add to the complexity of the process.
What is more important, source code cannot be considered to be an immutable deployment artifact and as a result deployment from source code cannot provide 100% guarantee that in production has been deployed exactly the same version of the application which had been tested.
Deployment from source code may be interfaced with the update operation which is a typical operation for source code management. As the update operation is destructive by its nature, when something goes wrong and the state of the system can not be determined, it is very difficult to debug and fix.
Atomic deployments and rollback
Some solutions to the problems may be to prepare containers or machine images containing all the environment and applications for every deployment. The images completely replace the application layer during deployment. In this case, an update operation cannot interfere into the process, since the new system state does not depended on the previous state, and a rollback operation to the previous version is also possible.
The solution adds to predictability and stability, but has its own downsides. For example, rebuilding images can take critically long time and in case of having more than just one runtime (e.g. a demo runtime or a runtime for pre-production/performance testing), it will be essential to support and maintain them all.
Packages as cumberstone of an immutability
To improve the efficiency of this solution, applications and systems, including Chef cookbooks or Puppet modules, can be represented in the form of immutable packages in the general format. This will enable to progress both the entire application and its individual parts in development, testing and deployment cycles more effectively and with more flexibility.
Someone may say that the use of packages leads to the additional dependency of the system on the package repository. But it should be emphasized that the dependency on the package repository only supersedes the dependency on the source code repository. Indeed, the processes of packaging and storing software components are new processes which will have to be additionally introduced. But the obtained benefits such as consistency, immutability and predictability are worth practicing them.
When the whole system is built out of immutable components, deployment can be reproduced with exactly the same artifacts as many times as required and for as many runtimes as required. Immutability of the language independent packages ensures that applications are installed and configured in the testing runtime the same way as they actually go to production. Fetching dependencies from public repositories in the Internet can be sometimes tricky as artifacts can change or even disappear between deployments. To avoid the situation, it’s advised to maintain own private repositories storing both application packages and all upstream dependencies.
RpmDeb private cloud package solution provides the possibility to quickly create and set up your private package repository without the necessity to build and maintain infrastructure for storing rpm, deb, npm (coming soon) and Maven (coming soon) packages. Try it now to assure more effective and stable development workflow.