pulumi/pulumi
The pulumi CLI
Active contributors: Ian Wahbe, Justin Van Patten, Thomas Gummerer, Fraser Ashyggton
Purpose
The pulumi CLI is the single binary every Pulumi user runs. It parses command-line input, locates the user's project, instantiates a deployment engine, spawns language hosts and providers, and renders progress to the terminal. It is the most-touched and most-tested surface in the repo.
Directory layout
pkg/cmd/pulumi/
├── main.go # tiny entry point — calls NewPulumiCmd and runs
├── pulumi.go # the giant root command (≈33 KB) with every subcommand registration
├── pulumi_test.go # full-CLI integration tests
├── about/ # `pulumi about` (CLI + system info)
├── ai/ # `pulumi ai` (AI integrations)
├── auth/ # login / logout / token lifecycle
├── autonaming/ # `pulumi autonaming` (resource auto-naming controls)
├── cmd/ # generic command helpers
├── config/ # `pulumi config get/set/...`
├── convert/ # `pulumi convert` (Terraform/CFN/etc → Pulumi)
├── deployment/ # `pulumi deployment` (cloud deployments)
├── env/ # `pulumi env` (ESC environments)
├── events/ # event filtering and streaming
├── install/ # `pulumi install` (plugin install)
├── logs/ # `pulumi logs`
├── neo/ # next-gen command tree (under construction)
├── newcmd/ # `pulumi new` (project bootstrap)
├── operations/ # programmatic operation runner — used by Automation API in-process
├── org/ # org-scoped commands (cloud)
├── packagecmd/ # package-level commands
├── packageinstallation/ # plugin install machinery
├── packageresolution/ # plugin/version resolution logic
├── packageworkspace/ # workspace-scoped package management
├── plugin/ # `pulumi plugin ls/install/...`
├── policy/ # `pulumi policy` (policy packs)
├── project/ # project-level helpers
├── schema/ # schema commands (`pulumi schema check` etc.)
├── stack/ # `pulumi stack`
├── state/ # `pulumi state` (snapshot surgery)
├── templatecmd/ # `pulumi template`
├── trace/ # `pulumi trace` (tracing decoder)
├── ui/ # interactive UI components for prompts
├── version/ # `pulumi version`
└── whoami/ # `pulumi whoami`How a command runs
graph TD
main[pkg/cmd/pulumi/main.go] -->|NewPulumiCmd| Root[Root cobra.Command]
Root -->|cobra subcommand routing| Sub[Subcommand handler<br/>e.g. pkg/cmd/pulumi/up]
Sub -->|loads| Workspace[Workspace<br/>sdk/go/common/workspace]
Sub -->|chooses| Backend[Backend<br/>diy or httpstate]
Sub -->|configures| Engine[Engine<br/>pkg/engine]
Engine -->|emits events| Display[Display<br/>pkg/cmd/pulumi/display + pkg/backend/display]
Display -->|renders| Term[Terminal]main.go is a few-line shim. The interesting code is in pulumi.go — the giant NewPulumiCmd() function builds the cobra command tree and wires every subcommand. Each subcommand package contributes a constructor (e.g. stack.NewStackCmd()) that returns a *cobra.Command.
Key abstractions
| Symbol | File | Role |
|---|---|---|
NewPulumiCmd |
pkg/cmd/pulumi/pulumi.go |
Constructs the root cobra command tree |
Backend |
pkg/backend/backend.go |
Abstract over DIY vs httpstate |
currentBackend(...) |
pkg/cmd/pulumi/backend/ |
Selects the backend for the current login |
Workspace |
sdk/go/common/workspace/ |
The on-disk project + stack representation |
Engine |
pkg/engine/engine.go |
What every operation eventually creates |
displayEvents |
pkg/cmd/pulumi/display/ |
Renders engine events to terminal |
CLI surface
The major user-visible commands. Each routes to a subpackage under pkg/cmd/pulumi/:
| Command | Subpackage | Purpose |
|---|---|---|
pulumi up |
(in pulumi.go) |
Apply desired state |
pulumi preview |
(in pulumi.go) |
Plan only |
pulumi destroy |
(in pulumi.go) |
Tear down |
pulumi refresh |
(in pulumi.go) |
Reconcile state with cloud |
pulumi import |
(in pulumi.go) |
Bring existing resources under management |
pulumi new |
newcmd/ |
Scaffold from a template |
pulumi convert |
convert/ |
TF/CFN/Kube → Pulumi |
pulumi stack ... |
stack/ |
Stack lifecycle |
pulumi config ... |
config/ |
Stack config |
pulumi state ... |
state/ |
Snapshot surgery |
pulumi plugin ... |
plugin/ |
Plugin cache management |
pulumi package ... |
packagecmd/ |
Package commands |
pulumi policy ... |
policy/ |
Policy packs |
pulumi env ... |
env/ |
ESC environments |
pulumi deployment ... |
deployment/ |
Cloud-managed deployments |
pulumi about |
about/ |
Version + system info |
pulumi login/logout |
auth/ |
Auth lifecycle |
pulumi schema ... |
schema/ |
Schema utilities |
How the CLI talks to the engine
The CLI does not hold the engine state in-process. For each operation:
- Resolve workspace and stack.
- Pull the latest snapshot from the chosen backend.
- Construct an
engine.UpdateInfo(target stack + source program). - Call
engine.Update(...)(orPreview,Destroy, etc.). - Stream the engine's events through the display layer to the terminal.
- Persist the resulting snapshot.
pkg/cmd/pulumi/operations/ exposes the same flow as a library, which is what Automation API runs.
Display
Engine events are rendered by pkg/backend/display/ (TUI/JSON renderer) plus terminal helpers in pkg/cmd/pulumi/display/. The display layer is event-driven — it never reaches into engine state directly. This isolation is what lets Pulumi Cloud reuse the same renderer to draw deployments in the browser.
Entry points for modification
- Adding a new top-level subcommand — add a constructor in a new (or existing) subpackage, register it from
pkg/cmd/pulumi/pulumi.go. Mirror an existing simple command (e.g.whoami) as a template. - Adding a flag to
pulumi up—pulumi.goagain. Threads through topkg/engine/update.go'sUpdate()options. - Changing how snapshots load — go through the
Backendinterface inpkg/backend/backend.go; do not touch~/.pulumipaths from the CLI. - Changing display —
pkg/backend/display/is the canonical renderer.
Tests
- Smoke tests:
tests/smoke/ - Full integration:
tests/integration/<name>/<lang>/ - Per-command unit tests:
pkg/cmd/pulumi/*_test.go - Login/auth-specific:
tests/login/
See also
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.