Skip to main content

Architecture

Understanding how Pulumi Any Terraform bridges Terraform providers to Pulumi
4 min read

This guide explains how Pulumi Any Terraform works internally, how the bridge operates, and the technical design decisions behind the project.

Overview#

Pulumi Any Terraform is a dynamic bridge that automatically converts Terraform providers into native Pulumi providers. This is achieved through Pulumi's pulumi-terraform-bridge, which translates Terraform's schema and resources into Pulumi's type system.

How It Works#

The Bridge Process#

  1. Terraform Provider Schema: Each Terraform provider defines its resources, data sources, and configuration in Go code with schemas.

  2. Bridge Configuration: The bridge reads the provider's schema and generates corresponding Pulumi resources.

  3. Type Generation: TypeScript type definitions are automatically generated, providing full IntelliSense and type safety.

  4. Resource Mapping: Terraform resources are mapped to Pulumi custom resources with appropriate CRUD operations.

  5. Runtime Execution: When you run pulumi up, the Pulumi engine invokes the bridged provider, which in turn calls the original Terraform provider.

Project Structure#

Provider Package Structure#

Each provider package follows a consistent structure:

Key Components#

1. Provider Resource#

Each package exports a Provider resource that configures the Terraform provider:

2. Custom Resources#

Resources are wrapped as Pulumi CustomResource classes with:

  • Full TypeScript types
  • Input/output properties
  • Proper lifecycle management
  • State tracking

3. Type Definitions#

All inputs and outputs are strongly typed:

Parameterization#

Each provider uses parameterization to specify which Terraform provider to bridge. This is stored as a base64-encoded value in package.json:

Decoded, this specifies:

This tells Pulumi:

  • Which Terraform provider to use (namecheap/namecheap)
  • Which version to bridge (2.2.0)
  • Where to download it from (registry.opentofu.org)

Build System#

The project uses Nx for monorepo management and build orchestration:

Nx Workspace#

Build Plugins#

Custom Nx plugins in /tools/ provide:

  1. Build Plugin (build.ts): TypeScript compilation orchestration
  2. Linter Plugin (linter.ts): Code quality checks
  3. Oxfmt Plugin (oxfmt.ts): Code formatting
  4. Syncpack Plugin (syncpack.ts): Dependency synchronization
  5. Audit Plugin (audit.ts): Security vulnerability scanning

Caching#

Nx provides smart caching to speed up builds:

  • Local cache: Stores build outputs locally
  • Computation caching: Skips unnecessary rebuilds

CI/CD Pipeline#

Workflow Architecture#

Key Workflows#

1. Test Workflow (test.yml)#

  • Runs on every push and PR
  • Lints code with Biome
  • Builds all packages
  • Runs type checking
  • Uses Nx affected commands for efficiency

2. Update Workflow (update.yml)#

  • Runs daily or on-demand
  • Checks for dependency updates
  • Creates automated PRs
  • Uses Renovate for dependency management

3. Publish Workflow (publish.yml)#

  • Runs on main branch after successful tests
  • Uses Changesets for version management
  • Publishes packages to NPM
  • Creates release notes automatically

External Integrations#

1. Terraform Registry#

  • Purpose: Source for Terraform providers
  • Usage: Downloads provider schemas and binaries
  • URL: registry.terraform.io and registry.opentofu.org

2. NPM Registry#

  • Purpose: Distribution of Pulumi packages
  • Usage: Publishing and installing packages
  • Packages: All under pulumi-* namespace

3. GitHub#

  • Purpose: Source control and CI/CD
  • Features:
    • Issue tracking
    • Pull requests
    • GitHub Actions
    • Package registry

4. Aikido Safe Chain#

  • Purpose: Dependency security scanning
  • Usage: Blocks malicious packages during install
  • Integration: GitHub Actions

5. Autofix.ci#

  • Purpose: Automated code fixes
  • Usage: Auto-fixes linting and formatting issues
  • Integration: Automatic PR commits

State Management#

Pulumi manages state differently from Terraform:

Pulumi State#

  • Stored in Pulumi Service (default) or self-managed backend
  • Contains resource metadata and outputs
  • Supports encryption and access control
  • Enables collaboration and history tracking

Bridge State Translation#

The bridge translates between Pulumi and Terraform state:

  1. Pulumi tracks resources in its own state
  2. Bridge invokes Terraform provider with translated inputs
  3. Provider returns outputs
  4. Bridge translates back to Pulumi format
  5. Pulumi updates its state

Type Safety#

One of the main benefits of this bridge is complete type safety:

Input Types#

Output Types#

Type Inference#

Resource Lifecycle#

Resources follow Pulumi's standard lifecycle:

  1. Create: When resource doesn't exist

    • Bridge calls Terraform's Create method
    • Returns resource ID and properties
  2. Read: To refresh state

    • Bridge calls Terraform's Read method
    • Updates Pulumi state with current values
  3. Update: When properties change

    • Bridge calls Terraform's Update method
    • Handles partial updates if supported
  4. Delete: When resource is removed

    • Bridge calls Terraform's Delete method
    • Removes from Pulumi state

Performance Considerations#

Build Performance#

  • Parallel compilation: Multiple packages build simultaneously
  • Incremental builds: Only rebuild changed packages
  • Caching: Skip unchanged builds entirely
  • Nx affected: Only process affected packages

Runtime Performance#

  • Lazy loading: Resources loaded on-demand
  • Concurrent operations: Multiple resources created in parallel
  • State optimization: Minimal state queries
  • Provider reuse: Single provider instance per program

Security#

Dependency Security#

  • Aikido Safe Chain: Scans npm packages during install
  • Dependabot/Renovate: Automated security updates
  • Audit checks: Regular security audits

Secrets Management#

  • Pulumi secrets: Encrypted at rest and in transit
  • Environment variables: For local development
  • Config encryption: Sensitive config encrypted in state

Package Publishing#

  • NPM 2FA: Required for publishing
  • Provenance: Supply chain security
  • Automated publishing: Reduces human error

Debugging#

Enable Debug Logging#

Inspect Bridge Behavior#

Future Enhancements#

Potential improvements to the architecture:

  1. Dynamic provider generation: Generate providers on-demand
  2. Better error messages: More helpful error context
  3. Performance optimization: Faster bridge overhead
  4. Multi-version support: Support multiple Terraform versions
  5. Enhanced types: More precise TypeScript types