Configuration Basics
Why Configuration & Secrets Matter
The Problem: Infrastructure code needs different values per environment (instance sizes, regions, database passwords), and secrets must never be stored in plain text in version control.
The Solution: Pulumi provides a built-in configuration system with per-stack values and automatic secret encryption, so you can safely store all config in Git.
Real Impact: Teams can manage hundreds of configuration values across environments without risking secret exposure or config drift.
Real-World Analogy
Think of Pulumi configuration like a hotel key card system:
- Config Values = Room preferences (floor, view, bed type) - different per guest
- Secrets = The key card itself - encrypted and unique per guest
- Stack Config File = The reservation record with all preferences
- Secret Provider = The key card encoder machine
- Config Class = The front desk that reads your reservation
How Config Works
Per-Stack Values
Each stack has its own Pulumi.<stack>.yaml file with environment-specific values like regions and instance sizes.
Namespaced Keys
Config keys are namespaced by project name (e.g., myproject:dbSize) to avoid conflicts between packages.
Encrypted Secrets
Secret values are automatically encrypted in the config file, safe to commit to version control.
Typed Access
The Config class provides typed getters (getString, getNumber, getBoolean) with required/optional variants.
Setting Config Values
# Set a plain config value
pulumi config set instanceType t3.micro
# Set a config value for a specific provider
pulumi config set aws:region us-east-1
# Set a secret value (automatically encrypted)
pulumi config set --secret dbPassword S3cur3P@ssw0rd!
# Set a config value on a specific stack
pulumi config set instanceType t3.large --stack prod
# View all config (secrets shown as [secret])
pulumi config
# View config including secret values
pulumi config --show-secrets
Structured Configuration
import * as pulumi from "@pulumi/pulumi";
const config = new pulumi.Config();
// Simple values
const instanceType = config.require("instanceType");
const minSize = config.requireNumber("minSize");
const enableMonitoring = config.getBoolean("enableMonitoring") ?? true;
// Structured config (objects)
interface DatabaseConfig {
engine: string;
instanceClass: string;
allocatedStorage: number;
}
const dbConfig = config.requireObject<DatabaseConfig>("database");
// Access provider-specific config
const awsConfig = new pulumi.Config("aws");
const region = awsConfig.require("region");
Managing Secrets
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const config = new pulumi.Config();
// Read a secret value (returns Output<string>)
const dbPassword = config.requireSecret("dbPassword");
// Use secrets in resources - Pulumi tracks secrecy
const db = new aws.rds.Instance("app-db", {
engine: "postgres",
instanceClass: "db.t3.micro",
allocatedStorage: 20,
username: "admin",
password: dbPassword, // Secret output - encrypted in state
});
// Programmatically mark a value as secret
const secretValue = pulumi.secret("my-sensitive-data");
// Secret outputs are never shown in logs or CLI output
export const connectionString = pulumi.secret(
pulumi.interpolate`postgres://admin:${dbPassword}@${db.endpoint}/mydb`
);
Common Pitfall
Problem: Using config.require() instead of config.requireSecret() for sensitive values causes them to appear in plain text in stack state and logs.
Solution: Always use the --secret flag when setting sensitive config values, and use requireSecret() / getSecret() to read them. This ensures end-to-end encryption.
Secret Providers
Available Secret Providers
- Pulumi Cloud (default): Managed encryption through Pulumi's service
- AWS KMS: Use your own AWS KMS key for encryption
- Azure Key Vault: Encrypt with Azure Key Vault keys
- GCP KMS: Use Google Cloud KMS for encryption
- Passphrase: Local encryption with a user-provided passphrase
# Use AWS KMS for secret encryption
pulumi stack init prod --secrets-provider="awskms://alias/pulumi-secrets?region=us-east-1"
# Use passphrase-based encryption
pulumi stack init dev --secrets-provider="passphrase"
# Change secrets provider for existing stack
pulumi stack change-secrets-provider "awskms://alias/my-key"
Quick Reference
Configuration Commands & Methods
| Command / Method | Description | Example |
|---|---|---|
pulumi config set |
Set a config value | pulumi config set key value |
pulumi config set --secret |
Set an encrypted secret | pulumi config set --secret apiKey abc123 |
config.require() |
Get required string config | config.require("instanceType") |
config.requireSecret() |
Get required secret as Output | config.requireSecret("dbPassword") |
config.getNumber() |
Get optional number config | config.getNumber("port") ?? 3000 |
config.requireObject() |
Get required structured config | config.requireObject<DbConfig>("db") |
pulumi.secret() |
Mark a value as secret | pulumi.secret(computedValue) |