ubx convert --from pulumi reads your TypeScript (or Python or Go) Pulumi program and generates equivalent .iac source. The converter handles config lookups (config.get("env") → input "env"), resource declarations (new aws.s3.BucketV2("assets", {...}) → unit "aws_s3_bucket_v2" "assets" {...}), and exports (export const bucket = ... → output "bucket" {...}). Cases that require manual attention — complex TypeScript expressions that don’t have .iac equivalents, multi-resource patterns that collapse to sub-blocks — are documented in the MIGRATION.md the converter produces.
What you’ll learn
- How
ubx convert --from pulumiconverts Pulumi TypeScript to.iac - The common manual fixups required after conversion
- Why existing Pulumi state is preserved — no reimport needed
Why this matters
Migrating from Pulumi to ubx preserves your Pulumi state entirely — the same S3/GCS/Azure Blob backend, the same resource URNs. No
import blocks needed, no resources recreated. ubx is a compiler that targets Pulumi, so the generated program is a valid Pulumi program that picks up where your existing program left off.The source code
How it works
Run ubx convert to generate .iac files
ubx convert --from pulumi ./pulumi-before/index.ts --out ./ reads the TypeScript Pulumi program and generates .iac equivalents. The converter handles config.get("x") → input "x", new aws.Resource("name", {...}) → unit "aws_resource" "name" {...}, and export const x = ... → output "x" {}.Apply manual fixups from MIGRATION.md
The converter documents cases requiring manual attention. Common fixups:
BucketVersioningV2 resource → versioning sub-block inside aws_s3_bucket_v2, complex TypeScript template literals → .iac string interpolation, config.require() → input with no default, pulumi.secret() wrapper → ephemeral = true on the input.No import needed — Pulumi state is reused
Unlike Terraform migration, no
import blocks are needed. ubx generates a Pulumi TypeScript program that uses the same resource URNs as the original. The first ubx apply runs against the existing Pulumi state and produces no diff if the converted source matches the original program’s configuration exactly.Common conversion patterns
| Pulumi TypeScript | ubx .iac | Notes |
|---|---|---|
config.get("env") || "dev" | input "env" { default = "dev" } | Default maps directly |
config.require("key") | input "key" {} (no default) | Required input |
new aws.s3.BucketV2("name", {...}) | unit "aws_s3_bucket_v2" "name" {...} | SDK class → unit type |
export const x = res.attr | output "x" { value = unit.res.attr } | export → output block |
BucketVersioningV2 resource | versioning {} sub-block | Sub-resource → sub-block |
pulumi.secret(value) | input "x" { ephemeral = true } | Secret wrapping → ephemeral |
`${env}-name` | "${input.env}-name" | Template literal → interpolation |
Common mistakes
Run it
What you learned
ubx convert --from pulumi converts Pulumi TypeScript programs to .iac automaticallyPulumi state is reused — no
import blocks needed, no resources recreatedA clean
ubx plan (0 diffs) confirms the converted source is equivalent to the original programNext steps
Migrate from Terraform
Convert Terraform .tf files to .iac
Multi-runtime compilation
Change the runtime target after migration
Full runnable example: github.com/ubiquex/ubx-examples/55-migration-from-pulumi

