Comparing Terraform, Pulumi, and Crossplane: A Comprehensive Guide to Infrastructure as Code Tools

Andreas Leicher
kotaicode
Published in
5 min readAug 30, 2024

Infrastructure as Code (IaC) has become a cornerstone of modern cloud computing, allowing teams to manage and provision infrastructure through code rather than manual processes. Among the plethora of IaC tools available, Terraform, Pulumi, and Crossplane stand out as powerful options, each with its own unique approach and philosophy. This article delves into these three tools, comparing their methodologies, strengths, and weaknesses, and providing code examples to help you understand how they operate in real-world scenarios.

Photo by Christopher Gower on Unsplash

Understanding the Basics: Terraform, Pulumi, and Crossplane

Terraform and Pulumi: Similar Goals, Different Approaches

Terraform and Pulumi are both designed to define and manage cloud infrastructure, but they differ significantly in how they achieve this goal.

  • Terraform uses HashiCorp Configuration Language (HCL), a domain-specific language tailored for infrastructure management. It is widely adopted due to its simplicity, readability, and large ecosystem of providers.
  • Pulumi, on the other hand, takes a more developer-centric approach by allowing infrastructure to be defined using general-purpose programming languages like JavaScript, TypeScript, Python, Go, and C#. This allows developers to leverage existing skills, integrate infrastructure as code with application code, and use familiar programming constructs such as loops, conditionals, and functions.

Crossplane: A Different Philosophy

Crossplane stands apart from Terraform and Pulumi by embracing a different philosophy rooted in Kubernetes. While Terraform and Pulumi are imperative tools that rely on explicit commands to provision infrastructure, Crossplane operates declaratively within a Kubernetes environment. It uses the concept of continuous reconciliation, where the desired state is maintained automatically by the Kubernetes control plane.

This approach aligns with Kubernetes’ native operations, making Crossplane an attractive option for teams already invested in Kubernetes. However, it also requires a Kubernetes cluster to operate, which adds a layer of complexity compared to Terraform and Pulumi.

Key Differences and Similarities

Reconciliation: Continuous vs. Rollout Processes

One of the most significant differences between these tools is how they handle reconciliation — the process of ensuring that the actual state of infrastructure matches the desired state defined in code.

  • Crossplane leverages Kubernetes’ continuous reconciliation model. Once you define the desired state, Crossplane ensures that the actual state continuously aligns with it, without the need for explicit rollouts.
  • Terraform and Pulumi, by contrast, rely on a rollout process. After defining the desired state in code, you must execute a command (terraform apply or pulumi up) to provision the infrastructure. This action reconciles the infrastructure with the defined state at a specific point in time but does not continuously monitor or update it.

Extensibility Through Providers

All three tools support extensibility through providers, which are plugins or extensions that allow the tools to interact with various cloud platforms, services, and APIs.

  • Terraform boasts a massive ecosystem of providers, making it one of the most versatile IaC tools available. Providers are written in Go and can be maintained by either HashiCorp or the community.
  • Pulumi also supports a wide range of providers, and it allows for custom provider development using general-purpose languages, which can be more accessible for developers.
  • Crossplane uses Kubernetes Custom Resource Definitions (CRDs) and controllers to extend its functionality. This Kubernetes-native approach makes Crossplane highly modular and extensible, but it requires familiarity with Kubernetes concepts.

Programming Language Support

  • Terraform uses HCL, which, while powerful and well-suited for infrastructure definition, is a domain-specific language. This means developers need to learn HCL in addition to their primary programming languages.
  • Pulumi allows you to define infrastructure using popular programming languages. This is a major advantage for teams with existing software development expertise, as it reduces the learning curve and enables more complex logic within infrastructure definitions.
  • Crossplane also allows for extensibility through programming but within the context of Kubernetes CRDs and operators, requiring knowledge of Kubernetes and its ecosystem. With the recent addition of Crossplane Composition Functions you can also write your infrastructure code in Python or Go

Pros and Cons

Terraform

Pros:

  • Large ecosystem of providers.
  • Mature, well-documented, and widely adopted.
  • Excellent for multi-cloud environments.

Cons:

Pulumi

Pros:

  • Supports general-purpose programming languages, reducing the need to learn a new DSL.
  • Integrates well with existing development workflows.
  • Strong support for complex logic and abstractions.

Cons:

  • Smaller ecosystem compared to Terraform.
  • Can be overkill for simple infrastructure setups.

Crossplane

Pros:

  • Native integration with Kubernetes and continuous reconciliation.
  • Highly modular and extensible through Kubernetes CRDs.
  • Ideal for teams heavily invested in Kubernetes.

Cons:

  • Requires a Kubernetes cluster to operate, adding operational overhead.
  • Steeper learning curve for teams not familiar with Kubernetes.

Example: Provisioning an AWS S3 Bucket

To demonstrate the differences between these tools, let’s look at how each would provision an AWS S3 bucket.

Terraform

The setup of terraform and configuration of providers is left out in this example:

provider "aws" {
region = "us-west-2"
}

resource "aws_s3_bucket" "example" {
bucket = "my-unique-bucket-name"
acl = "private"
}

Pulumi (TypeScript)

The setup of pulumi and configuration of providers is left out in this example:

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

const bucket = new aws.s3.Bucket("example", {
bucket: "my-unique-bucket-name",
acl: "private",
});

Crossplane (YAML)

The setup of crossplane and configuration of providers is left out in this example:

apiVersion: s3.aws.crossplane.io/v1alpha3
kind: Bucket
metadata:
name: example
spec:
forProvider:
acl: private
bucketName: my-unique-bucket-name
providerConfigRef:
name: aws-provider

All of the above are the bare minimum to provision an AWS S3 bucket. All three IaC tools allow DevOps and Platform teams to build abstractions above the base components, providing development teams with higher level components to be used. Terraform uses the concept of modules, in Pulumi (TypeScript) classes and libraries can be created, and Crossplane is built around the concept of Compositions, which allow you to compose multiple cloud resources using your own custom API.

Conclusion

Terraform, Pulumi, and Crossplane each offer powerful tools for managing cloud infrastructure, but they cater to different needs and philosophies. Terraform is a robust, battle-tested tool with a vast ecosystem, making it ideal for multi-cloud environments. Pulumi appeals to developers by integrating with general-purpose programming languages, offering a seamless transition from application to infrastructure code. Crossplane, with its Kubernetes-native approach, is perfect for teams that already leverage Kubernetes and want to adopt continuous reconciliation for their infrastructure.

When choosing between these tools, consider your team’s existing expertise, your infrastructure needs, and your preferred operational model. Each tool has its strengths, and the right choice depends on your specific use case.

What all these tools have in common is that they are cloud-agnostic and can be used to provision and manage infrastructure in multiple different cloud environments. Cloud-provider specific tooling such as AWS CloudFormation, Azure Bicep or Google Cloud Config Controller could also be interesting for your team. However they often lack extensibility to manage resources outside the cloud provider, which Pulumi, Terraform and Crossplane allow with a huge and growing ecosystem of providers for third party systems.

By understanding the differences and the unique benefits each tool brings, you can make an informed decision that aligns with your team’s goals and capabilities.

--

--

Andreas Leicher
kotaicode

founder kotaico.de - Entrepreneur and Software Developer. Using Creativity&Curiosity to bring innovation from idea to product.Agile, DevOps, Golang, Kubernetes.