Escaping HCL with Pulumi TypeScript
Learn how to migrate from Terraform to Pulumi using TypeScript to leverage real programming logic and IDE support. This guide covers using the pulumi-terraform-bridge, managing state with pulumi import, and navigating Pulumi Cloud pricing tiers.
Programming over configuration
Pulumi allows teams to define infrastructure using TypeScript, Python, Go, C#, Java, or F#. This approach gives developers access to real functions, classes, and package managers like npm or PyPI. Many engineers leave Terraform because HCL lacks the expressiveness found in a general-purpose language. HCL stays predictable, but complex logic often requires awkward workarounds with for_each or count. I recommend Pulumi for teams that prioritize developer experience.
Pulumi provides full IDE support and type checking.
The tool handles multi-cloud deployments for AWS, Azure, and GCP. While Terraform has a registry of 4,800 providers, Pulumi maintains 1,800 providers. You can use any Terraform provider via the pulumi-terraform-bridge project. This bridge translates Terraform provider schemas into Pulumi-native SDKs. If you need a niche service, the bridge allows you to use existing Terraform providers without writing new code. Using real programming languages means you can unit-test infrastructure code with existing frameworks like Jest or pytest. This ability fits into your existing CI/CD pipelines without friction.
Use TypeScript.
Managing migration and state
Migrating from Terraform to Pulumi requires a methodical plan. You must inventory your resources and define module boundaries before you begin. Pulumi provides a converter tool that reads HCL and produces a Pulumi project. Do not attempt a big-bang rewrite of a large estate. Move networking, then data stores, then compute, one module at a time.
Protect your data.
You must use pulumi import to tell Pulumi that a resource already exists. If you skip this step, pulumi up will try to create new resources. This causes errors when the cloud provider finds the resource already exists. Set protect: true on stateful resources like RDS or S3 to prevent accidental deletion. After importing, run pulumi preview. This step acts as a safety gate. A successful migration shows zero changes. If you see replacements, you must fix the program or add ignoreChanges to the resource options.
If you have a large estate, you can import in bulk from a JSON file instead of one command per resource. You can generate this file using terraform state list and terraform show -json to map the addresses and cloud IDs. This makes the process faster for large environments.
Pulumi stores infrastructure metadata in a state file. This state tracks resource URNs, input properties, and dependencies. You can use Pulumi Cloud or a DIY backend like AWS S3, Azure Blob Storage, or Google Cloud Storage. Pulumi Cloud handles state locking automatically. DIY backends use a file-based locking system in your storage bucket.
To migrate between backends, use the pulumi stack migrate command. This command requires Pulumi CLI version 3.254.0 or later. You must log into your target backend before running the command. For example, you can migrate a stack from a local backend to Pulumi Cloud. This process re-encrypts secrets in the configuration and state with the target stack’s secrets provider.
Costs and infrastructure models
Pulumi Cloud pricing revolves around Pulumi Credits. In the Team tier, each credit costs $0.0005. The Team tier provides 150,000 free credits monthly and up to 10 users. This tier also includes 3,000 deployment minutes per month.
The Enterprise tier provides unlimited users, role-based access control, and 12×5 support for massive organizations that need to scale their infrastructure management across many different departments and cloud accounts while maintaining strict security and compliance standards. This tier costs $32,850 yearly on the AWS Marketplace. The Business Critical tier starts at $50,000 yearly on the Azure Marketplace.
You should evaluate your team’s skill set before switching.
Will you manage your own state?
Import existing resources.