Deployment Automation FTW!
Around these parts we love automation. That’s not just because automating things is fun (it totally is — anything else is fighting words), but also because we don’t like losing time doing repetitive tasks. No one likes doing the same thing over and over. Repetitive tasks easily become failure points — boredom sets in and shortcuts are used, or mistakes are made as your brain doesn’t give the task the concentration it requires.
Let’s see how our old friends Romulus and Remus deal with automation — specifically, deployment automation.
Romulus and Remus Development Agency and the RESTful API
Romulus and Remus are super excited! They have won a project that is going to allow them to show off their skills at building a RESTful API! The API will power some cool new features for a Drupal site they built and deployed on Acquia. It’s a good day.
Our heroes love Python and Flask, so that’s what they’re going to use to build their API. The also love Ubuntu 14.04, so they’re going to use that as well.
Things go great in the beginning of their project; they only have to worry about one environment: the dev testing environment. Each of the developers can login to that system to do manual code deploys. Every time someone deploys new code they manually announce it on the project’s Slack channel so that everyone is kept in sync. There are some minor conflicts, but by and large this first sprint zips by without difficulty.
After the first sprint, however, they have to set up a QA environment so that their trusty QA team can get in and start testing all of that awesome new API code.
This is where things start to … unravel.
Developers start getting confused regarding which server they are on when they’re doing deployments. They keep ending up with QA code on dev and dev code on QA. QA is getting frustrated because everything is constantly breaking and they can’t get through their tests.
Finally, with frustration at an all time high, the QA and dev leads get together and agree that there need to be some baseline unit tests created. That would make it possible for QA to quickly run a set of tests on a build before they waste time testing a broken build. The dev lead agrees: all developers will run the tests before they commit code.
In the second sprint, the developers write some good tests for the API they have created so far. They are in a hurry now, because no new API work is getting done. Because they’re trying to wrap this up quickly, the tests aren’t great, but at least now they have something that QA can use in order to gauge a really broken build. It’s progress … kind of.
During the third spring the developers are back in business, working frantically to make up for the time they lost in the previous sprint. They try to remember to run the tests before they commit, but they’re in a rush — and only human — so most of the time? They forget. As a result, QA is still spending most of their time rejecting builds, and nearly every time it’s because the deployment to the QA environment wasn’t done correctly.
The QA team and the dev team begin giving each other dirty looks in the lunch room.
At the end of the fourth sprint it gets even more complicated. Now, the client would like an environment where they can review progress on the API. Because the client will be reviewing this site, it’s decided that only the dev lead will be responsible for updating it. The deployment process takes an hour of Remus’s day, but it gets done properly and the client is happy.
QA, unfortunately, is NOT happy and is ready to stage a revolt because they were unable to test a build all week due to the fact that the QA environment was so messed up. Tensions continue to flare. In order to try to make things a little better, Romulus takes charge of all deployments to QA to make sure that QA can test. This takes an hour of his time each day, but the builds are testable for the most part. QA simmers down a bit as they are finally able to do their jobs, but now both Romulus and Remus are super-stressed because they aren’t able to complete their development tasks and can’t complete code reviews for the team. Progress slows down and the quality of the code decreases.
The cycle continues and the project runs late; they are having trouble getting to a stable point. Adding the production environment creates another level of complexity, and things are breaking pretty frequently. The client isn’t impressed because they remember how well things went with the Drupal build on Acquia. They can’t understand why this is not going as smoothly… and it is SO not going smoothly.
Testing and Deploying Code as Repetitive Task
As you can see from the trials of Romulus and Remus, one of the repetitive tasks that we encounter frequently is deploying solid code to development, test, and production environments. I talked about how Acquia’s environment can help when working with Drupal (read all about it in https://www.bowst.com/article/horror-stories-development-trenches) but we at Bōwst work with a variety of systems — not only Drupal.
So what do we do then? Our current go-to is CircleCI, which provides by far the easiest Continuous Integration and Deployment service we’ve used (and we’ve used a bunch over the years). CircleCI facilitates the automation of code testing and deployment so that every time someone commits new code, it’s tested and deployed to the appropriate environment.
CircleCI, What is it Good For? Huh?
The first big win for us is that CircleCI integrates easily with GitHub, which is our preferred source code repository. That’s a must. CircleCI watches GitHub for changes, and can be configured to automatically respond to those changes.
CircleCI also supports Ubuntu 14.04 LTS as a build platform. Here’s why that matters: Ubuntu 14.04 LTS is our favored deployment platform for production systems. It’s great that we can run automated tests on CircleCI using the exact same environment that we will ultimately deploy into.
That segues nicely into our next love — support for a ton of languages. We use Python/Flask for building APIs, and CircleCI supports it beautifully. We also have a need to deploy other PHP-based CMSs that aren’t supported by Acquia or Pantheon, and CircleCI has our back there as well.
CircleCI also integrates with Slack, which we use for all intra-team communication. This makes it super easy to get build notifications out to our whole team. No need to check email when you can instead receive a message right in a shared channel in Slack!
Additionally, CircleCI has super-simple configuration. Add a circle.yml to the root of your source repository and you can configure all aspects of the build and deployment in the same place as the code is stored. Boom.
The second biggest win for us is the ability to automate tests of the code every single time it is pushed to the git repository. That helps us catch build problems early and get them resolved before they can cause problems for other members of the development team. We use nose2 for testing our Python projects. A failed test prevents the build from being deployed and sends a notification to Slack so problem can be resolved.
Finally, the thing that brings us the most joy, the thing that really makes us jump up and down with glee? Is the ability to script deployment to multiple environments based on branches. The develop branch deploys to the development environment, the staging branch deploys to the testing environment, and the master branch deploys to the production environment. Unlimited environments can be supported. So fabulous.
Romulus and Remus Revisited: Welcome to CircleCI
Let’s once again revisit our boys Romulus and Remus, but imagine that they have been using CircleCI for AGES and know how it will help them out!
Romulus spends some time during their first sprint setting up a development environment and writing some scripts to deploy to that environment. He integrates the deployment script with CircleCI so that every time someone commits to the develop branch, it runs all unit tests and, if they are successful, uses his deployment script to deploy the code to development environment.
Remus works with the development team to make sure that as they add new functionality, they also create new tests; those tests are maintained as a part of the overall development plan. These tests are run automatically, and Romulus configures CircleCI to post to Slack every time a build succeeds or fails, allowing team to respond immediately to build problems.
Looping the QA team in is as simple as configuring a new server and adding configuration to the deploy script to ensure that the QA branch is deployed to the new QA server. Code is only merged to the QA branch when it’s ready to be tested by QA. QA productivity — and morale — is high because they don’t have to deal with any broken builds.
Adding the production environment and a staging environment for the client is the same process as was followed for QA. It’s a fairly quick, one-time setup … instead of the ongoing process it was without the use of CircleCI.
In the end, Romulus and Remus’s team once again produce a high quality deliverable ahead of schedule because they were able to spend most of their time on writing and testing excellent code.
And That’s Amore!
No one loves repetitive, time consuming tasks. They are boring, and boredom leads to zoning out, which leads to mistakes. Tools like CircleCI allow repetitive tasks to become a one-time configuration and help to eliminate mistakes. Deployment automation means we produce better work faster, and that is something everyone loves.