Pulumi — Theory
Pulumi — Theory (interview deep-dive)
Section titled “Pulumi — Theory (interview deep-dive)”Programming model
Section titled “Programming model”Pulumi runs your program once to construct a resource graph. The runtime then computes diff and applies.
- Imperative-looking code → declarative model.
- Same provider semantics as Terraform (most providers wrap Terraform’s).
- Resources have inputs (you provide), outputs (cloud assigns).
Inputs/Outputs
Section titled “Inputs/Outputs”Outputs are async because they depend on cloud responses (e.g., a generated ID, an ARN).
Input<T>acceptsT | Promise<T> | Output<T>.Output<T>is “computed value, possibly with secrets/dependencies tracked”.pulumi.all([a, b]).apply(([av, bv]) => ...)to combine multiple Outputs.
If you do bucket.arn + "/key" you get junk because arn is an Output. Use interpolate or apply.
Component resources
Section titled “Component resources”Wrap many primitives as one logical unit. They:
- Show up as one entry in
pulumi upsummary. - Group lifecycle.
- Are composable (a Component can contain Components).
Encourages reusable infra abstractions (“I have a WebService component that handles ALB+ECS+CloudWatch — drop it in any project”).
- State stored as JSON in chosen backend.
- Has resource graph + last-known inputs/outputs.
- Encrypts secrets automatically using stack passphrase or KMS.
- Stack state operations:
pulumi state delete,pulumi state rename. pulumi importto bring existing resources under management.
Drift & refresh
Section titled “Drift & refresh”pulumi refreshupdates state to match real world (similar to TF).- Detect drift by
preview --diffafter refresh.
Secrets
Section titled “Secrets”pulumi config set --secret password xxx— encrypted in state.- Use
pulumi.secret(value)to wrap any Output as secret. - KMS provider: pass
--secrets-provideron stack init for cloud-key encryption.
Multi-stack workflows (cross-stack refs)
Section titled “Multi-stack workflows (cross-stack refs)”const networkStack = new pulumi.StackReference("acme/network/prod");const vpcId = networkStack.requireOutput("vpcId");Equivalent to TF’s terraform_remote_state.
Common interview Qs
Section titled “Common interview Qs”- Outputs are async — how do you build a string from one?
pulumi.interpolateor.apply(). - What happens when your program errors mid-
up? Pulumi rolls forward what succeeded; failed resource left in error state. Re-run resumes. - TF vs Pulumi tradeoff? HCL discipline vs general-language flexibility.
- Where does state live? Pulumi Cloud or self-hosted (S3/GCS/Azure).
- How would you test infra? Mocks for unit tests; ephemeral stack + assert via SDK for integration.
- Migrate TF → Pulumi? Use
pulumi importper resource, ortf2pulumi(legacy). Most do gradual stack-by-stack.
Pitfalls
Section titled “Pitfalls”- Treating Outputs as plain values.
- Pulumi program with side effects (HTTP, file IO) at top level — runs every preview.
- Not encrypting state at rest.
- Mixing config and code (use
Confignamespace). - Letting program get too complex — refactor into Components.
Use it well
Section titled “Use it well”- Project structure: separate stacks for
dev/staging/prod; same code, different config. - Components in
lib/for reuse across services. - CI runs
pulumi previewon PR (withpulumi/actionsGitHub Action),upon merge. - OIDC for cloud auth (no static keys in CI).
- Pin SDK + provider versions.