Eric has worked in the financial markets in New York City for 25 years, developing infrastructure for market data and financial information exchange (FIX) protocol networks. He loves to talk about what makes teams effective (or not so effective!)
Configuration as code (CAC) is managing configuration resources in your source repository. You treat your application config resources as versioned artifacts. By managing your application environment in tandem with your application code, you gain the same benefits you get with your code. CaC is a set of processes and practices that will save you time, increase your flexibility, and improve your system uptime.
In this post, I’ll explore what you need to know about configuration as code. If you’re planning to put CAC in place, it will help you make informed decisions. If you’re not, my goal is to convince you to use it.
Configuration as Code vs. Infrastructure as Code
Some treat CAC and infrastructure as code (IAC) as the same thing. They’re not, and there’s a reason we have two distinct terms.
Infrastructure as code (IAC) is the managing and provisioning of infrastructure through code instead of using a manual process to configure devices or systems.
IAC is a process for managing infrastructure. It’s a process for managing tools like Puppet, Chef, Terraform, and Amazon’s Cloud Formation. As we discussed here, IAC has its own set of responsibilities and practices.
Configuration as code is a process for managing application configuration data. Depending on how you view your infrastructure and use your management tools, these areas may overlap. But CAC and IAC manage two different aspects of your environment.
What is Configuration as Code?
Here’s the most concise definition of CAC I can find. I paraphrased it from where it appears in one of the illustrations in that post.
Configuration as code is the formal migration of config between environments, backed by a version control system.
There’s a lot packed into that sentence.
First, you check your configuration into version control. This is a significant step for people who handle configuration “out of band.” I’ve worked on systems that archived configs as tarballs. Then they copied them to each environment and edited to fit. I’ve worked on others that shipped no configs and referred you to documentation. My personal favorite was watching an engineer migrate configs between terminal sessions—he copied and pasted them for every release.
With CAC you migrate your configurations in your release pipeline, alongside your application code. If you need to change a setting, you treat it like any other code change. Depending on your system, you branch that change. You test it in each environment and then merge it back into the pipeline for production.
Configuration as code means precisely what it says; you’re treating your configs as if they were code.
Rules for Configuration as Code
When it comes to formal descriptions of how to use CAC, there’s not a lot out there. But, we can look at how we manage configurations and how we handle source code. Then we can identify a set of principles for implementing configuration as code.
CAC Isn’t Shipping Apps With Configs
A shallow reading of configuration as code might lead you to add a configs folder to your release package and throw in the files. That approach would be wrong and dangerous.
That solution means that a configuration change requires a release of the application. This meets the goal of adding an audit trail for configs but muddies the water by mixing them with code changes. If a new feature requires both a code and configuration change, this might make sense. But what if you’re only changing the configuration? What if you’re just increasing a cache setting in production?
You’ll want to test this in at least one of your pre-production environments. You also want to check against the current release of code. Then, after you’re sure it’s going to work, you’ll want to promote the change. CAC gives you the traceability you need. You can look at your config repo, find the change, and see exactly what happened.
What if you need to back out a code change but keep a configuration that came after it in the release stream? Now you’re dealing with source control merges or patches. Keeping configuration in separate repositories allows you to release and roll-back separately. It’s easier to synchronize them when needed than it is to decouple them on demand.
CAC Isn’t Shipping Containers With Configs
If you’re using containers, you can start baking your configurations into them. That’s configuration as code, right?
No. No, it’s not.
First, this sets up the same situation as above. Any configuration change requires a new release of the container. So, even if you’re maintaining the configs and code in different places, combining them in the container creates an unnecessary dependency.
Second, now your containers are brittle. If you only have one environment or if all your environments look the same, this might not be a problem. But when it comes time to add a new environment or migrate to a different cloud provider, the first thing you’ll need to fix is your build process.
CAC is Maintaining a Separate Pipeline For Configuration
Configuration as code means maintaining a separate release pipeline for configuration. You migrate configuration between environments as a distinct artifact. It’s tracked separately, and you can reason about it as a discrete entity.
If a configuration change fails, you can roll it back independent of other releases. If it is dependent on another version, or another release relies on it, the relationship is clear and unambiguous.
You do this with the configuration data in the same repository as the application. While it’s better to keep them separate, it’s still possible to commingle them in VCS if you are mindful of how you manage the repository. You need to make sure that your configurations are stored in distinct commits and tagged as such.
Guidelines for Implementing Configuration as Code
Simplify Configuration Data
When configurations become a managed resource that you migrate across all your environments, simplicity is a gift. The goal is to identify that configuration during development and have it remain consistent. This used to be almost impossible, but containers make it not just possible, but natural.
Take Advantage of Version Control
Many technical concepts have unfortunate names. (I’m looking at you, “inversion of control.”) But configuration as code is what it says it is. Your configuration data, whether it’s YAML, XML (might want to rethink that), JSON, or input for a tool like Helm, is now code. You will treat it the same way you treat your source.
So, branch, tag it, perform pull requests, review it, and merge it to master. Apply whatever process you’ve been using for your application code to your configurations. Don’t carve out any exceptions for it.
It’s Not Either IAC or CAC. It’s Both.
I started out contrasting configuration as code with infrastructure as code because there’s a significant difference. But they’re not mutually exclusive. They can work together to give you unparalleled control over your environments and ability to respond to change. Take advantage of them both.
Make the Move to Configuration as Code Now
We’ve covered what CAC is and what it’s not. It’s a process for managing how you set up your applications in each environment as it moves from development into production. With it, you have a valuable mechanism for managing application config and responding to change. Without it, you might be flying blind.
Rollout has added new CAC features to their platform. You can use them to track your feature toggle changes in tandem with your existing config. Sign up for a trial today!