Install Pulumi on Linux
Install Pulumi on Debian, Fedora, or Arch Linux, pick a language runtime, configure a state backend, manage secrets, and compare Pulumi to Terraform.
Before you start
- ▸curl installed for the install script method
- ▸Language runtime installed (Node.js, Python 3.8+, Go 1.21+, or .NET 6+) matching your chosen stack
- ▸Cloud provider credentials configured (e.g., AWS_ACCESS_KEY_ID, GOOGLE_CREDENTIALS) before running pulumi up
- ▸An S3 bucket or Pulumi Cloud account if using a remote state backend
Pulumi is an infrastructure-as-code tool that lets you write real programs—Python, TypeScript, Go, C#, Java, or YAML—instead of a domain-specific language. That distinction matters: you get loops, functions, package managers, and IDE support for free. This guide walks through installing Pulumi on Linux, picking a language runtime, wiring up a state backend, handling secrets, and understanding where Pulumi sits relative to Terraform.
Install Pulumi
Option 1: Official install script (any distro)
The upstream script installs the latest release to ~/.pulumi/bin and is the quickest path on any distribution.
curl -fsSL https://get.pulumi.com | sh
Add the binary to your PATH if the installer does not do it automatically:
echo 'export PATH="$HOME/.pulumi/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
Option 2: Package managers
Debian/Ubuntu — add the official apt repository:
curl -fsSL https://apt.pulumi.com/pulumi.gpg | sudo gpg --dearmor -o /usr/share/keyrings/pulumi.gpg
echo "deb [signed-by=/usr/share/keyrings/pulumi.gpg] https://apt.pulumi.com/apt stable main" \
| sudo tee /etc/apt/sources.list.d/pulumi.list
sudo apt update && sudo apt install pulumi
Fedora / RHEL / Rocky:
sudo dnf install 'dnf-command(config-manager)'
sudo dnf config-manager --add-repo https://rpm.pulumi.com/pulumi.repo
sudo dnf install pulumi
Arch Linux — available in the AUR:
paru -S pulumi-bin
# or: yay -S pulumi-bin
Verify installation
pulumi version
You should see output like v3.x.x. The exact version will vary.
Choose a Language Runtime
Pulumi delegates execution to your language's runtime. Install whichever one matches your stack before running pulumi new.
- TypeScript / JavaScript — requires Node.js 18+. Install via your distro's package manager or nodejs.org.
- Python — requires Python 3.8+. Most distros ship a suitable version; confirm with
python3 --version. Pulumi creates a virtualenv per project automatically. - Go — requires Go 1.21+. Install via
apt install golang-go,dnf install golang, or the official tarball for a newer release. - C# / .NET — requires .NET 6 SDK or later. Follow Microsoft's Linux install docs.
- Java — requires JDK 11+. Use
apt install default-jdkordnf install java-21-openjdk. - YAML — no runtime dependency; Pulumi interprets it natively. Good for simple stacks.
Create your first project with the interactive wizard:
mkdir my-infra && cd my-infra
pulumi new aws-python # replace with your cloud and language template
Available templates appear when you run pulumi new with no arguments.
Configure a State Backend
Pulumi stores a state file that tracks what real resources exist. By default it uses Pulumi Cloud (free for individuals), but you can self-host using S3-compatible storage, Azure Blob, or a local directory.
Pulumi Cloud (default)
pulumi login
This opens a browser for token-based auth. For headless servers, create a token at app.pulumi.com and export it:
export PULUMI_ACCESS_TOKEN=pul-xxxxxxxxxxxxx
Self-hosted: S3 or S3-compatible (MinIO, Ceph)
pulumi login s3://my-pulumi-state-bucket
Ensure your environment has AWS credentials or set AWS_ENDPOINT_URL for S3-compatible stores. Pulumi will create a .pulumi/ prefix inside the bucket.
Self-hosted: local filesystem
pulumi login file:///home/user/pulumi-state
Simple for single-user setups or CI. Avoid this for teams—no locking, no sharing.
Check current backend
pulumi whoami -v
Manage Secrets
Pulumi encrypts secret config values before writing them to state. The encryption provider is set per stack.
Default: Pulumi Cloud secrets manager
When using Pulumi Cloud as the backend, secrets are encrypted with a per-stack key managed by the service. Mark a config value as secret:
pulumi config set --secret db_password s3cr3t!
The value is stored encrypted in Pulumi.<stack>.yaml and is only decrypted at runtime.
Passphrase provider (self-hosted)
When using a file or S3 backend, set a passphrase-based secrets provider:
export PULUMI_CONFIG_PASSPHRASE="a-strong-passphrase"
pulumi stack init dev --secrets-provider=passphrase
Store PULUMI_CONFIG_PASSPHRASE in a secrets manager (Vault, AWS Secrets Manager, a CI secret) — never in a dotfile committed to version control.
Cloud KMS providers
You can delegate to AWS KMS, GCP KMS, or Azure Key Vault:
# AWS KMS example
pulumi stack init prod --secrets-provider="awskms://alias/my-pulumi-key?region=us-east-1"
This gives you auditable key usage and rotation without Pulumi Cloud.
Pulumi vs Terraform
Both tools provision cloud infrastructure declaratively and track state, but they take meaningfully different approaches.
| Area | Pulumi | Terraform / OpenTofu |
|---|---|---|
| Language | Python, TypeScript, Go, C#, Java, YAML | HCL (domain-specific); CDKTF adds general languages on top |
| Logic | Native loops, conditionals, functions, classes | Limited: count, for_each, locals; workarounds required for complex logic |
| Testing | Unit-test with pytest, Jest, go test, etc. | Terratest (Go); less idiomatic |
| State | Pulumi Cloud, S3, Azure Blob, GCS, local | Terraform Cloud, S3, Azure Blob, GCS, local |
| Provider ecosystem | Large; many are auto-generated from Terraform providers via the bridge | Very large; de-facto standard |
| Secrets | First-class encrypted secrets in state | Sensitive values marked; still stored in state (often plain in older versions) |
| Open source | Core CLI and SDK: Apache 2.0; Cloud service is SaaS | OpenTofu (MPL 2.0) is the community fork after HashiCorp's BSL change |
Choose Pulumi when your team already works in a supported language, when you need complex logic (generating 50 S3 buckets from a list, conditional module composition), or when you want to unit-test infrastructure code. Choose Terraform/OpenTofu when you need the widest provider coverage, a large existing codebase, or a team more comfortable with HCL.
If you have existing Terraform code, pulumi convert --from terraform can migrate HCL to a Pulumi program automatically—though review the output carefully.
First Deployment
After initialising a project and configuring a backend, run:
pulumi up
Pulumi shows a preview diff, prompts for confirmation, then applies changes. To skip the prompt in CI:
pulumi up --yes
To destroy all managed resources:
pulumi destroy
Troubleshooting
pulumi: command not found after install
The install script adds ~/.pulumi/bin to PATH in your shell rc file, but the current session won't see it until you source it. Run source ~/.bashrc (or ~/.zshrc) or open a new terminal.
State lock errors
If a previous pulumi up was interrupted, the stack may be locked. Inspect and force-unlock with:
pulumi stack export --show-secrets > backup.json
pulumi cancel
Only force-cancel if you are certain no other operation is running.
Passphrase not found
If you see error: passphrase must be set, the PULUMI_CONFIG_PASSPHRASE environment variable is not exported in the current shell or CI environment. Double-check your secret injection and that you're using the same passphrase that was used when the stack was created.
Runtime not found
Pulumi spawns your language runtime as a subprocess. If you get error: python3: not found or similar, install the runtime and ensure it is on PATH for the user running Pulumi—including in CI where PATH may be narrower than your interactive shell.
Frequently asked questions
- Can I use Pulumi without Pulumi Cloud?
- Yes. Log in with `pulumi login s3://your-bucket` or `pulumi login file:///path` to use S3-compatible storage or the local filesystem as the state backend. No Pulumi account is required.
- How does Pulumi compare to Terraform for teams already using HCL?
- Pulumi uses general-purpose languages, which makes complex logic and testing easier, but Terraform/OpenTofu has a larger provider ecosystem and more existing community modules. `pulumi convert --from terraform` can migrate HCL code as a starting point.
- Are Pulumi secrets safe if I use an S3 backend?
- Yes, as long as you choose a passphrase or KMS secrets provider when initialising the stack. The secret values are encrypted before being written to state; S3 bucket permissions control access to the ciphertext.
- Can I import existing cloud resources into Pulumi?
- Yes. Use `pulumi import <resource-type> <name> <cloud-id>` to bring an existing resource under Pulumi management without recreating it. Pulumi generates the corresponding code for you.
- Does Pulumi work in CI/CD pipelines?
- Pulumi is designed for CI use. Export `PULUMI_ACCESS_TOKEN` (or your passphrase) as a CI secret, then run `pulumi up --yes` or use the official GitHub Actions and GitLab CI integrations.
Related guides
Configure Prometheus Alertmanager
Configure Prometheus Alertmanager with routing trees, receivers, inhibition rules, grouping, Go templates, and PagerDuty/Slack on-call integrations.
Build an Intranet Server on Linux
Set up a complete small-office intranet on one Linux box: Nginx web server, dnsmasq local DNS, Samba file sharing, and a Wiki.js team wiki.
Build an nftables Firewall Script
Build a complete nftables firewall from scratch: tables, chains, sets, default-deny input policy, service allowlisting, and persistent systemd configuration.
Caddy as a Reverse Proxy
Set up Caddy as a reverse proxy with automatic HTTPS, load balancing, WebSocket passthrough, reusable snippets, and header control — no certbot required.