The IaC platform you choose is critical. If your goal is to use standard software engineering tools and practices that are already in place, then look for the following qualities when you evaluate your choices.
Support for standard languages means that your developers can define and configure infrastructure using the same languages used to write application code. For example, common languages like TypeScript, Go, Python, and C#. Many older IaC tools have their own domain-specific language (DSL), and these can be problematic. Developers often find that common programming constructs are missing.
The platform you choose should allow engineers to easily create strongly typed, structured configurations and to use features they’ve always relied on such as loops, constants, and functions. Another advantage to using standard languages is, of course, that the developers already know it. They can begin coding right away. Learning the idiosyncrasies and limitations of a DSL can be time-consuming and frustrating.
Standard Development Tools
Using standard programming languages means that you can also use standard development tools such as IDEs. One advantage is, again, familiarity. Developers can work in an environment they already understand. The other is that developers can work in environments designed to help them easily author, debug, test, and deploy code.
It’s important that infrastructure is tested thoroughly, just as applications are. A modern IaC platform should support standard testing frameworks and it should also help your teams to expand the types of tests they perform.
Standard ops testing focuses on acceptance tests. That means the ops team spins up infrastructure in the cloud and they then test that infrastructure to see if it’s correct. Of course, if it wasn’t spun up correctly, the team needs to destroy and redeploy it. That’s not an optimal approach because, potentially, something that shouldn’t have happened already has, depending on how quickly the team reacts. A modern IaC platform should help your teams “shift risk left” through frequent testing before and during deployment. If they’re not already performing them, here are the types of tests your teams should be able to perform with a modern IaC platform.
Unit tests evaluate the behavior of your infrastructure in isolation. External dependencies, such as databases, are replaced by mocks to check your resource configuration and responses. It’s possible to use mocks because responses from cloud providers are well known and tested. You already know how, given some parameters, the provider will respond.
Unit tests run in memory without any out-of-process calls, which makes them very fast. Use them for fast feedback loops during development. Unit tests really help you solve problems early in the lifecycle of your infrastructure.
Integration testing (also known as black-box testing) comes after unit testing, and it takes a different approach. Integration tests deploy cloud resources and validate their actual behavior — but in an ephemeral environment. An ephemeral environment is a short-lived environment that mimics a production environment. It’s often simpler and only includes the first-level dependencies of the code you’re testing. Once the integration tests are finished, you can destroy the ephemeral infrastructure.
Too often, security tests are left until the last minute, or code that’s considered “finished” gets thrown over the wall to a security team, who’ve been left out of the entire development process. The phrase “courting disaster” comes to mind when considering this approach.
First, a modern IaC platform should encrypt sensitive configuration data. It should also make it easy to follow standard security practices such as key rotation. Check to see if the platform you’re evaluating encrypts state metadata and ensures that secret values are never exposed in plain text. The platform should also integrate easily with security services offered by the cloud providers.
In addition, as with other types of tests, the IaC platform should help you include security tests that you write yourself into your workflow. Just as you start testing your code early with unit tests, so should you start testing early to find security problems. Those tests belong in your CI/CD pipeline, so the infrastructure is thoroughly tested for vulnerabilities before it’s released.
Creating Reusable Components
Reusable components mean you build higher level resources out of individual ones. With them, you can create useful abstractions that can be reused in other places. These components can be written with your company’s best practices built in, tested, and shared within the company and with the community. Using reusable components helps to create repeatable, reliable infrastructure. Look to see if the platform you’re considering helps you create these components easily.
Standard Package Managers
If you want to create reusable components, you’ll need a way to package them so you can share them easily. Along with using standard tools, you’ll want support for standard package managers. For example, you might want to put your component into a GitHub repo and publish it through NPM. Your IaC platform should make that a simple task.
Central visibility across all infrastructure resources, with an historical view of past changes, is important both for accountability and collaboration. Your platform should give you visibility across your infrastructure by supporting audit logs and the ability to see diffs when cloud resources change (similarly to how teams use collaborative tools such as Git). Additionally, the platform should allow you to set fine-grained controls so you can control who can access and change your infrastructure.
Support for Multiple Cloud Vendors
Not every company wants to use multiple cloud vendors but it’s something you should consider. Do you want to leave that option open? If so, look for an IaC platform that won’t lock you into a single provider.
Policy as Code
Another too-often ignored facet of IaC is policy as code. A modern IaC platform should allow you to apply software engineering principles and approaches to your policies, just as it does with infrastructure. The benefits for policy as code are much the same as they are for infrastructure. Policies continuously enforce your organization's cloud governance in terms of security, compliance, and cost controls. Policies are unambiguous, they can be written with standard languages and tools, they can be versioned, tested, and finally integrated into the CI/CD pipeline so all infrastructure follows the company’s best practices.