Deploying software doesn’t have to be that complicated!
I’ve seen and built many software building and deployment solutions over my career, and I have come to find that most software deployment can be boiled down to a simple process.
I’m not trying to give you a solution for your software deployment automation, nor am I trying to perfectly model your exact process.
What I am trying to do in this post, is to help you to simplify your process.
If you can identify the parts of your deployment process that fit into the simple steps I am going to outline below, it should be much easier for you to automate your deployment process.
Even though software build processes, infrastructure and components are unique, I have found that most software deployment processes can be simplified into the following steps.
- Build software without configuration
- Create environment specific configuration.
- Create a set of database changes.
- Bundle software, configuration and database changes.
- Apply new software
- Apply new configuration
- Apply new database changes
- Start it back up
You might read through these steps and think “well duh.”
You might be tempted to say “my process is more complicated than that.”
I’m not going to argue with you. You are right, your process is probably more complicated than that. But, does it need to be?
Can you simplify your process to fit into these steps?
Sure, the implementation of these steps is likely to be fairly complex and vary for each type of software, but if you can distill the process into these steps, you can much more easily automate that process.
Where people go wrong
The big key to my simple version of deployment is
Build software without configuration
You MUST do this! Departing from this step causes all kinds of pain and complexity. Please don’t try to build your software and the configuration for an environment at the same time. These things must be pulled out from the get g or you will have the pain of trying to tease them apart later – or you will have to create separate builds for each environment.
It is also critical that the same bits that were built by your build server are what is deployed to each environment!
I will say that this isn’t the easiest problem to solve. You may need to have a separate build process that builds up the configuration for an environment.
Separating the two will also force you down the path of building a process to apply that configuration to an environment.
But, if you are willing to accept that this is just a must and bite through this pain, you’ll come out on the other side clean (even though you had to crawl through tunnels of crap.)
The whole story
Now that I’ve hopefully convinced you to separate your configuration from the building of your software, let’s go over the big picture of a deployment using the simple process outlined above.
It all starts out when you build your software. Perhaps you have a continuous integration build server setup that is automatically building software on each check-in; perhaps you are manually kicking off a script.
Once you have built your software, you have some bits that you should be able to apply to any environment. Nothing that you built here should be machine or environment specific in any way.
Now, you kick off another process, or perhaps one was kicked off simultaneously by your continuous integration server. This builds up the configuration for the environment you are going to deploy to.
A similar process is kicked off—also could be simultaneous, for generating a list of database changes that need to be applied to the target environment.
Now that you have your bits, configuration and database changes, you are ready to deploy.
If you are smart, you’ve even built these ahead of time and they are just waiting for when you need them.
Next, gather up the artifacts and move them to the deployment target where you actually apply them.
First, unpack your bits and put the new bits into place. (You may or may not need to take your application fully offline to do this.)
Then apply the new configuration on top of your newly installed bits for that environment.
Finally, apply database changes for that environment.
Now you should be completely deployed and can start up your application.
But how do I do it?
Perhaps you agree with me that the actual process should be what I have outlined and described, but now you are at the point of implementing a solution.
How do you actually automate this stuff?
Good question. If you figure out a simple answer, let me know.
This is the point where you might be writing custom tools and scripts to get all this working. The key is to take it one step at a time.
There are at least two tools out there that I know of that help you do this. I can’t speak for either of these tools, since I haven’t used them myself, but I have heard good things about them.
One other thing to consider is how you are going to get the right stuff to the right server. You will want to think about things like:
- Promoting build products
- Preloading promoted products to servers to make deployment faster
- Getting through firewalls by having the software or some other process PULL the upgrade to your target, rather than you PUSHING it there.
- Rollback, or some kind of mitigation strategy if things go wrong. (My recommendation here is not to get fancy. I have NEVER seen a successful rollback, only a database restore followed by a manual code restore. If you mess up bad, just count on restoring the machine and the database.)