Pulumi in CI/CD & securing secrets

Automate up; protect state and secrets.

Advanced14 min · lesson 12 of 12

The safe automation pattern mirrors every mature IaC shop: on a pull request, run pulumi preview and surface the diff for review; on merge, run pulumi up to apply the reviewed change — never an interactive up from a laptop against prod. Pulumi ships CI integrations and a GitHub App that comment the preview directly on the PR, so the change is visible before it lands.

.github/workflows/infra.yml
jobs:
preview:
if: github.event_name == 'pull_request'
steps:
- uses: pulumi/actions@v5
with: { command: preview, stack-name: acme/prod }
env: { PULUMI_ACCESS_TOKEN: ${{ secrets.PULUMI_ACCESS_TOKEN }} }
up:
if: github.ref == 'refs/heads/main'
environment: production # requires approval
steps:
- uses: pulumi/actions@v5
with: { command: up, stack-name: acme/prod }

Securing state and secrets

Pulumi automation holds the keys to your cloud, so harden it like the CI/CD course teaches. Use OIDC to get short-lived cloud credentials instead of long-lived keys in CI; back the stack’s secret encryption with a managed KMS key, not a passphrase in an env var; restrict who can read state (Pulumi Cloud RBAC, or a locked-down bucket for self-managed); and gate prod updates behind a protected environment with human approval.

The secure Pulumi pipeline
1PR: preview
diff + policy pack
2review
human reads the diff
3merge: up
apply reviewed change
4guardrails
OIDC, KMS secrets, RBAC
Preview is visible and policy-gated; up is approved; credentials are short-lived; secrets and state are encrypted and access-controlled.
The secret provider key is critical infrastructure
Every stack secret and, on self-managed backends, sometimes the state itself, depends on the encryption key. Back it with a managed KMS that has proper key policies and backups, make sure every CI runner and engineer who needs it can reach it, and never commit a passphrase or check the key into the repo — losing it can make secrets (and updates) unrecoverable.