Top Infrastructure as Code Tools and Terraform Alternatives
Tags: infrastructureascode, terraform, cloud, cloudcomputing
Published: 2024-04-18 11:05:28

Infrastructure-as-Code (IaC) allows engineers to manage cloud assets, databases, and networks as code, enhancing efficiency and consistency and bypassing manual ClickOps for cloud infrastructure provisioning and deployment.   
The key benefits of popular IaC tools like Terraform, OpenTofu, and Pulumi, include:

**Automation and Error Reduction:** Using IaC, you can automate the setup of a complex server environment in minutes with a single script, eliminating hours of manual configuration. This not only accelerates deployment but also significantly reduces the chance of human error.
**Version Control and Collaboration:** Enable version control to track changes and enhance team collaboration. For instance, when a team member submits a pull request for an IaC configuration change, the entire team can collaboratively review, discuss, and approve the IaC changes.
**Scalability:** By changing a few lines in your IaC script, you can effortlessly scale your cloud infrastructure to handle the increased load, transforming what used to be a complex process involving manual adjustments in your cloud environment.
**Multi-Cloud Support:** IaC tools are cloud-agnostic, meaning they offer flexibility in deploying infrastructure across various cloud environments (AWS, Azure, GCP, etc).
**Security:** IaC tools integrate with security frameworks like OPA, enabling engineers to define security policies and check compliance before (or after) the infrastructure provisioning process, ensuring infrastructure security.

In this post, I’ve selected a range of the most popular IaC tools to provide a quick overview of the ecosystem and help you find the IaC option best suited for your organization or project.


**Terraform CLI**
-----------------

[Terraform CLI](https://www.env0.com/blog/what-is-terraform-cli) is the most popular and widely used IaC tool today. Owned by HashiCorp, Terraform is designed to provision and manage infrastructure resources through code.

Terraform key features are:

*   **Multi-cloud Support:** Offers extensive multi-cloud support, enabling efficient infrastructure management across various platforms like AWS, Azure, GCP, and [env0](https://www.env0.com/), with the same tool and syntax.
*   **Declarative Syntax:** Terraform employs the declarative HashiCorp Configuration Language (HCL) to describe the infrastructure's desired state through IaC.
*   **State Management:** State management in Terraform uses a state file to track resources, serving as a source of truth for efficient updates, deletions, and metadata tracking.

### **Usage**

You should follow a series of steps to get started with Terraform:

#### **1\. Install Terraform**

You can download and install [Terraform](https://developer.hashicorp.com/terraform/install) on your local machine. It supports different operating systems like Windows, Linux, and MacOS.

#### **2.Write your first Terraform Configuration**

Create a new directory for your Terraform project and create a file named main.tf inside that directory. We'll take an example of writing the Terraform configuration for provisioning an S3 bucket in **main.tf**. Here is an example configuration:

```
    provider "aws" {
      region = "us-west-1"
    }
    resource "aws_s3_bucket" "my_bucket" {
      bucket = "env0-dev-bucket"
      tags = {
        Name        = "env0-bucket"
        Environment = "Dev"
      }
    }
    
```

This configuration:

*   Defines an AWS provider and sets the region where the resources will be created.
*   Defines a resource block for an AWS S3 bucket with a unique bucket name, sets the access control list (ACL) to private, and adds some descriptive tags.

#### **3\. Run Terraform Workflow (Terraform CLI in Action)**

You would now need to basic Terraform commands to provision this S3 bucket in AWS in the real world.

*   [`terraform init`](https://www.env0.com/blog/terraform-init)\: This command prepares your directory for Terraform operations by downloading the necessary provider plugins.

![terraform init](https://assets-global.website-files.com/63eb9bf7fa9e2724829607c1/65f1c5cb480c6af7d6006fb3_sVGrVdUJKC7I8qmpVydN5Pcm4T7B-Z0IMsXuriLsj42GMgDBbOc6jEnBURnva9FwIFfjkqLarIa_zAnuek7P5q0I86pnImC58DbkpZEjiL5unBkCTjiw9b062SJKythL6rfxUpMGUr17OlW8UcGfeps.png)

*   [`terraform plan`](https://www.env0.com/blog/terraform-plan): This command will show you a plan of all the resources Terraform will create, modify, or destroy based on your configuration. The `plan` output shows creating an S3 bucket (**env0-dev-bucket**).

![terraform plan](https://assets-global.website-files.com/63eb9bf7fa9e2724829607c1/65f1c5cba0bd119e66b1ba84_RGlWBuoHczE4a-Iy8Ubc5brPBWt3p47J48TgQvtcKCC8Wqbvgw3dgOk-u9SUm9PimOo1IOezjjqgB4zWeWwl3SCFKgpmyvFVYN9itg8xNPIuFIsS8GDUi-xS4xwDLmsHd7kjTNHVXSIW8J8wpIN7FXs.png)

*   [`terraform apply`](https://www.env0.com/blog/terraform-apply-guide-command-options-and-examples): If you're satisfied with the plan, apply the configuration to create the S3 bucket by running `terraform apply`. After confirming with a **‘yes’**, you’ll see the S3 bucket provisioned in your cloud environment.

![terraform apply](https://assets-global.website-files.com/63eb9bf7fa9e2724829607c1/65f1c5cb25f1f46088f54aae_H2UZJ-xEudYFmb1rPsFw2hOYjb4SQV_7T9EriS0rHcbiZn7B57mvSEg0HPCpH-KRjB6PoUGetc-ROd_J4y7KcHnyxRTxJZGgwrB3yw3MQyzQzlFaSlQ2UiaJ7CiIq86kPEXEECbVWzJ75UF4_BkLY0Y.png)

> ‍**Licensing  
> ‍**Recently, Terraform moved from Mozilla Public License (MPL) to Business Source License (BSL), confirming it will no longer be an open-source project. For instance, since HashiCorp moved from its open-source license, [the Gitlab community](https://gitlab.com/groups/gitlab-org/-/epics/12401) has rooted to replace Terraform CI templates with OpenTofu templates for SaaS and Self-Managed features in GitLab, since its internal legal analysis restricts shipping Terraform CI templates.


‍**OpenTofu**
-------------

**‍**[OpenTofu](https://www.env0.com/blog/opentofu-the-open-source-terraform-alternative) is an open-source alternative for Terraform and a drop-in replacement for Terraform v1.6. OpenTofu is forked from Terraform, and initiated by [env0](https://www.env0.com/), Gruntwork, Harness, Spacelift, and others as a response to [HashiCorp's shift from an open-source MPL license](https://www.env0.com/blog/hashicorp-license-change#:~:text=32K%20GitHub%20stars.-,%E2%80%8DAugust%2025th%2C%202023%3A%20The%20OpenTF%20initiative%20officially%20announces%20an,open%2Dsource%20fork%20of%20Terraform.&text=%E2%80%8D-,On%20August%2010%2C%202023%2C%20HashiCorp%20announced%20a%20change%20of%20license,non%2Dopen%20source%20BSL%20v1.) to the Business Source License (BSL) for Terraform.OpenTofu comes with all the features of Terraform, except that it is open-source. Moreover, OpenTofu has its own [registry](https://opentofu.org/registry/) that uses the same modules and providers that can be used with Terraform.

Key features:

*   **Open Source Nature:** OpenTofu's open-source nature ensures that its codebase is freely accessible to all, fostering a transparent and inclusive environment for users and developers.
*   **Community-driven Development:** OpenTofu's development is community-driven, emphasizing collaboration in feature suggestions, bug reporting, and documentation enhancements, making the process transparent and feedback-valued for users.

### **Usage**

You can get started with OpenTofu by just adding or replacing the Terraform binary with the OpenTofu binary, defining the configuration with the same HCL syntax, and running your workflow.

#### **1\. Install OpenTofu**

Follow the OpenTofu [installation guide](https://opentofu.org/docs/intro/install/) with respect to your operating system.

#### **2\. Define your OpenTofu configuration**

OpenTofu uses the same HCL syntax for defining your infrastructure code. Let’s take the same example of provisioning an S3 bucket:

```
    provider "aws" {
      region = "us-west-1"
    }
    resource "aws_s3_bucket" "env0_bucket" {
      bucket = "env0-tofu-bucket"
      tags = {
        Name        = "env0-opentofu-bucket"
        Environment = "Dev"
      }
    }
```

#### **3\. Run OpenTofu workflow**

After defining your configuration, run the same workflow as Terraform with some minor changes in syntax (replace `terraform` with `tofu` when running workflow commands).

*   `tofu init`: same as `terraform init` Initializes the directory by downloading provider plugins and modules.

![tofu init](https://assets-global.website-files.com/63eb9bf7fa9e2724829607c1/65f1cff3be319f6fa36b9a86_3Y__ltyPA0bKC1dqWgr4mG5frk-gXDdIs3RSQCxsK4InAHDuS6v7UpzVtrW22ioIwrxC0mRe9GqyvU0mn-tXl19mnP8tYvYTYW2CKAoL4QcjHL9iAeuZvkH-S2r-S7bzoggN0mmys-sVmg1j2FCQoiU.png)

*   `tofu plan`: Again, identical to the terraform command it Shows you an execution plan to modify, create, or destroy resources. In our case, we’re creating an S3 bucket.

![tofu plan](https://assets-global.website-files.com/63eb9bf7fa9e2724829607c1/65f1cff3339cd1efd50c0c53_O_lbvKMqVCpx4h9BRc_buXM2mMrLmfXZa4TGRcvRslWRUlaoTBnRJ_wxT06h2WuP5mJJappeYofZbEf1uDKjd8T0olbSvK_epuzbimm3PLIyqd6RJGeXqNISAV00ylvn7g8kEwitfuKPmX61V8DxemU.png)

*   `tofu apply`: After running the  command, Opentofu generates an execution plan again and asks for confirmation. Upon confirming with a **‘yes’**, it creates the **env0-tofu-bucket**:

![tofu apply](https://assets-global.website-files.com/63eb9bf7fa9e2724829607c1/65f1cff33d68be38e33a531f_gCcEBTwMSQInMSc8uxXnixDKgBFpe_1oOW9j4csDV2V3bWWhB_IH2woC0c7H7O6bK7vq5u81rCB8zdq8rwvMSCWLATLfpFZUWwmO1YrPtsrT3AAgBdpZ3zCsUCLBY9nwn_xaZxs0TqkxTx4nPjuG3fY.png)

> ‍**Licensing  
> ‍**OpenTofu is under the open source Mozilla Public License (MPL) and was acquired by the Linux Foundation.


**Pulumi**
----------

[Pulumi](https://www.env0.com/blog/what-is-pulumi-and-how-to-use-it-with-env0) is an open-source Infrastructure as Code (IaC) tool enabling engineers to manage cloud infrastructure with languages like JavaScript, TypeScript, Python, Go, and .NET, offering flexibility beyond traditional declarative-syntax IaC tools like Terraform.

Here are some of its key features:

*   **Multi-Cloud Support:** Like Terraform, Pulumi too offers a wide range of integration with various cloud providers like AWS, GCP, Azure, etc.
*   **State Management:** Pulumi automatically manages the state of your infrastructure, keeping track of your resources and their relationships.
*   **Secret Management:** Pulumi provides secure handling of sensitive information, such as passwords or API keys, integrating with existing secrets management tools like AWS KMS, Azure Key Vault, or HashiCorp Vault.

### **Usage**

#### 1\. Install Pulumi and create a project

There are different ways of installing Pulumi on your local system, and you can find everything [here](https://www.pulumi.com/docs/install/). You can follow along on [creating a Pulumi project](https://www.pulumi.com/docs/clouds/aws/get-started/create-project/) and get started writing Python code for provisioning an S3 bucket.

#### 2\. Write a script to provision infrastructure

Here's a basic Python script to deploy an S3 bucket:

```
    import pulumi
    from pulumi_aws import s3
    # Create an AWS resource (S3 Bucket)
    bucket = s3.Bucket('env0-pulumi-bucket',
                       tags={
                           'Name': 'Created by Pulumi',
                           'Environment': 'Dev'
                       })
    # Export the name of the bucket
    pulumi.export('env0-pulumi-bucket', bucket.id)
```

#### 3\. Deploy Stack

Run `pulumi up` to provision the S3 bucket (**env0-pulumi-bucket**):

![pulumi up](https://assets-global.website-files.com/63eb9bf7fa9e2724829607c1/65f1d2c56cb85ddebd8c4296_IucqGrDHpWrXs65p-zYN_5HdHHJXGxBeCPli-2S8Wid1uI6q_IMKVtvX2_S-Xf-AgH9isb9aD9YKbdjzssVldufmtJvE0Q85aZQSMHEKzugyrB_7pSAQ524rGLe-zqPz8KTr9RV-M2ZDT-V62x_JfK0.png)

![pulumi up](https://assets-global.website-files.com/63eb9bf7fa9e2724829607c1/65f1d2c587f09f2910564595_63-k8eOA_wwm0lJY8sHDiIk7gJElw8d--1pXUZMbj1GncGYpNpQ97n4MvgKH6O0qvGuubLOUEK5mQ2cd-JnAxM00EEms5rb2-zEFt7SMaSw1vEaTGhn5B8GiUwwtb8_80dPzq5hve1UBFNXNC4Kj7qw.png)

> **Licensing**  
> Pulumi is an open-source project licensed under Apache License 2.0.


**Crossplane**
--------------

Crossplane is an open-source Kubernetes add-on that makes cloud infrastructure management native to Kubernetes through custom resource definitions (CRDs), enabling provisioning and management of cloud resources directly from Kubernetes.

It allows you to define your infrastructure using Kubernetes manifests, making the entire cloud infrastructure a Kubernetes-native experience.

Key features:

*   **Universal Control Plane:** Crossplane makes Kubernetes a universal control plane with CRDs for cloud resources, simplifying multi-cloud infrastructure provisioning and management.
*   **Multi-cloud and Hybrid Cloud Support:** Crossplane supports multiple cloud providers (AWS, GCP, Azure, Alibaba Cloud, and more), enabling you to deploy workloads and services across different clouds, facilitating complex multi-cloud and hybrid cloud architectures.

### **Usage**

#### To provision an S3 bucket using Crossplane, we should have:

1.  An existing Kubernetes cluster running (preferably minikube or kind)
2.  Helm (to [install Crossplane](https://docs.crossplane.io/latest/software/install/))
3.  Configure the [AWS provider](https://docs.crossplane.io/latest/getting-started/provider-aws/)

After following all the prerequisites, I have defined a custom resource definition (CRD) to provision an S3 bucket below:

```
    apiVersion: s3.aws.upbound.io/v1beta1
    kind: Bucket
    metadata:
      generateName: env0-crossplane-bucket	    #random hash generated by crossplane
    spec:
      forProvider:
        region: us-west-1
      providerConfigRef:
        name: default
```

After running `kubectl apply` command on our CRD, we see that our bucket is provisioned:

![kubectl apply](https://assets-global.website-files.com/63eb9bf7fa9e2724829607c1/65f1d373eabbdf7525fcf132_NL1qixH3AlbvsBRF3t166dBTjY1izPsWWztkO2ofgxDSvJmrBG2G3AiSqioYudLonuAMfqz3D9VGCghvJYs1w2enPe09GYk0pLOASlNuCTMqQeW411hnEpCqZ0dImzB8--4ReNCKr3y2UBszElYwR4o.png)

> **Licensing**  
> Crossplane is open source and licensed under Apache License 2.0.


**Ansible**
-----------

[Ansible](https://www.env0.com/blog/ansible-vs-terraform-when-to-choose-one-or-use-them-together) is an open-source automation tool, or platform, used for IT tasks such as configuration management, application deployment, intra-service orchestration, and provisioning. Ansible uses a simple syntax written in YAML called playbooks.

Key features:

*   **Agentless Architecture:** No need to install any agents on the nodes to manage them.
*   **Idempotency:** Ensures that an operation will produce the same results if executed multiple times on the same system.
*   **Simplifies Complex Deployments:** Ansible's modular and scalable nature allows for the orchestration of complex multi-tier IT application environments.

### **Usage**

Taking an example to create an IAM using Ansible, you would typically use the `aws.iam_user` module. Here's a simple example of an Ansible playbook that creates an IAM user **env0-ansible-user**:

```
    ---
    - name: Create IAM user using Ansible
      hosts: localhost
      connection: local
      vars_files:
        - creds.yaml
      tasks:
        - name: Create a user
          amazon.aws.iam_user:
            name: env0-ansible-user
            state: present
            region: us-west-1
            aws_access_key: "{{ aws_access_key }}"
            aws_secret_key: "{{ aws_secret_key }}"
```

Run `ansible-playbook [playbook-name]`, in our case `iam-playbook`:

![ansible-playbook](https://assets-global.website-files.com/63eb9bf7fa9e2724829607c1/65f1d4bdd2ead5f79bca2914_JselD12Stbd322Qwt3bVsXZEghRV5oX8aCCsQ9O_bfVDi4_q9WCiHAYA9ODYE9LhP-ng13OGJTeJLwebhqOIDJ3XTUKkMrmsZdWJT8UeiASgOFzFubLGcMluzzPe43zMZ8kie31Sz6fivcZYze4HXAQ.png)

> **Licensing**  
> Ansible is open source and licensed under the GNU General Public License v3.0 (GPLv3). 


**Salt**
--------

SaltStack, also known simply as Salt, is an open-source configuration management and remote execution tool. It is designed to automate the management of infrastructure changes, software deployment, and configuration across a wide range of systems in data centers and cloud environments.

Key features:

*   **Configuration Management:** Employs a declarative, YAML-based language for idempotent state files, enabling simple, readable system state definitions with consistent outcomes on multiple applications.
*   **Remote Execution:** Efficiently executes commands across thousands of servers using ZeroMQ or SSH, with flexible targeting based on hostname, metadata, or custom grains.

### **Usage**

Install [Saltstack](https://docs.saltproject.io/salt/install-guide/en/latest/topics/install-by-operating-system/index.html), and make sure you have the latest [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) installed for provisioning AWS resources. After that, configure your AWS credentials.

Define your S3 bucket config in the **provision-s3.sls** file in **/srv/salt/** folder (make one, if it doesn’t exist) and make sure to uncomment the config below located in **/etc/salt/master** folder:

```
    file_roots:
      base:
        - /srv/salt
```
    

Here is the bucket config:

```
    create_bucket:
      cmd.run:
        - name: aws s3api create-bucket --bucket env0-salt-bucket --region us-west-1 --create-bucket-configuration LocationConstraint=us-west-1
        - unless: aws s3 ls s3://env0-salt-bucket
```
    

We provisioned the **env0-salt-bucket** by running the `salt-call` command:

![salt-call](https://assets-global.website-files.com/63eb9bf7fa9e2724829607c1/65f1d554eb938a8a2886dce0_6Az1Sp5Lmi9qdeN_joHyf998CZ33z6IFbiqsmSl8zYG9QUxUD6Pke5Mgf_PwW_8Pc-AK6V9bDlYq_Nxfk47JXauIDwEIem9adLFLjzrZnM_yjk9JQpdKrUK9D8pcPy8KV-1X3goaA7GIPbIxxsooGu4.png)

> **Licensing**  
> Saltstack, or Salt, is open source and licensed under Apache License 2.0.


**Chef**
--------

Chef is a powerful automation platform that transforms infrastructure into code, automating how infrastructure is configured, deployed, and managed across a network, regardless of size. It's especially popular in cloud and server management contexts, where managing large numbers of servers efficiently and predictably is critical.

Key features:

*   **Infrastructure as Code (IaC):** Chef uses Ruby to write infrastructure configuration, allowing for automation, versioning, and testing of your IaC.
*   **Automated Configuration:** Automates server configuration and maintenance for both small and large-scale environments, ensuring uniform system setup across any number of servers.

### **Usage**

Install [Chef Workstation](https://docs.chef.io/workstation/install_workstation/) and generate a cookbook. After that, navigate to the cookbook directory and start writing your recipe.

Here is a recipe written in Ruby to provision an S3 bucket using Chef:

We successfully provisioned **env0-chef-bucket**, running the `chef-client` command:

![chef-client](https://assets-global.website-files.com/63eb9bf7fa9e2724829607c1/65f1d5d2da4f3809bca97034_61CvLwUu3cvF9c1V-m067Mc-tpR2qhQ2Y8MvPo9TgCP8_1eVazYXUQ19dgqPMyz5lDMcwJSAX09ia_Zu-bG6F5-t_81PoccFnkrJg3bsoOzihX7_qMXj1V37C5qMqS9J_T8-UWi9olAevnaAJQaN86s.png)

This is the Chef automated dashboard in action:

![Chef automated dashboard](https://assets-global.website-files.com/63eb9bf7fa9e2724829607c1/65f1d5d2eb938a8a28874d5d_RUhrNyHE_e8yt5L5wFVXdoEZ_m1ZBJnam0xvHXcn0_C6NGCTAvptAKuzNw9Uy3r9wWGMBtnmNL1vF5bOoRfICp84vJ63UXGbNaKxttl6I_tgO7mxlLZGjWQY8h0D009yX5h_eqGAiDuFcai6zzGOUgA.png)

> **Licensing**  
> Chef is available under Apache License 2.0.


**Puppet**
----------

Puppet is a configuration management tool designed to automate the management of infrastructure across its lifecycle, from provisioning and managing infrastructure configuration, to orchestration and reporting

Key features:

*   **Automated Infrastructure Management:** Uses a declarative language (Ruby) to automate infrastructure setup and enable centralized control.
*   **Scalability:** Employs a master-agent architecture, enabling it to manage a large number of nodes from a central point.
*   **Security and Compliance:** Automates compliance enforcement and security management by monitoring and adjusting configurations to meet external regulations, internal policies, and applying security updates.

### **Usage**

You can write a Puppet manifest to provision an S3 bucket like below:

```
    s3_bucket { 'env0-puppet-bucket':
      ensure => present,
      region => 'us-west-1',
      bucket => 'env0-puppet-bucket', 
    }
```

We can visualize our infrastructure using Puppet Dashboard.

![Puppet Dashboard](https://assets-global.website-files.com/63eb9bf7fa9e2724829607c1/65f2fedc0acfee8ba5cca542_image-pup-ent-robust-automation.png)

> **Licensing**  
> Puppet is licensed under Apache License 2.0.


Frequently Asked Questions/FAQs
-------------------------------

#### **Q. What is the difference between Pulumi, Crossplane, OpenTofu, and Terraform?**

Terraform, OpenTofu, and Pulumi are Infrastructure as Code (IaC) tools designed to provision and manage cloud infrastructure, using HCL and popular programming languages (Python, JavaScript, .NET, etc.), respectively. 

In contrast, Crossplane is built specifically for Kubernetes, allowing you to manage infrastructure through Kubernetes CRDs, encompassing a wide range of major cloud providers and their services.

#### **Q. Which is better: Terraform or Ansible?**

Terraform specializes in provisioning immutable cloud infrastructure with a declarative model, tracking all resources. Ansible is best for configuration management and application deployment with a procedural approach, without tracking resources. You should choose based on your focus: infra-provisioning or management.

#### **Q. What is the difference between Chef, Puppet and Ansible?**

Puppet and Chef are both configuration management tools that use a master-agent model and a declarative language for system configuration, requiring a setup process for the master and agents. 

Ansible, on the other hand, is agentless, using SSH to connect and execute tasks in a procedural style, making it simpler to set up and use for ad-hoc task execution and automation.

#### **Q. What tools are competitors of Terraform?**

Different tools help us manage resources and automate infrastructure provisioning, like Terraform. Top competitors include OpenTofu (an open-source version of Terraform), Pulumi, and Crossplane, to name a few. Chef and Puppet, though competitors, are hard to install and configure and have more of a learning curve than Terraform.

‍