Why does code deployment matter?

The subject of code deployment is often forgotten, pushed aside, or is considered a waste of resources, which can tend to eliminate all of the hard and ingenious work that went into developing the project in the first place.

To illustrate why this is important, here’s an example to get you thinking: in 2012, Knight Capital Group went from being one of the biggest Wall Street players to becoming bankrupt in just 45-minutes, all because of a human error during the code deployment. I understand that it’s rare for these types of failures to happen, but would you really bet your company’s success and good reputation on a single person’s work on deployment? I’m not suggesting your employees have bad intentions, but we all have good and bad work days.

Is there a better way?

Of course there is! Code deployment is a very common task and the risks or issues that are connected with it are well-known. Because of that, there are several tools and workflows that promise to solve all of your headaches with code deployment. But is it actually easy to solve these problems?

The answer is both yes and no. Yes, because there are tools to help with the process, and no, because the tools themselves only do what someone tells them to do and nothing else. It works similar to a a hammer, in that the tools will not tell you where to put the nails in when building a wall, it will only hammer a nail when you use it. Therefore, things need to be considered thoroughly when thinking about code deployment automation.

Is your project ready for automation?

If you’re starting a new project, this can be fairly easy to handle. On every step that your tech team should be asking themselves is if the project will be possible (or easy) to deploy automatically. If the answer is no, then maybe there’s a better way of solving the problem at hand. Either way, it’s worth looking into the options.

It might be more troublesome if you’re looking for ways to automate the deployments on a pre-existing project if it wasn’t built with this in mind. However, here’s how you can approach the situation:

1. Create a document with a detailed description of all the steps needed to deploy the whole project stack.

Assume that you’ve made a change to every separate part of the system. And in reality, you should already have this done. If you don’t, then you probably trust that the person/team working on code deployments will always be available. But what if the key person ends up sick or can’t come into work? What if they’re not available?

2. For each and every step, decide how hard it is to automate it.

Simple scales such as Trivial, Easy, Hard, or Impossible can do the trick at this point, and for sake of clarity, let’s define them as follows:

Trivial – Running a single command on one or many known servers. No variations to the command beyond something like application version.

Easy – There’s a certain added complexity to the Trivial task. For example, you don’t know the exact list of the servers and it needs to be obtained from another service. Consider if it’s possible that the service providing the servers list may have outdated information and how to discover it.

Hard – Something that requires a creative decision from the person doing the deployment. A good example would be to require source code adjustment per server or time, etc. This should be never be the case.

Impossible – Tasks that require a physical action from the technology team. For example, the server needs to be switched to a different physical network to run the deployment process.

3. We can assume that the Easy and Trivial items are good to go, but something must be done about the Hard and Impossible issues:

Hard – Do what’s needed to be done so that no manual code changes are required while doing the deployment. Code should be tested and vetted during a QA (Quality Assessment) process, and afterwards there shouldn’t be any changes made to it while deploying(a single typo can cause a lot of trouble). Of course, these changes can be automated in some cases, but it will make the deployment process more complex and harder to test.

Impossible – If you have these issues, then there’s either a very specific reason for it that should be documented, or something went in very weird direction at some point. In 99.9% of most situations, this should not be needed and I’d put it on the list of things to get rid of.

After dealing with the Hard and Impossible items, we should be good to go. Sometimes it’s good to see if it’s possible to simplify the Easy stuff as well.

4. If all of the above is behind us, then the next step is to create the working deployment solution.

What automation options do we have?

Since code deployment is a well-known problem, there are a lot of tools that aim to lessen your stress. The simplest classification divides the tools into 2 main categories: self maintained and hosted (SaaS). The deciding factor is finding out which one is right for you.

I won’t dare to say that there’s a right one. I’d carefully review the process that you have in place and then try and find a tool that matches what you need. At Nopio, we use 3 different tools to automate our deployments. They include the following:

Deploy– A hosted solution that makes the deployments from Git repository a breeze. We tested quite a few of these services, but found Deploy to be the best fit for our needs. Basically, you allow the service access to your repository, setup target environments, and then decide which branch should be deployed where. It works with most hosted repositories (such as Bitbucket, GitHub and GitLab) and allows deploying with many protocols (SSH, SFTP, FTP etc).

The cool thing is that it keeps the history of releases and allows for easy rollbacks. As with any piece of technology, there are some issues. The biggest one is that it’s not a good option if you need to pre-build the code before deployment. For example, some of our projects require SASS styles to be compiled and we don’t keep the result styles in the repository. Usually, we compile them after deployment, on the target system, but it’s not possible if we deploy to FTP.

Capistrano – A tool where you can keep the configuration of as specially crafted files in your code. Traditionally, it was used for Ruby on Rails projects, but it’s perfectly fine for other platforms as well – we use if for our WordPress deployments. It gives a lot of flexibility in designing the deployment process, but it’s not easy to setup and requires a fair amount of work to create a robust solution. It’s also not FTP friendly, so even though it’s possible to deploy to FTP using it, you’d be going against the intent behind the tool.

JenkinsCI– While it’s not exactly a deployment tool, it’s an automation tool that can handle many different tasks, including code deployments.

At Nopio, we use it as our global cron service. It governs all of our tasks that need to run on schedule. What we like about it, in terms of deployments, is the fact that it allows us to create complex workflows, such as Docker-hosted projects. In cases like this, we can run a workflow that runs multiple steps, such as:

Checkout the code for each project service, run tests, and if successful, build the images versions.

Upload the new versions to the DockerHub repository.

On the target system fetch the new versions, kill running containers, and re-run the service using new app version.

Perform automated tests if the deploy has been successful.

This is only the tip of the iceberg, as there are many more options to explore. You and your team should spend some time reviewing what would work best for your company in each particular case, and whatever you plan, don’t leave the deployment process to a single manual effort. It may work for you during this time, but it might come back to bite your head off at some point in the long run.