Infrastructure as code, also referred to as IaC, is an IT practice that codifies and manages underlying IT infrastructure as software. The purpose of infrastructure as code is to enable developers or operations teams to automatically manage, monitor and provision resources, rather than manually configure discrete hardware devices and operating systems. Infrastructure as code is sometimes referred to as programmable or software-defined infrastructure.
The concept of infrastructure as code is similar to programming scripts, which are used to automate IT processes. However, scripts are primarily used to automate a series of static steps that are repeated numerous times across multiple servers. Infrastructure as code uses higher-level or descriptive language to code more versatile and adaptive provisioning and deployment processes. For example, infrastructure-as-code capabilities included with Ansible, an IT management and configuration tool, can install MySQL server, verify that MySQL is running properly, create a user account and password, set up a new database and remove unneeded databases.
The code-based infrastructure automation process closely resembles software design practices in which development teams carefully control code versions, test iterations and limit deployment until the software is proven and approved for production.
Benefits of infrastructure as code
There are many benefits associated with infrastructure as code, from efficiencies of automation to its flexibility to align with other modern IT practices.
- Speed and efficiency. Automated provisioning and management are faster and more efficient than manual processes. This stretches not just to provisioned resources and virtualization, but also to databases, networking, user account management and other tied-in services. IaC also can include code that automatically scales (adds or shuts down environments and resources when they are no longer needed).
- Consistency. Software developers can use code to provision and deploy servers and applications according to business practices and policies, rather than rely on system administrators in a DevOps environment. A developer might create a configuration file to provision and deploy a new application for quality assurance or experimental deployment before operations takes over for live deployment in production.
- Alignment with DevOps. With the infrastructure setup written as code, it can go through the same version control, automated testing and other steps of a continuous integration and continuous delivery (CI/CD) pipeline that developers use for application code. An organization may choose to combine infrastructure as code with containers, which abstract the application from the infrastructure at the operating system level. Because the OS and hardware infrastructure are provisioned automatically and the application is encapsulated atop it, these technologies prove complementary for diverse deployment targets, such as test, staging and production.
Despite its benefits, infrastructure as code poses potential disadvantages. It requires additional tools, such as a configuration management and automation/orchestration system, that could introduce learning curves and room for error. Any errors can proliferate quickly through servers, especially where there is extensive automation, so it is essential to monitor version control and perform comprehensive prerelease testing.
If administrators change server configurations outside of the set infrastructure-as-code template, there is potential for configuration drift without the use of additional change management tools. It's important to fully integrate infrastructure as code into systems administration, IT operations and DevOps practices with well-documented policies and procedures. If legacy security and monitoring tools are not up to the task to handle infrastructure as code, this will require additional investments in more tools, with additional training and testing to integrate them into workflows.
Another challenge with infrastructure as code is that it places more responsibility onto developers to understand how to write efficient code that translates seamlessly into production environments. They must also have strong knowledge of languages used for infrastructure as code however an organization has implemented it, such as JSON, YAML, Ruby, C++ or SQL.
Infrastructure as code and cloud computing
Cloud computing shares a general starting vision with infrastructure as code: IT resources such as compute, storage and networking are abstracted from physical hardware, tied to additional services, and loaded into instances that are spun up and down as needed.
IaC takes this a step further, to automate this process through predefined sets of instructions:
- Provision resources.
- Configure the instance.
- Configure and deploy a workload into the instance.
- Connect associated services.
- Monitor and manage the deployment over time.
This depth of automation is especially important because of the cloud's vast array of applications, services and functions, stacked together and mainly connected through APIs. The scale and scope of cloud requires an automated governed process, rather than doing everything manually. Organizations with hybrid cloud benefit even more, as such templated configurations and resources can be applied across multiple environments.
Immutable vs. mutable infrastructure
Mutable infrastructure refers to the practice whereby infrastructure components are changed in production, while the overall service or application continues to operate as normal. Immutable infrastructure assembles and sets components and resources to create a full service or application. If a change is required for any component, they are not changed or reconfigured -- they are all updated and effectively redeployed in an instance. A new iteration is assembled, tested, validated and launched, while the old iteration is discontinued and its resources released for reuse.
Immutable infrastructure has gained favor particularly for cloud and microservices environments, which are highly scalable and involve many more interdependent components and services. Any one-off updates to address specific issues can cause configuration drift that cascades as updates are rapidly pushed to production. It's more efficient and effective to reissue sets of immutable services and components than to patch and reconfigure individual infrastructure components.
Infrastructure-as-code approaches and methods
Infrastructure-as-code tools can be declarative and imperative.
A declarative programming approach outlines the desired, intended state of the infrastructure, but does not explicitly list the steps to reach that state. SQL is a commonly known declarative programming language. AWS CloudFormation templates, among others, are written in the declarative style of infrastructure as code.
In contrast, an imperative approach defines commands that enable the infrastructure to reach the desired state. Object-oriented languages, such as C++ and Java, can be used for imperative programming. A tool such as Chef can be used in the declarative manner, but also imperatively as needed.
In both approaches, infrastructure as code is configured on a template, where the user specifies the resources needed for each server in the infrastructure. The template is used to either verify that a system is properly configured or put it in the appropriate setup. Templates can be constructed as a set of layers of resources, such as in AWS CloudFormation, which makes a stack.
Infrastructure-as-code tools configure and automate the provisioning of infrastructure. These tools can automatically execute the deployment of infrastructure, such as servers, with orchestration functionality. They also can configure and monitor previously provisioned systems.
Infrastructure-as-code tools enforce the setup from the template via push or pull methods. In the push method, a centralized server sends the desired configuration to a specific system or systems. The pull method is initiated by a request to a centralized server from a system or systems in the infrastructure. Tools typically are designed by default for push or pull deployment of code, but can be set up for specific instances to do the other. These tools should also be able to roll back changes to the code, as in the event of unexpected problems from an update.
Examples of infrastructure-as-code tools include AWS CloudFormation, Red Hat Ansible, Chef, Puppet, SaltStack and HashiCorp Terraform. Some tools rely on a domain-specific language (DSL), while others use a standard template format, such as YAML and JSON.
When selecting a tool, organizations should consider the target deployment. For example, AWS CloudFormation is designed to provision and manage infrastructure on AWS, and it works with other AWS offerings. Alternatively, Chef works with on-premises servers and multiple cloud provider infrastructure-as-a-service offerings.