Infrastructure as code tools

Mariusz Walczyk

01 Jun 2022.10 minutes read

Infrastructure as code tools webp image

A comparison of Infrastructure as Code tools as of 2022


Infrastructure as code has become a very important and popular part of software development these days. If your team is preparing applications that will be run on a cloud environment, sooner or later, you will need something that lets you describe your infrastructure and simplify setting it up.

In this article, I will explain Infrastructure as Code, describe the most important IaC tools, and compare main features of each of the tools.

What is Infrastructure as code?

First, I have to explain what Infrastructure as code is. Following Wikipedia:

Infrastructure as code (IaC) is the process of managing and provisioning computer data centers through machine-readable definition files, rather than physical hardware configuration or interactive configuration tools.

Simply speaking, you can write code to describe your servers, networks, databases and anything else you can imagine. With the correct tool you can then compare the current state of your infrastructure with your infrastructure code and make necessary changes in real infrastructure.

Brief history

Infrastructure as code grows with the expansion of Amazon Web Services and issues of large companies with the scaling of their infrastructure. Having the ability to design, implement, and deploy application infrastructure with IaC software become best practices appealed to both software developers and IT infrastructure administrators.

Why do you need Infrastructure as Code?

If you are still not sure whether to include infrastructure as code in your project consider a few benefits of using it. Infrastructure as code decreases risk, reduces costs, and improves consistency of environments for faster iterations. IaC also helps you with documentation because code, if created in a good fashion, can explain how your infrastructure works.

Tools not included in the comparison

There are many tools not included in this article. Most were created before the tools described here, and, in my opinion, they do not fit into the modern way of creating Infrastructure as code.

My criteria for choosing the items on my list were: a tool providing declarative language that mainly was developed to create cloud infrastructure. In this sense I skipped tools like: Ansible, Chef, Puppet, and Vagrant.

Best 2022 infrastructure as a code tools


Crossplane is an open source Kubernetes add-on that allows you to manage multi-cloud infrastructure, provision, compose, and consume infrastructure in any cloud service provider using the Kubernetes API.

You can create resources on the cloud using simple Kubernetes manifests and also integrate it with your CI/CD pipelines. Resources can be managed directly interacting with the API of Kubernetes, kubectl or even with GitOps tools like Flux CD or Argo CD.

Every Infrastructure as code tool needs to keep its state somewhere. In this case, the list of resources created by Crossplane is kept in the Etcd database inside the Kubernetes cluster.

Example of AWS S3 bucket creation:

kind: Bucket
  name: test-bucket
  namespace: default
  deletionPolicy: Delete
    acl: private
    locationConstraint: eu-central-1

Key features of Crossplane

Crossplane is developer friendly, so if someone has access to a Kubernetes cluster, they can add cloud resources by applying simple manifest. In many cases, it will increase productivity and speed of work but we have to keep in mind that costs of infrastructure can increase as well. I suggest closely monitoring your cloud infrastructure costs after introducing Crossplane.

Cloud resources may consist of multiple parts (like roles, permissions, VPCs) and it might be hard to declare all of them for developers. Here, another feature of Crossplane comes in handy - composition. With composition’s help, you can declare multiple resources and give end users a model (Crossplane Resource Model - XRM) to create more complex resources with simple api.


Infrastructure as code tools usually use json or yaml to define resources. Pulumi meets the need of IT technicians who already know one of programming languages like Javascript, Typescript, Python, Go or C# and want to use their favourite language to create infrastructure. Pulumi offers SDK to create resources for major cloud providers: AWS, Google Cloud, and Azure. Also, with Pulumi, you can integrate your favourite libraries to extend the capabilities of your Infrastructure as code even further.

Example of S3 Bucket creation with Pulumi and TypeScript:

import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";

const bucket = new aws.s3.Bucket("test-bucket", {
    Name: "test-bucket",
    acl: "private",
    tags: {
        Environment: "Dev",
        Name: "test-bucket",

With Pulumi and good knowledge of the language Pulumi supports, you can build very elegant code that can be understood by other developers. Unlike terraform for example, teams don’t have to learn another language. The only thing everyone needs to learn is cloud services, and then it’s enough that they follow the documentation from Pulumi.

Collaboration of multiple team members is possible because Pulumi supports keeping state in online storage solutions like AWS S3 bucket. However if you like to easily refer to outputs in other stacks, it’s better to use the Pulumi service. It allows you to simplify sharing state with others in your organisation and track changes made in your infrastructure.

The last very important piece of information about this tool is that Pulumi supports binary Terraform providers, which makes it an even more powerful tool.

Google Cloud Deployment Manager

All major cloud providers have their own way to create and manage resources. Google Cloud Deployment Manager, as the name suggests, is that kind of tool created by Google. It will help you declare Google resources as a YAML file.
If you are familiar with Google Cloud, you probably already have a tool installed to deploy a configuration file.

Example of Storage Bucket creation with Google Cloud Deployment Manager:

  - name: test_bucket
      name: test_bucket
      location: us-east1
        enabled: True
        env: development

Azure Resource Manager Templates

Azure Resource Manager Templates, known also as ARM templates, are usually a JSON file that defines a configuration of a project in Azure cloud. As other similar tools, it's a declarative way to set up your infrastructure.

ARM templates consist of a few general parts described below:

  • Schema definition - which define the version of template language used
  • Parameters - you can think of parameters like the input variables. With use of parameters you can specify important resource parameters depending on current project needs.
  • Variables - defines values that can be reused in your template. In addition you can construct them from parameters. As a terraform daily user I can compare them to locals.
  • Resources - here comes the essence of your infrastructure. All the resources like databases, virtual machines or load balancers can be set up here.
  • Functions - user defined functions can be used to simplify resource creation. For example you can make a function for preparing unique names for your resources.

However, don't expect a lot from this feature, there are multiple limitations you need to have in mind while using functions (for example functions can’t access variables or can’t call other user-defined functions).

If you are focusing entirely on Azure, ARM templates can be very useful for you because all new features come very early to this product. Also you can find multiple examples on how to create resources on Azure with ARM templates.

  "$schema": "",
  "contentVersion": "",
  "parameters": {},
  "variables": {
    "accountName": "accountname",
    "containerName": "containername"
  "resources": [
      "type": "Microsoft.Storage/storageAccounts",
      "name": "[variables('accountName')]",
      "apiVersion": "2018-02-01",
      "location": "westeurope",
      "kind": "BlobStorage",
      "sku": {
        "name": "Standard_LRS",
        "tier": "Standard"
      "tags": {},
      "dependsOn": [],
      "properties": {
        "accessTier": "Cool"
      "resources": [
          "type": "blobServices/containers",
          "apiVersion": "2018-03-01-preview",
          "name": "[concat('default/', variables('containerName'))]",
          "dependsOn": [
          "properties": {
            "publicAccess": "None"

AWS CloudFormation

Similar to Azure, AWS also has a tool to create infrastructure in the cloud. CloudFormation also refers to a cloud service that is responsible for provisioning your infrastructure code. The state of the object you created is also stored in the AWS service.

The benefits of using CloudFormation is that you have full access to the service without any additional costs, you pay just for resources you created and consume.

If you already worked with the Lambda function and serverless framework, you might have already seen CloudFormation. At the end of the serverless.yaml file defining your lambda function, you can find the resources section with CloudFormation code that can be used to create resources required by the Lambda function.

CloudFormation code can be defined in JSON or YAML format and consist of:

  • Version,
  • Description,
  • Metadata,
  • Parameters - where you can customize your template,
  • Mapping - to map keys to a corresponding named value that you specify in a conditional parameter,
  • conditions, which can be used when you want to reuse the templates,
  • Transform, which enables you to reuse template components,
  • Resources where you can finally define your resources,
  • Outputs, where you can define values that are returned and can be imported into other stacks and used to create other resources.

AWS CloudFormation S3 bucket creation example:

    Type: AWS::S3::Bucket
      BucketName: 'example-bucket-iaac-comp
    Description: 'The ARN of the bucket'
    Value: !GetAtt MyS3Bucket.Arn


If you found CloudFormation interesting but you feel better in languages like Java, C#, JavaScript, TypeScript, or Python, you might like this tool.
AWS CDK will help you generate project structure with the cdk cli tool (e.g. cdk init app --language typescript), and with predefined classes, create the resources you need. As we are working with general purpose languages, you can use all kinds of loops, functions, and variables to make the creation of resources easier and faster.

The state of your infrastructure is kept in an AWS service, so if you are already familiar with CloudFormation, it will be easy to debug and track your infrastructure changes.

Creating the famous S3 bucket is as easy as creating a bucket object:

import * as cdk from 'aws-cdk-lib';
import { aws_s3 as s3 } from 'aws-cdk-lib';

export class HelloCdkStack extends cdk.Stack {
  constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    new s3.Bucket(this, 'MyFirstBucket', {
      versioned: true


Finally, the most popular IaC tool. It's an open source project initially created by HashiCorp and actively developed by the community. As of writing this article, Terraform has 32K stars and 7,5k forks on GitHub, which proves its popularity.

Terraform has the biggest number of integrations among its competitors. You can find all major cloud providers as well as less popular ones like Alibaba Cloud or IBM Cloud. Terraform is not only supporting cloud providers but also many products like 1Password, MySQL, Helm or Active Directory so you can integrate them into your infrastructure. I listed some very different examples of providers to emphasize the versatility of Terraform.

If you would like to get to know other providers you can use with Terraform, please check the official list of providers. If you didn’t find the needed integration, it’s possible that it’s present on GitHub but it’s not official.
I won’t explain Terraform in detail, but you have to know that it’s based on the HCL2 language where you can define resources, providers, inputs, and outputs. The benefit of the HCL2 language is that it is both machine and human readable. In many cases, all you need to document your infrastructure is the HCL language itself and following good practices in the formatting and structure of the document.

As the last piece of important information about Terraform, I’d like to mention Terraform state. You can keep your resources state in local files as well as in an AWS S3 bucket, Azure Storage or Google Cloud Storage, depending on your project. It’s also worth mentioning that HasiCorp has a product named Terraform Cloud where you can store and share your state file with your coworkers.

Example of creating AWS S3 bucket with Terraform:

resource "aws_s3_bucket" "b" {
  bucket = "my-tf-test-bucket"

  tags = {
    Name        = "My bucket"
    Environment = "Dev"

resource "aws_s3_bucket_acl" "example" {
  bucket =
  acl    = "private"


As there are so many IaC tools, it might be hard to choose one. I think there is no one and only tool you should use. The decision on the right tool should be always preceded by an assessment of the project in terms of:

  • skills of people creating the infrastructure - it’s possible that you have skilled JavaScript developers, and they will prefer JS over HCL
  • project specific decisions - for example if you are planning to use the serverless framework, maybe it's worth to stick to CloudFormation as you will have to use it in serverless.yaml anyway,
  • scope of the project - if you plan to create heterogeneous infrastructure, you need to find tools that let you cover all types of resources needed.

I think that the above article will help you decide which IaC tool to use, because there is one undeniable truth: with the growth of your infrastructure, you will definitely need Infrastructure as code.

Blog Comments powered by Disqus.