In the table above, we grouped and covered differences based on feature domain. Now, letās examine each domain in detail and discover exactly how Terraform and Pulumi achieve the same thingābut do so differently.
Operational domain
A not-so-well-known fact is that Pulumi has a dependence on Terraform provider schemas. It uses these for each cloud-provider to discover which APIs exist and what configuration options are available. To a degree this makes sense, as schemas are not specific to a given tool. However, this dependency may not be immediately obvious to the end-user. Itās not true to say that Pulumi cannot work without a schema, particularly since the Pulumi ānative providersā initiative has been active, but itās a risk worth knowing. Itās also worth noting that Terraform is not completely independent either, and relies on cloud or SaaS vendor API availability.
One of the more notable differences between these tools is the default way that they handle state. While Terraform relies on a local file (terraform.tfstate), Pulumi uses its own SaaS to store state - which also provides additional features such as change history and statistics recording. The use of SaaS could raise availability and reliability questions. We should mention that both tools do offer a variety of state backends (TF, Pulumi), which does alleviate risk of failure, but requires additional configuration and maintenance.
Another important difference is the suitability of these tools for different project sizes. Pulumiās concept of āstackā defines the entire infrastructure and is rather monolithic in nature. Thereās no dependency between stacks and no way to aggregate them to create homogenous infrastructure. Put another way, once you abstract or extend the definition of the āenvironmentā (to contain a Kubernetes cluster and managed services for example), there is no way to gain granular control over them. For Terraform though, the concept of environment can contain any number of modules or definition files, both reusable and structured. Therefore, Terraform probably provides a better fit for enterprise scale infrastructure.
Development domain
A key factor when choosing between Terraform or Pulumi, might just be the language used. Terraform uses HCL, its own domain-specific language (DSL), that is visually similar to JSON, but with additional capabilities. Unlike JSON, HCL is no stranger to comment sections, value assignments or data structures.
Letās look at a quick and dirty code excerpt that creates a private S3 bucket. Simple and straightforward, isnāt it?
resource "aws_s3_bucket" "demo"
{
# Here we create a bucket
bucket = "demo"
acl = "private"
tags = {
environment = "dev"
createdBy = "terraform"
}
}
Now, letās see how this same task could be achieved using Pulumi. Pulumi uses general purpose languages to describe the desired infrastructure state. You are allowed to use any construct that the programming language supports, whether itās a class or an interface, a function or a loop. This is why some administrators might call Pulumi an āimperative toolā...But this not entirely accurate, because while its configuration language is indeed imperative, its engine is actually declarative and maintains state.
Below you can see an exampleāthe same as beforeābut this time implemented as a Python package, which could easily form part of your application code.
import pulumi
import pulumi_aws as aws
bucket = aws.s3.Bucket("demo",
acl="private",
tags={
"environment": "dev",
"createdBy": "terraform",
})
These examples are simplistic and are only used to highlight the āDSL vs programming languageā difference. The most important take-home is this: you can actually include Pulumi code within your application (and its pipeline) and have them delivered together. Unfortunately, the same cannot be achieved so easily with Terraform.
Security domain
Regarding the security of both tools, itās essential to remember that by default, Pulumi is exchanging information not only with cloud provider APIs (as does Terraform), but also with its own SaaS. Your infrastructure state is stored there (S3, MySQL) and is encrypted at rest. All communication with the Pulumi SaaS is encrypted in transit using TLS. The diagram below depicts the security architecture of the Pulumi service.
Image shows the Pulumi security architecture (official security whitepaper)
For Terraform, state can also be stored remotely (with the use of proper backend config) and can be encrypted. By default however, itās stored locally and is unencrypted - which could raise security concerns. For Terraformās SaaS offering Terraform Cloud, both the traffic and the state are encrypted.
Itās fair to say that both tools can be used securely, but Pulumi does provide a little more security out-of-the-box. Beyond that, itās only a matter of setup and price for both SaaS offerings.
Support domain
We have briefly mentioned Pulumiās native providers, which are useful when supporting new cloud or SaaS features and resources. Pulumi officially promises same-day support for these providers (such as Azure and GCP), while Terraform conversely, make no such claims. In reality, the likelihood of needing urgent support for a new feature are quite low. On the other hand, most Pulumi providers are still classical (non-native) and might have some reliance on Terraform, as previously discussed. Itās fair to say though, that until Pulumi native providers completely replace the classical, we canāt call them leader in cloud provider support.
Another important difference is support for Kubernetes. Rarely nowadays would you see an infrastructure without some distribution or other of Kubernetes, so it makes sense for IaC tools to come with K8ās integration capability. As it stands, Pulumi currently has the superior support for Kubernetes, specifically:
- full coverage of all Kubernetes APIs
- support for custom resources definitions (CRDs) directly within Pulumi code
- has a Kubernetes operator for deploying Pulumi code via CRD definitions
- can convert Kubernetes manifests into Pulumi code via kube2pulumi
Whether you actually need these features or not may differ, but as long as Terraform supports only the core Kubernetes API, you might find yourself limited for choice if you do.