I’m a continuous deployment advocate, and I hope you are, too. I’m not pitching CD in this post because I think the benefits speak for themselves. What I want to examine today is how to build strong continuous deployment pipelines.
Containers and orchestration solutions such as Kubernetes immediately come to mind since they’re today’s default target. The industry is moving towards containers, but adopting these technologies does not make sense for every single team in all circumstances. You may not need containers. There are other options and some, frankly, are simply better alternatives.
My position is simple. Teams should deploy correctly behaving code as quickly and reliably as possible. Technologies should move teams closer, not farther, from this goal. Achieving this goal requires automating many tasks, building multiple stages (or “environments”, such as staging, UAT, etc.), and mechanisms for deployments or promotions. Teams are increasingly coordinating their process via ChatOps (for many good reasons I won’t get into here). So the question is: what set of technologies provide continuous deployment with minimal friction?
The Answer Is Not Containers
Container-based infrastructure stacks tend to be bespoke, meaning they are customized for particular uses. This will change over time as better standard tools rise to the top. However, this is not the case today. Kubernetes seems to have, just recently, claimed the position of the orchestration solution.
Building off-the-shelf components that integrate with various container infrastructure components is difficult. The problem becomes more complex when considering distributed containerized applications, which lead to an entirely new set of concerns such as packaging (e.g. Helm for Kubernetes) and coordination (such as service A, followed by service B, then everything else), let alone how those concerns map to implementations on multiple different platforms (such as Kubernetes, DCOS, or Docker Swarm). These problems are not unique to containers, but they seem to amplify given the flexibility containers provide.
Here’s an exercise for a greenfield containerized application. Allot yourself one hour. Try building a CI pipeline that can deploy to some orchestration with the process controlled by ChatOps. It may be paid or free. Can’t do it? Perhaps you’re befuddled by all the considerations (don’t forget to set up a registry, authenticate, push images, then push into some infrastructure). Perhaps you could make it work if you had a day or two. Perhaps you simply cannot find the relevant tooling. I would guess the issue is this: there simply isn’t off-the-shelf technology (FOSS or proprietary).
My goal here isn’t to disparage the container platform. It’s to illuminate the assumption that building a continuous deployment pipeline with containers is accessible and easy enough for teams using containers.
There Are Better Options
Heroku Flow provides an entire workflow from commit to production. It integrates seamlessly with GitHub and Slack. Merged PRs may be automatically deployed to Heroku or the process may be controlled ChatOps style via Slack. Heroku flow bundles up CI, one-off review applications, and environment promotion. This is largely good enough for anyone using Heroku and perhaps even tempting enough to bring people to Heroku. It’s also free. Nothing as slick, integrated, or turn-key exists for containerized stacks. Heroku can also run Docker applications, but their CD support is limited. This is likely fine because you don’t need containers if you’re targeting Heroku. Remember, don’t assume you need containers in the first place.
GitLab offers similar features, but with much more flexibility. Their current CD offering combines CI, Review Apps, and deployment integrations based around GitLab. However, ChatOps support is notably lacking. Setting this entire stack up requires much far leg work on your behalf. It’s not a single button configuration by any means. However, it does provide flexibility for those of you who need containers, or simply want more control over how things happen.
GitLab also has an Auto DevOps in beta. Auto DevOps is container-native in that it uses Helm and Kubernetes for the entire CD lifecycle. However it’s doesn’t expose the full power of Kubernetes. Instead it opts to use Heroku buildpacks to build compliant Docker images that run on Kubernetes. You get these features all for the small price of understanding all the components and ceremony that come with them. Also, ChatOps integration is notably missing from the beta, so maybe–just maybe–it may come with the production release.
Projects like Keel.sh attempt to bridge the gap. Keel provides a step in the process, but not the entire chain. It also integrates with Slack and provides integration with Kubernetes directly or via helm. Careful though: the project is in its early days, so you’ll rely on maintainers to fix bugs or take that responsibility on yourself.
These projects are not the only things on offer. A quick search yields many options. Of course, some are more full-featured than others. That should matter to you because less complete options require your team to fill in the gaps, thus diverting focus from their prime objective: delivering business value. Don’t get distracted by the new shiny technology.
All software teams share the lead time KPI. Lead time is how long it takes to go from idea to production including all forms of process machinery. The business benefits when lead time decreases, since that means more frequent deploys, thus more changes presented to the customer. It’s wise to evaluate infrastructure technology’s impact on this metric. Sure the team can adopt containers for production, but what about all the machinery to get them there and achieve continuous deployment?
Teams must consider the entire pipeline. Assuming one technology will work seamlessly throughout the pipeline is troublesome–especially containers. I suggest you keep an open mind in asking what set of tools provide the best deployment pipeline with minimal friction and appropriate integrations. Don’t be afraid to shy away from containers. You may not have needed them in the first place.