Comparison between Terraform and Pulumi in OCI and multicloud infrastructure deployment and management

December 21, 2023 | 8 minute read
Adina Nicolescu
Senior Cloud Engineer
Text Size 100%:

Pulumi and Terraform are both infrastructure as code (IaC) tools, used to automate and manage cloud infrastructure and other resources. The choice between them often comes down to your team’s preferences, existing skills, and the specific needs of your projects.

Even if they have similar objectives, we need to also understand how they differ when trying to decide which is better for each use case. In most cases, customers must manage several environments, either all in Oracle Cloud Infrastructure (OCI) with production, developer, and test environment or multicloud. Because many customers no longer use just one cloud provider, and in many cases, they’re no longer looking to migrate environments but expand to a multicloud configuration, it’s also important to understand the multicloud solutions to easily deploy and especially manage resources for OCI and other cloud providers at the same time. We recommend evaluating both tools based on your requirements before deciding, so review the following considerations to make a more informed decision.

Configuration of file management

One of the most relevant differences is how these tools can centralize the resources they declare and manage.

Terraform is a mature and complex IaC tool, which also has numerous providers available. It’s integrated with OCI as the Resource Manager service, which can also generate the code for existing resources on your behalf and create drift detection reports. If you want to create separate dev and prod environments, you must deploy the code several times from different separate stacks. You can also use workspaces, which allow the use of multiple states with a single configuration directory. With Terraform, you can also create infrastructure for multicloud, using different providers. With this configuration, you create and manage separate sets of configuration files for each cloud provider.

As an alternative, under Pulumi, you can create and manage the infrastructure for several environments (dev and prod) for OCI from the same configuration files. In the same way, it can manage multiple providers and their respective resources under a single set of files, which can be useful in multicloud configurations. In addition to managing them together, with Pulumi you can define a stack for each environment or for each cloud provider you want to manage, and under that stack, it manages the resources declared.

In the following simplified Python example, Pulumi creates a network for three environments: Prod and Dev in OCI and another for Amazon Web Services (AWS).

import pulumi
from pulumi import Output
from pulumi_oci import core
from pulumi_aws import ec2

# Define OCI Stack
oci_prod_stack = pulumi.Stack('oci-prod-stack')

# Create a VCN in OCI (Production)
oci_vcn_prod = core.VirtualNetwork('oci-vcn-prod',
    cidr_block="10.0.0.0/16",
    display_name="oci-vcn-prod",
    compartment_id=oci_stack.output("compartment_id"))

# Define OCI Dev Stack
oci_dev_stack = pulumi.Stack('oci-dev-stack')

# Create a VCN in OCI (Dev)
oci_vcn_dev = core.VirtualNetwork('oci-vcn-dev',
    cidr_block="10.0.0.0/16",
    display_name="oci-vcn-dev",
    compartment_id=oci_dev_stack.output("compartment_id"))

# Define AWS Stack
aws_stack = pulumi.Stack('aws-stack')

# Create a VPC in AWS
aws_vpc = ec2.Vpc('aws-vpc',
    cidr_block="10.0.0.0/16",
    tags={"Name": "aws-vpc"})

# Export OCI and AWS network information
pulumi.export('oci_vcn_prod_id', oci_vcn_prod.id)
pulumi.export('oci_vcn_dev_id', oci_vcn_dev.id)
pulumi.export('aws_vpc_id', aws_vpc.id)

You can initialize these stacks independently from command line, although they’re defined in the same file. To deploy the stacks separately, run the following commands:

pulumi up --stack oci-prod-stack
pulumi up --stack oci-dev-stack
pulumi up --stack aws-stack

These commands deploy the OCI production, OCI developer, and AWS networks as separate stacks in the same Pulumi program.

Language and configuration

These tools handle configuration files differently. Terraform uses HashiCorp Configuration Language (HCL), which is a declarative language specifically designed for Terraform. You use HCL to write configuration files. It’s designed to be human-readable and used to define infrastructure as code in a declarative way. HCL doesn’t implement the classic loops and conditionals, but it’s flexible enough to be able to implement such logic in other ways.

The following example shows an OCI Compute instance definition in Terraform:

resource "oci_core_instance" "test" {
  availability_domain = "ad"
  compartment_id     = "comp"
  # Other configuration parameters
}

Pulumi is a multilanguage tool. It uses existing familiar programming languages, such as TypeScript, JavaScript, Python, Go, .NET, Java, and markup languages like YAML, and their native ecosystems to interact with cloud resources through the Pulumi software developer kit (SDK). This configuration enables you to use the full power of these programming languages, including loops, conditionals, and libraries.

The following example shows an OCI Compute instance definition in Pulumi:

import pulumi
import pulumi_oci as oci

test = oci.core.Instance(
    'test',
    availability_domain='ad',
    compartment_id='comp',
    # Other configuration parameters
)

Declarative versus imperative

Terraform is primarily declarative. You specify the desired state of your infrastructure, and Terraform figures out how to create or modify resources to match that state.

Pulumi is considered both declarative and imperative. It’s imperative because you write code to define the infrastructure, specifying the exact steps to create or modify resources, and the languages you use are imperative. It’s closer to writing programs than to describing your infrastructure. The imperative side is related to what happens under the hood and the programming side. The language host sends requests to the engine to fulfill your to-be infrastructure. The declarative part helps with the infrastructure management, where the engine combines the intended model of the infrastructure received from the language host, the current state recorded in the state backend, and the actual resource state to compute which actions need to be run to bring the actual state in line with the intended model.

State management

Terraform uses a state file to keep track of the current state of the infrastructure. This state file can be stored locally or remotely in OCI Object Storage, so it’s self-managed by the user. When using the OCI Resource Manager to manage infrastructure the state is also managed remotely by the service. Terraform uses this state to plan and apply changes.

Pulumi uses a stack-based approach where you can define multiple stacks for different environments, such as development, staging, and production. Each stack maintains its own state, which can be stored in various backends. Just like in Terraform, the state can be cloud-managed in Pulumi Cloud or self-managed locally or in different cloud storage options, such as OCI Object Storage).

Workflow

Terraform follows three steps: Write code, plan (preview changes before applying), and apply (provision infrastructure).

Pulumi run the code, so you don’t have plan and apply phases. After configuring your project with code and values, you deploy everything with the command, pulumi up.

Tool maturity

Terraform has been around for a longer time. It’s more mature and has a wider variety of providers and modules for various cloud platforms and services. So, it supports a wide range of cloud resources out of the box.

Pulumi is newer and currently has a smaller ecosystem compared to Terraform. At present, it supports fewer cloud providers and services directly. Indirectly, if needed, you can write your own providers. You can use OCI to provision any of the following resources available for Pulumi, such as the pulumi_oci library.

Conclusion

The following table gives an overview comparing the features of the two tools:

Feature Terraform Pulumi
Language HashiCorp Configuration Language (HCL) Support for multiple languages, including JavaScript, TypeScript, Python, Go, and .NET
Deployment model Declarative Imperative and declarative
Ease of learning Generally considered easy to learn, more difficult to master complex aspects Depends on familiarity and experience with programming languages and concepts
Community support Large and active community Community smaller than Terraform, growing
Providers Rich provider ecosystem (OCI, AWS, Azure, GCP, and K8s) Supports multiple cloud providers and services but may have fewer providers compared to Terraform
State management Uses local and remote state files (OCI Object Storage, AWS S3) Can use remote state storage or local state files
Code reusability Modules (reusable code) Uses standard programming language features for code organization and reusability
Dynamic configuration Limited support for dynamic values Uses programming language features for dynamic configuration
Tooling integration Well-integrated with Terraform CLI and GUI and Resource Manager in OCI Integrated with existing infrastructure tooling but might require extra setup
Updates & drift detection OCI has drift detection feature in the Resource Manager. Terraform plans and detects updates based on state Can detect and manage resource drift
Commercial support Offered by HashiCorp, integrated in the Resource Manager managed service in OCI Pulumi offers commercial support
Maturity Mature, well-developed, widely adopted Newer than Terraform, still developing, gaining traction in industry
Serverless support Good support for serverless services Supports serverless services
Multicloud support Excellent multicloud support through multiple deployments Might have fewer providers than Terraform but can deploy to multiple clouds from same configuration files

The choice between Pulumi and Terraform depends on your specific requirements and preferences. If you’re a developer and familiar with programming languages, Pulumi might be quite easy for you to adopt. If programming isn’t your strong point, Terraform can be easily picked up to a level where you can comfortably manage infrastructure in OCI or even multiple clouds. Pulumi can compete with Terraform even if you only run OCI and want to manage one or more environments, or if you prefer to configure using a programming language. But it might be most useful when you need to manage stacks in a multicloud environment in a simple way.

Start off with an Oracle Cloud Infrastructure tenancy today and test these two IaC solutions!

For more information, see the following resources:

Adina Nicolescu

Senior Cloud Engineer


Previous Post

Better backups with policy-based snapshots and replication in OCI File Storage Service

Vinoth Krishnamurthy | 4 min read

Next Post


Observability & Management services to manage a large Oracle Database fleet

Erika Sciunzi | 8 min read