What is Pulumi ESC?
Pulumi ESC (Environments, Secrets, and Configuration) is a secrets management platform that centralizes environment variables, secrets, and configuration across all your tools — Terraform, AWS CLI, Docker, Kubernetes, GitHub Actions, and more.
Why Pulumi ESC?
- Free tier — up to 200 secrets, unlimited environments
- Dynamic secrets — generate short-lived AWS/GCP/Azure credentials on the fly
- Universal — works with ANY tool that reads env vars (not just Pulumi)
- Composable environments — inherit and override configs
- Audit trail — full history of who accessed what secrets
- No agent — CLI-based, no daemon or sidecar needed
Quick Start
# Install Pulumi CLI
curl -fsSL https://get.pulumi.com | sh
# Login
pulumi login
# Create an environment
pulumi env init myorg/production
Define an Environment
# production.yaml
values:
aws:
login:
fn::open::aws-login:
oidc:
roleArn: arn:aws:iam::123456789:role/pulumi-esc
sessionName: production
database:
host: prod-db.cluster-abc.us-east-1.rds.amazonaws.com
port: 5432
name: myapp_production
password:
fn::secret: super-secret-password
app:
replicas: 5
log_level: warn
feature_flags:
new_checkout: true
beta_search: false
environmentVariables:
DATABASE_URL: postgres://${database.host}:${database.port}/${database.name}
AWS_ACCESS_KEY_ID: ${aws.login.accessKeyId}
AWS_SECRET_ACCESS_KEY: ${aws.login.secretAccessKey}
AWS_SESSION_TOKEN: ${aws.login.sessionToken}
APP_REPLICAS: ${app.replicas}
Use with ANY Tool
# Run any command with ESC environment
pulumi env run myorg/production -- terraform apply
pulumi env run myorg/production -- aws s3 ls
pulumi env run myorg/production -- kubectl get pods
pulumi env run myorg/production -- docker compose up
# Or export to current shell
eval $(pulumi env open myorg/production --format shell)
aws s3 ls # Uses dynamic credentials from ESC
Composable Environments
# base.yaml — shared across all environments
values:
monitoring:
datadog_api_key:
fn::secret: dd-api-key-123
sentry_dsn:
fn::secret: https://sentry.io/abc
# staging.yaml — imports base, overrides specific values
imports:
- myorg/base
values:
database:
host: staging-db.cluster-xyz.us-east-1.rds.amazonaws.com
app:
replicas: 2
log_level: debug
# production.yaml — imports base with production overrides
imports:
- myorg/base
values:
database:
host: prod-db.cluster-abc.us-east-1.rds.amazonaws.com
app:
replicas: 10
log_level: warn
Dynamic AWS Credentials
# No more static AWS keys!
values:
aws:
login:
fn::open::aws-login:
oidc:
roleArn: arn:aws:iam::123456789:role/deploy
sessionName: deploy-session
duration: 1h # Auto-expires!
environmentVariables:
AWS_ACCESS_KEY_ID: ${aws.login.accessKeyId}
AWS_SECRET_ACCESS_KEY: ${aws.login.secretAccessKey}
AWS_SESSION_TOKEN: ${aws.login.sessionToken}
Pulumi ESC vs Alternatives
| Feature | Pulumi ESC | HashiCorp Vault | AWS SSM | Doppler |
|---|---|---|---|---|
| Free tier | 200 secrets | Self-host | 10K params | 5 users |
| Dynamic credentials | AWS, GCP, Azure | Yes | IAM only | No |
| Universal (any tool) | Yes | Partial | AWS only | Yes |
| Composable envs | Yes | Policies | Hierarchy | Branches |
| No agent | Yes | Agent optional | CLI | CLI |
| Audit trail | Yes | Yes | CloudTrail | Yes |
Real-World Impact
A startup had AWS keys in 12 different places: .env files, CI/CD secrets, developer laptops, Terraform Cloud. When a key leaked on GitHub, rotating it took 6 hours of hunting. With Pulumi ESC: one environment, dynamic credentials everywhere. When they needed to rotate: change ONE role ARN, every tool gets new temporary credentials automatically. Rotation time: 30 seconds.
Tired of scattered secrets? I help teams centralize configuration management. Contact spinov001@gmail.com or check my data automation on Apify.
Top comments (0)