Terraform

Pulumi vs. Terraform : Key Differences and Comparison

Terraform vs. Pulumi

Cloud-native applications embrace the widely accepted practice of Infrastructure as Code, or IaC. IaC applies software development practices to the management of infrastructure, i.e., networks, virtual machines, load balancers, etc. 

Applying software development techniques to managing infrastructure provides several benefits, including versioning using a repository like GitHub and streamlining provisioning and maintenance by creating repeatable processes. Code reviews and audits can be done to ensure changes to infrastructure are correct and won’t introduce errors. 

With IaC, infrastructure becomes reproducible in a consistent manner and can be included in a CI/CD deployment pipeline. IaC is scalable and helps to eliminate human error.

Many IaC tools are available to facilitate the provisioning of cloud-native applications across all the major cloud platforms. Terraform and Pulumi are two such tools. In this article, we’ll take a look at both and provide a comparison between them.

We will cover:

  1. What is Terraform
  2. What is Pulumi
  3. Feature comparison with examples
  4. Terraform or Pulumi: which is better?

What is Terraform

Terraform, is an open-source tool created by Hashicorp. It is probably the most well-known IaC infrastructure provisioning tool. Terraform is cloud-agnostic and allows automating infrastructure stacks from multiple cloud service providers simultaneously. Terraform uses its own domain-specific language called Hashicorp Configuration Language (HCL).

Terraform uses “plans” to validate the configuration and display exactly what elements are going to change before the changes are applied. For a detailed look at plans, check out our introduction to Terraform plan.

Note: New versions of Terraform will be placed under the BUSL license, but everything created before version 1.5.x stays open-source. OpenTofu is an open-source version of Terraform that will expand on Terraform’s existing concepts and offerings. It is a viable alternative to HashiCorp’s Terraform, being forked from Terraform version 1.5.6. OpenTofu retained all the features and functionalities that had made Terraform popular among developers while also introducing improvements and enhancements. OpenTofu is the future of the Terraform ecosystem, and having a truly open-source project to support all your IaC needs is the main priority.

What is Pulumi

Pulumi is an IaC tool that uses a declarative format to deploy infrastructure. Like Terraform, it is open source on GitHub and is free to use. It offers the ability to use any major development language in the creation of infrastructure template files. Pulumi, like Terraform, supports all of the major cloud providers.

Read more in our Pulumi introduction and check out our Pulumi pricing overview.

Feature comparison between Pulumi and Terraform

Pulumi and Terraform are both software tools that automate the management of cloud computing infrastructure using code and templates. They help businesses provision and configure servers, storage, databases, and networks without manual intervention or hardware controls. 

They store the documented configurations in version control systems that ensure consistency and reduce turnaround time. They support DevOps and NetOps practices, enabling agility, scalability, and resilience. They can be cloud-specific or cloud-agnostic, depending on the provider and the environment. 

The following table lists the key differences between Pulumi and Terraform:

pulumi vs terraform table comparison

Let’s take a deeper look into each of the differences listed above with examples.

1. Language Support

Terraform’s HCL is JSON-compatible and is used to create the configuration files that describe the infrastructure resources in the stack. It uses proprietary syntax for common programming constructs like conditionals and loops. Terraform recently released the beta of a development kit that allows you to use programming languages that compile to HCL. 

Here’s a look at a typical Terraform configuration file created using HCL to provision an Azure Resource Group.

terraform {
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "=3.0.0"
    }
  }
}

variable "region" {
  description = "Azure location for the resource group"
  type        = string
}

provider "azurerm" {
  features { }
}

resource "azurerm_resource_group" "iac" {
  name     = "rg-iac-example-centralus"
  location = var.region
  tags = {name: "iac-test"}
}

Pulumi supports familiar programming languages like TypeScript, JavaScript, Python, Go, and C#, among others. This flexibility allows you to write your templates in the language you are most comfortable with. Pulumi will also convert HCL configurations into Pulumi templates.

This reference provides a document listing Terraform terminology and command equivalents in Pulumi.

A Pulumi template file written in C# to create the same Resource Group in Azure looks like this:

using Pulumi;
using Azure = Pulumi.Azure;

class MyStack : Stack
{
    public MyStack()
    {
        var config = new Config();
        var region = config.Require("region");
        var iac = new Azure.Core.ResourceGroup("iac", new Azure.Core.ResourceGroupArgs
        {
            Location = region,
            Tags = 
            {
                { "name", "iac-test" },
            },
        });
    }
}

2. IDE Features

Plugins for Terraform are available for some IDEs like VS Code. IDE integration is limited to the capabilities of the plugin itself. 

Pulumi’s support for common programming languages means you get the rich IDE integration that comes with the language you choose. For example, when using C#, Visual Studio provides code completion, strong data types, intellisense, etc.

3. Open Source Licenses

Terraform uses the Mozilla Public License 2.0. Pulumi uses the Apache License 2.0. There are differences between each licensing model. Your use case will determine the license that is appropriate for you.

4. Testability

Pulumi’s support for common programming languages like C# allows you to perform unit tests on your IaC templates using .Net test tools like xUnit. Pulumi also provides the ability to perform tests that mock external calls.

Terraform supports integration testing. The plan command shows the proposed infrastructure changes before they are applied, allowing you to review the changes prior to their execution. There are also commands to validate and format a configuration file.

Robust integration testing can be performed using third-party tools like Terratest, which is a Go library that enables you to write automated tests for infrastructure code. It provides many helper functions and patterns for common infrastructure testing tasks such as unit testing, integration testing, end-to-end testing, dependency injection, testing parallelism, retry logic, error handling, and static analysis.

5. Cloud Provider Support

A resource provider handles communications with a cloud service to manage the infrastructure resources defined in IaC configurations.

Both tools support all the major cloud services. Terraform has a community of developers writing custom providers for a myriad of services. Navigating their provider registry you’ll find provider support for services like Ansible and Atlassian. New cloud services aren’t always available to deploy using Terraform on day one.

Pulumi supports over 60 of the major cloud services. They also create “Native” providers for AWS, Azure, Google, and Kubernetes, which receive same-day support with every new release. The Pulumi registry provides detailed information for each provider they support. Also of note, Pulumi is able to adapt Terraform providers, so you can use the custom providers created by the Terraform community in your Pulumi templates.

6. State Management

IaC tools store metadata about your infrastructure so that it can manage your cloud resources. This metadata is called _state_. Both Terraform and Pulumi offer a desired state model where the code represents the desired infrastructure state, and the tool compares this desired state with the stack’s current state to determine the resources to be created, updated, or deleted.

By default, Terraform stores the state locally in a file named terraform.tfstate. Terraform state can be stored using a centrally located file, i.e., Azure blob container. This is the recommended configuration for the state file. Storing state in a centrally located file provides for backup and recovery scenarios and allows larger teams to collaborate and manage infrastructure with shared state.

In contrast, Pulumi stores its state in the Pulumi Cloud by default. Pulumi’s use of common development languages allows state to be compared as a “diff”, like how code is compared and reviewed across versions.

7. Secrets Management

The management of secrets, e.g., database credentials, API keys, etc., in code can become a security risk.

Terraform manages secrets through a separate product named Vault. Vault enables the management secrets without the need for developers to have direct access to the secrets. Vault encrypts the values it stores. It can be deployed as a SaaS or run locally as a service. Variables marked as “secret” will be excluded from an output unless the secrets command line argument is provided.

terraform output secrets

It is important to note that Terraform state files store secrets in plain text. Because of this you should restrict access to the state file to only those with the appropriate level of authorization. A recommended best practice is to always encrypt your state file to prevent accidentally leaking sensitive information.

Learn more about Terraform secrets management and best practices.

As mentioned above, Pulumi stores secrets in state in the Pulumi Cloud. You can also choose your own provider to store your secrets. Pulumi always stores and transmits secrets securely. It also supports encrypting sensitive data for extra protection. Configuration settings can be encrypted via the CLI command config set with the --secret flag. Secrets can also be set during runtime.

8. Infrastructure Reuse

A development best practice is to avoid duplicating code. The same practice applies to IaC. The ability to reuse configurations lowers the overall overhead involved with managing infrastructure.

Terraform provides a library of reusable modules. A Terraform module is comprised of a collection of .tf and/or .tf.json files stored in the same folder. Modules are the main way to package and reuse resource configurations with Terraform. Modules can be referenced from a public online registry or your own local module library.

Since Pulumi uses common programming languages, structures like classes, functions, and packages are reusable. Pulumi also provides a searchable registry where you can find packages that can be installed directly into your project. You can also create your own library of reusable packages.

Terraform or Pulumi: which is better?

As in most decisions in software development, the answer is – it depends. Pulumi’s native language support is its biggest advantage. By using native languages, you can embed IaC code directly within your application, perform unit testing, and reduce the learning curve by using a familiar language. This would be most important to developers who are new to DevOps. IT administrators with little coding experience will probably prefer the simplicity of HCL. 

Bottom line, if the prospect of having to learn a proprietary language like HCL scares you, or if you think you’ll need to integrate your IaC deployments within your application, choose Pulumi. Otherwise, go with Terraform.

Either way, there is no wrong choice with Terraform or Pulumi. Both are more than capable of meeting your IaC requirements.

Key Points

If you are looking to manage infrastructure as code, Spacelift is the way to go. It’s a continuous integration and deployment (CI/CD) platform that supports Git workflows, policy as code, programmatic configuration, context sharing, and many more great features. It currently works with both Terraform and Pulumi, also supporting AWS CloudFormation, Kubernetes, and Ansible. You can test drive it by creating a free trial account.

You can also use Spacelift to mix and match Terraform, Pulumi, and CloudFormation Stacks and have them talk to one another. For example, you can set up Terraform Stacks to provision required infrastructure (like an ECS/EKS cluster with all its dependencies) and then connect that to a CloudFormation Stack, which then transactionally deploys your services there using trigger policies, and the Spacelift provider run resources for workflow orchestration and Contexts to export Terraform outputs as CloudFormation input parameters.

The most flexible management platform for Infrastructure as Code

Spacelift is a flexible orchestration solution for IaC development. It delivers enhanced collaboration, automation and controls to simplify and accelerate the provisioning of cloud based infrastructures.

Start free trial