Build once, deploy many

I’ve heard many times the phrase “We need a build to X environment” or “We’ll be doing a build to production on X date”, when in fact I think we should substitute build for push, deploy, install or some other verb that indicates that we have already generated the artifact that you’re going to go live with.

In most cases, this is accurate, as we’re compiling or otherwise generating the file that we’ll be then moving it to the specified target. But why are we building this artifact just before we’re going to push it to an environment? In software we certainly don’t enjoy the benefits of an on-demand, just-in-time philosophy that other industries do.

So, why do we insist on building and packaging every time? I think this often is a bad habit that teams acquire when their codebase is small. Compiling and/or packaging is relatively cheap (no more than a few seconds), so this cost is often neglected. And since it’s easier to re-generate the artifact than it is to create an infrastructure to persist these files and have the deployment scripts use it, teams usually skip this step in favor of short term gains. But as the codebase grows, this cost cannot be neglected and sometimes I’ve seen it take over 50% of the time of the overall deployment process. I’ve also seen (and worked with) a team in which the build was cloning their dependent repositories and building them from scratch, taking at least two hours. So much for continuous integration.

Build once, deploy many is a philosophy that has two advantages:

  1. Our deployment scripts become just a few instructions on how to move the package from one place to another. If your deployment scripts are doing something other than just deploying, that’s a big smell.
  2. We guarantee that the file that we’re deploying is going to be exactly the same across all environments.

The infrastructure for this could be as simple as copying the file to a shared drive and have the deployment scripts pick it up from there or as sophisticated as using tools like Artifactory or Nexus. These artifact repositories even have a REST API that allows you to perform operations like deploying the artifacts directly from the container, so your scripts don’t even have to download them. Your deployment scripts become even thinner!

Another advantage of these tools over simple file copy is that they add a layer of metadata on top of the files that makes file versioning easier.

So, you can have an independent process that generates the binaries to be deployed, versions them and pushes them to your artifact repository. Then your deployment scripts pick it up and just moves it across your different environments, making its way towards your production environment. As a former boss put it: “You wrap a gift and just hand it over to the next guy until it gets to the hands of the right person”.

And just for the record, I don’t like the term “production”; I’d rather use the term “live environment”, but that’s a different discussion.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: