Coming from Pulumi

Map Pulumi programs to Encore resources and environments

Pulumi programs execute general-purpose code to construct an infrastructure graph. Encore's TypeScript or Go SDK declarations instead describe the APIs, services, and infrastructure used by the backend. They form an application model that Encore uses for local development and deployment, while Pulumi can continue to manage infrastructure outside that model.

For the deployment models and migration paths shared by all infrastructure-as-code tools, see Coming from an IaC tool.

How it works

The following TypeScript examples define an object storage bucket in Pulumi and Encore:

import * as aws from "@pulumi/aws"; const uploads = new aws.s3.Bucket("uploads");
import { Bucket } from "encore.dev/storage/objects"; export const uploads = new Bucket("uploads", { versioned: false });
import "encore.dev/storage/objects" var Uploads = objects.NewBucket("uploads", objects.BucketConfig{Versioned: false})

The Pulumi resource represents an S3 bucket managed in a Pulumi stack. The Encore declaration identifies the bucket used by the application. Locally, Encore provides development infrastructure. In a cloud environment, Encore can provision the bucket or connect the declaration to a supported existing bucket.

Resource names must be string literals, and declarations must be statically discoverable. This differs from a Pulumi program, which can use normal language control flow to construct an infrastructure graph when the program runs.

How the concepts map

PulumiEncore
ProjectEncore application
StackAn environment is the closest operational concept, but the lifecycle and configuration differ
Custom resourceA primitive when Encore supports the resource type; otherwise it remains in Pulumi
Component resourceNo direct equivalent; Encore services organize application code and its resource usage
Resource inputsApplication-level properties in the declaration, or deployment settings configured per environment
Resource outputsUsually not passed through the application; code imports the logical resource object
Passing a resource Output as an inputResource usage and service calls recorded in the application model; no direct one-to-one equivalent
dependsOnUsually derived from application relationships; no direct equivalent
Stack configurationNo single equivalent; infrastructure settings, secrets, and other application configuration are handled separately
Stack outputs and stack referencesNo general equivalent; keep Pulumi outputs for infrastructure that remains in Pulumi
Pulumi state backendThe application model is rebuilt from source; Encore Cloud separately records the infrastructure it manages
pulumi previewNo direct equivalent; builds validate declarations and Encore Cloud provides infrastructure change workflows
pulumi upNo direct equivalent; an Encore Cloud deployment provisions supported changes, while self-hosted infrastructure remains in the Pulumi workflow

Pulumi configuration often combines application values with physical infrastructure settings. In Encore, place each value according to its purpose:

  • Keep logical resource properties, such as a database name and migrations directory, in application code.
  • Configure capacity, networking, backups, and other deployment properties per Encore Cloud environment.
  • Store sensitive application values in Encore TypeScript secrets or Go secrets.
  • Keep configuration for Pulumi-managed resources in the Pulumi stack.
  • Keep logical resource properties, such as a database name and migrations directory, in application code.
  • Configure capacity, networking, backups, and other deployment properties per Encore Cloud environment.
  • Store sensitive application values in Encore TypeScript secrets or Go secrets.
  • Keep configuration for Pulumi-managed resources in the Pulumi stack.

Encore does not provide a general-purpose non-secret configuration primitive. Ordinary application settings can remain in code or come from an external configuration service.

Decide what Pulumi continues to manage

Pulumi and Encore can run alongside each other. A common boundary is to use Encore for supported resources owned by the application, while Pulumi continues to manage:

  • account and organization configuration
  • shared networking and DNS
  • third-party providers
  • AWS, Azure, or Kubernetes resources without an Encore primitive
  • infrastructure shared with applications outside Encore
  • resources generated dynamically by the infrastructure program

Encore Cloud provisions on AWS and GCP. Pulumi can continue to manage infrastructure on other providers. For a self-hosted Encore deployment, Pulumi provisions all physical infrastructure and an infra config file maps Encore's logical resources to it. See Configure infrastructure.

Migrate existing resources

Do not remove a resource from Pulumi state until you have chosen its new owner and reviewed the cutover process.

For an Encore Cloud environment, supported existing resources can be connected to an Encore declaration. These include:

Connecting a resource to Encore is separate from Pulumi's resource import feature. Pulumi import adds an existing cloud resource to a Pulumi stack and state. Encore's import workflow connects a logical application resource to existing physical infrastructure. Follow the Encore guide for that resource to determine what Encore manages afterward.

If Pulumi should retain ownership, leave the resource in its Pulumi stack. The Encore application can use it as an external dependency, with sensitive connection details stored in Encore secrets.

When moving ownership away from Pulumi, set Pulumi's retainOnDelete resource option and run pulumi up before removing the declaration. Then preview and apply the removal so Pulumi stops managing the resource without deleting it. Verify the resource in the target Encore environment before completing the handoff. If you use a different state workflow, confirm that it also retains the physical resource.

Migrate incrementally

Start with one service rather than an entire Pulumi project:

  1. List the cloud resources used by the service and identify their Pulumi stacks.
  2. Map databases, Pub/Sub, object storage, caches, cron jobs, and secrets to Encore primitives.
  3. Mark shared, unsupported, and dynamically generated infrastructure to remain in Pulumi.
  4. Choose Encore Cloud or self-hosting for the target environment.
  5. Add the Encore declarations and test the service with encore run and encore test.
  6. For Encore Cloud, provision new resources or follow the resource-specific import guide. For self-hosting, map the declarations to Pulumi-provisioned infrastructure.
  7. Deploy and verify connectivity, data, permissions, and rollback procedures.
  8. Change Pulumi ownership only after the Encore environment is verified.

Repeat the process for the next service. Stack references and exported outputs may reveal dependencies that must remain available during the migration.

Workflow differences

Encore validates statically discoverable resource declarations during the build and configures their deployment per environment. It does not replace Pulumi previews or stack state. Keep unsupported, shared, and dynamically generated infrastructure in Pulumi, and migrate one ownership boundary at a time.

For service-by-service application migration patterns, see Migrating an existing system to Encore.