Pulumi Python SDK
raw JSON → 3.227.0 verified Tue May 12 auth: no python install: verified quickstart: stale
Infrastructure as Code SDK for Python. Current version: 3.227.0 (Mar 2026). Requires Pulumi CLI installed separately — 'pip install pulumi' alone does nothing useful. All resource properties return Output[T] not plain values — cannot use them directly as strings/ints. Must use .apply() or Output.all() to work with output values. pulumi.export() must be at top level, not inside apply(). CLI and SDK versions should be kept in sync.
pip install pulumi Common errors
error pulumi: command not found ↓
cause The Pulumi CLI is either not installed on your system or its installation directory is not included in your system's PATH environment variable.
fix
Install the Pulumi CLI by following the instructions on the official Pulumi website (e.g., using
curl -fsSL https://get.pulumi.com | sh for Linux/macOS or a direct download for Windows) and ensure its bin directory is added to your system's PATH. error TypeError: Object of type Output is not JSON serializable ↓
cause Pulumi resource properties return `Output[T]` objects, not direct primitive values, because their actual values might not be known until runtime during the deployment. Attempting to serialize an `Output` object directly (e.g., for logging or passing to a non-Pulumi function expecting a plain string or int) results in this error.
fix
Use the
.apply() method of the Output to work with its resolved value. For JSON serialization, you might pass the Output to a function within .apply() that performs the serialization once the value is known. Alternatively, use pulumi.Output.all() for multiple outputs. error ModuleNotFoundError: No module named 'pulumi' ↓
cause The Pulumi Python SDK or a required provider package (e.g., `pulumi_aws`) is not installed in the Python environment (virtual or global) that Pulumi is using to execute your program.
fix
Activate your project's virtual environment and run
pip install pulumi along with any necessary provider packages (e.g., pip install pulumi_aws, pip install pulumi_azure_native). Ensure your Pulumi.yaml is configured to use your virtual environment if applicable. error Failed to export output. Root resource is not an instance of 'Stack' ↓
cause The `pulumi.export()` function must be called at the top level of your Pulumi program, outside of any functions or class constructors (especially `ComponentResource` constructors), as it registers stack outputs with the Pulumi engine.
fix
Refactor your code to ensure all
pulumi.export() calls are made directly within your main Pulumi program file, after all resources have been defined. If exporting values from a ComponentResource, return them via self.register_outputs() from the component, and then export those outputs from the top-level program. error Value out of range: 8589934588 ↓
cause This obscure error often indicates a significant mismatch between the installed Pulumi CLI version and the Pulumi Python SDK version, possibly due to underlying protobuf library incompatibilities.
fix
Ensure that your Pulumi CLI and Pulumi SDK (and provider SDKs) are kept in sync, ideally using the latest stable versions for both. Upgrade both the CLI and your Python SDK dependencies to their latest compatible versions.
Warnings
breaking 'pip install pulumi' installs the SDK but does NOT install the CLI. Running Python files directly does nothing. Must install Pulumi CLI separately and run via 'pulumi up'. ↓
fix Install CLI: curl -fsSL https://get.pulumi.com | sh. Then: pulumi new <template> && pulumi up.
breaking All resource properties (bucket.bucket, instance.id, etc.) return Output[T] — not plain values. Printing them shows '<pulumi.output.Output object>'. Cannot concatenate or format directly. ↓
fix Use .apply(lambda val: ...) to access the inner value. Or use Output.all() to combine multiple outputs.
breaking pulumi.export() called inside .apply() callbacks or functions is silently ignored. Stack outputs must be registered at the top level of __main__.py. ↓
fix Call pulumi.export('key', output) at the top level — not inside apply(), functions, or conditionals.
gotcha CLI version and SDK version should be kept in sync. Using CLI v3.114+ with SDK < v3.114 breaks --continue-on-error and other features added in that release. ↓
fix Keep pulumi CLI and pip install pulumi at the same major.minor version. Check: pulumi version && pip show pulumi.
gotcha Provider packages (pulumi-aws, pulumi-azure-native, pulumi-gcp) must be installed separately. 'pip install pulumi' alone gives you no cloud resources. ↓
fix pip install pulumi pulumi-aws for AWS. pip install pulumi pulumi-azure-native for Azure.
gotcha hasattr() does not work on Pulumi resource objects. Python output lifting overrides __getattr__ — hasattr will always return True for resource outputs even for non-existent properties. ↓
fix Don't use hasattr() on Pulumi resources. Check the resource type's documented properties instead.
gotcha Pulumi programs must be run via 'pulumi up' or 'pulumi preview' — not 'python __main__.py'. Running directly produces no output and doesn't register resources. ↓
fix Always use the Pulumi CLI: pulumi up, pulumi preview, pulumi destroy.
Install
curl -fsSL https://get.pulumi.com | sh Install compatibility verified last tested: 2026-05-12
python os / libc status wheel install import disk
3.10 alpine (musl) - - 1.28s 85.3M
3.10 slim (glibc) - - 0.57s 71M
3.11 alpine (musl) - - 1.92s 91.2M
3.11 slim (glibc) - - 1.01s 77M
3.12 alpine (musl) - - 1.94s 82.3M
3.12 slim (glibc) - - 1.26s 71M
3.13 alpine (musl) - - 1.80s 81.9M
3.13 slim (glibc) - - 1.20s 71M
3.9 alpine (musl) - - 0.97s 75.3M
3.9 slim (glibc) - - 0.51s 61M
Imports
- Output / apply wrong
import pulumi_aws as aws bucket = aws.s3.Bucket('my-bucket') # Wrong: bucket.bucket is Output[str] not str print(f'Bucket: {bucket.bucket}') # prints <pulumi.output.Output> # Wrong: export inside apply bucket.bucket.apply(lambda name: pulumi.export('name', name)) # ignoredcorrectimport pulumi import pulumi_aws as aws bucket = aws.s3.Bucket('my-bucket') # Output values must be accessed via .apply() bucket.bucket.apply(lambda name: print(f'Bucket name: {name}')) # Combine multiple outputs with Output.all() pulumi.Output.all(bucket.bucket, bucket.region).apply( lambda args: print(f'Bucket {args[0]} in {args[1]}') ) # Export at TOP LEVEL — not inside apply() pulumi.export('bucket_name', bucket.bucket) pulumi.export('bucket_arn', bucket.arn) - pulumi.export wrong
# Wrong: export inside a function called during up def setup(): bucket = aws.s3.Bucket('b') pulumi.export('name', bucket.bucket) # may not be registered setup()correctimport pulumi import pulumi_aws as aws # Stack outputs — must be at top level of __main__.py bucket = aws.s3.Bucket('my-bucket', acl='private') # Export Output directly — Pulumi resolves it pulumi.export('bucket_name', bucket.bucket) pulumi.export('bucket_arn', bucket.arn) # Export transformed output pulumi.export('bucket_url', bucket.bucket.apply(lambda name: f'https://{name}.s3.amazonaws.com') )
Quickstart stale last tested: 2026-04-23
# 1. Install CLI: curl -fsSL https://get.pulumi.com | sh
# 2. pip install pulumi pulumi-aws
# 3. pulumi new aws-python
# 4. Edit __main__.py:
import pulumi
import pulumi_aws as aws
# Create an S3 bucket
bucket = aws.s3.Bucket(
'my-bucket',
acl='private',
tags={'Environment': 'dev'}
)
# Create an EC2 security group
sg = aws.ec2.SecurityGroup(
'web-sg',
description='Allow HTTP',
ingress=[aws.ec2.SecurityGroupIngressArgs(
protocol='tcp',
from_port=80,
to_port=80,
cidr_blocks=['0.0.0.0/0']
)]
)
# Stack exports — must be at top level
pulumi.export('bucket_name', bucket.bucket)
pulumi.export('bucket_arn', bucket.arn)
pulumi.export('sg_id', sg.id)
# 5. pulumi up