Terraform vs Ansible - Understanding the Differences
Terraform vs Ansible — understand the key differences between provisioning and configuration management, and when to use each tool or both together.
DevOps
Compare Terraform and Pulumi for infrastructure as code — language choice, state management, multi-cloud support, testing, and which tool fits your team.
Terraform: Declarative DSL (HCL), largest provider ecosystem, battle-tested at scale. Pulumi: Use Python, TypeScript, Go, or C# — real programming languages with loops, classes, and testing frameworks. Choose based on your team's skills and complexity needs.
| Feature | Terraform | Pulumi |
|---|---|---|
| Language | HCL (domain-specific) | Python, TypeScript, Go, C#, Java |
| Paradigm | Declarative | Imperative + declarative |
| Providers | 3,000+ | Uses Terraform providers via bridge |
| State | Self-managed (S3, etc.) or TF Cloud | Pulumi Cloud or self-managed |
| Modules/reuse | Terraform Registry modules | NPM, PyPI, Go packages |
| Testing | terraform test (1.6+) | pytest, Jest, Go test (native) |
| Plan/preview | terraform plan | pulumi preview |
| Learning curve | Learn HCL | Use your existing language |
| IDE support | HCL plugins | Full IDE support (autocomplete, types) |
| License | BSL 1.1 (since 1.6) | Apache 2.0 |
Terraform:
resource "aws_s3_bucket" "data" {
bucket = "my-data-bucket"
tags = { Environment = "prod" }
}
resource "aws_s3_bucket_versioning" "data" {
bucket = aws_s3_bucket.data.id
versioning_configuration { status = "Enabled" }
}Pulumi (Python):
import pulumi_aws as aws
bucket = aws.s3.Bucket("data",
bucket="my-data-bucket",
tags={"Environment": "prod"},
)
versioning = aws.s3.BucketVersioningV2("data",
bucket=bucket.id,
versioning_configuration={"status": "Enabled"},
)Pulumi (TypeScript):
import * as aws from "@pulumi/aws";
const bucket = new aws.s3.Bucket("data", {
bucket: "my-data-bucket",
tags: { Environment: "prod" },
});Terraform (for_each):
variable "environments" {
default = ["dev", "staging", "prod"]
}
resource "aws_s3_bucket" "env" {
for_each = toset(var.environments)
bucket = "myapp-${each.key}-data"
}Pulumi (Python loop):
environments = ["dev", "staging", "prod"]
buckets = {}
for env in environments:
buckets[env] = aws.s3.Bucket(f"{env}-data",
bucket=f"myapp-{env}-data",
)terraform test| Aspect | Terraform | Pulumi |
|---|---|---|
| Default | Local file | Pulumi Cloud (free tier) |
| Self-hosted | S3, Azure Blob, GCS | S3, Azure Blob, GCS |
| Locking | DynamoDB/native | Automatic |
| Encryption | Your responsibility | Built-in (Cloud) |
| Secrets | Plaintext in state | Encrypted per-value |
Pulumi's per-value secret encryption is a significant security advantage — secrets in state are encrypted individually, not just at the backend level.
pulumi convert --from terraform
# Converts HCL to your chosen languageNo automated tool — manual rewrite required.
Terraform wins on ecosystem size, community, and simplicity. Pulumi wins on language flexibility, testing, and secret handling. If your team writes Python or TypeScript daily and needs complex abstractions, Pulumi is compelling. If you want the largest community and most straightforward IaC, Terraform is the safer bet.
Terraform vs Ansible — understand the key differences between provisioning and configuration management, and when to use each tool or both together.
Set up OCI Load Balancer with Terraform — backend sets, listeners, SSL certificates, and health checks. Step-by-step guide with code examples and best practi...
Configure OCI Object Storage buckets with Terraform — lifecycle policies, pre-authenticated requests, and replication. Step-by-step guide with code examples ...
Deploy Oracle Autonomous Database with Terraform — ATP and ADW instances, wallets, and private endpoints. Step-by-step guide with code examples and best prac...