Use when working with Pulumi — pulumi infrastructure-as-code management. Covers stack management, preview/update workflows, configuration and secrets, state inspection, resource history, and policy packs. Use when managing Pulumi stacks, investigating deployment failures, managing secrets, or auditing infrastructure resources.
Scanned 9/8/2026
Install to Claude Code
npx -y skills add cloudthinker-ai/CloudSkills --skill managing-pulumi --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Managing Pulumi?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/cloudthinker-ai-managing-pulumi)More formats (shields.io, HTML) on the badges page.
---
name: managing-pulumi
description: |
Use when working with Pulumi — pulumi infrastructure-as-code management.
Covers stack management, preview/update workflows, configuration and secrets,
state inspection, resource history, and policy packs. Use when managing Pulumi
stacks, investigating deployment failures, managing secrets, or auditing
infrastructure resources.
connection_type: pulumi
preload: false
---
# Pulumi Management Skill
Manage and inspect Pulumi stacks, configurations, secrets, and deployments.
## MANDATORY: Discovery-First Pattern
**Always list stacks and check current stack before modifying infrastructure.**
### Phase 1: Discovery
```bash
#!/bin/bash
echo "=== Pulumi Version ==="
pulumi version 2>/dev/null
echo ""
echo "=== Available Stacks ==="
pulumi stack ls --json 2>/dev/null | jq -r '.[] | "\(.name)\t\(.current // false)\t\(.resourceCount // 0) resources\t\(.lastUpdate // "never")"' | column -t
echo ""
echo "=== Current Stack ==="
pulumi stack --json 2>/dev/null | jq '{name: .current, url: .url}'
echo ""
echo "=== Stack Outputs ==="
pulumi stack output --json 2>/dev/null | jq 'to_entries[] | {key: .key, value: .value}' | head -30
```
## Core Helper Functions
```bash
#!/bin/bash
# Pulumi wrapper with stack selection
pu_cmd() {
pulumi "$@" --non-interactive 2>/dev/null
}
# Safe stack selection
pu_select_stack() {
local stack="$1"
pulumi stack select "$stack" --non-interactive 2>/dev/null
}
# Pulumi API call (for Pulumi Cloud)
pu_api() {
local endpoint="$1"
curl -s -H "Authorization: token $PULUMI_ACCESS_TOKEN" \
"https://api.pulumi.com/api/$endpoint"
}
```
## Output Rules
- **TOKEN EFFICIENCY**: Target <=50 lines per output
- Use `--json` output with jq filtering
- Never dump full stack exports -- extract key fields
- Use `--non-interactive` to prevent prompts
## Common Operations
### Stack Resource Inspection
```bash
#!/bin/bash
STACK="${1:-$(pulumi stack --show-name 2>/dev/null)}"
echo "=== Stack Resources: $STACK ==="
pulumi stack export --stack "$STACK" 2>/dev/null | jq '
.deployment.resources[] |
select(.type != "pulumi:pulumi:Stack") |
{type: .type, urn: .urn | split("::") | last, provider: .provider | split("::")[2]}
' | head -50
echo ""
echo "=== Resource Type Summary ==="
pulumi stack export --stack "$STACK" 2>/dev/null | jq -r '
[.deployment.resources[] | .type] | group_by(.) | map({type: .[0], count: length}) | sort_by(-.count)[] | "\(.count)\t\(.type)"
' | head -20
```
### Preview Changes
```bash
#!/bin/bash
echo "=== Preview Changes ==="
pulumi preview --json --non-interactive 2>/dev/null | jq '{
steps: [.steps[]? | {
op: .op,
urn: .urn | split("::") | last,
type: .type
}],
summary: {
create: [.steps[]? | select(.op == "create")] | length,
update: [.steps[]? | select(.op == "update")] | length,
delete: [.steps[]? | select(.op == "delete")] | length,
same: [.steps[]? | select(.op == "same")] | length
}
}'
```
### Configuration and Secrets Management
```bash
#!/bin/bash
echo "=== Stack Configuration ==="
pulumi config --json 2>/dev/null | jq 'to_entries[] | {
key: .key,
secret: .value.secret,
value: (if .value.secret then "***" else .value.value end)
}'
echo ""
echo "=== Environment Variables ==="
pulumi config env --json 2>/dev/null | jq '.' 2>/dev/null || echo "No environment configuration found"
```
### Stack History and Rollback
```bash
#!/bin/bash
echo "=== Update History ==="
pulumi stack history --json 2>/dev/null | jq '.[0:10][] | {
version: .version,
kind: .kind,
result: .result,
timestamp: .startTime,
resourceChanges: .resourceChanges
}'
echo ""
echo "=== Last Failed Update ==="
pulumi stack history --json 2>/dev/null | jq '
[.[] | select(.result == "failed")] | first // "No failures found"
'
```
### Cross-Stack References
```bash
#!/bin/bash
echo "=== Stack References ==="
pulumi stack export 2>/dev/null | jq -r '
.deployment.resources[] |
select(.type == "pulumi:pulumi:StackReference") |
{name: (.urn | split("::") | last), target: .inputs.name}
'
echo ""
echo "=== All Stack Outputs ==="
for stack in $(pulumi stack ls --json 2>/dev/null | jq -r '.[].name'); do
echo "--- $stack ---"
pulumi stack output --stack "$stack" --json 2>/dev/null | jq 'keys' 2>/dev/null
done
```
## Safety Rules
- **NEVER run `pulumi up` without explicit user confirmation** -- always preview first
- **NEVER run `pulumi destroy`** unless explicitly requested with confirmation
- **Always use `--non-interactive`** to prevent prompts that hang automation
- **Secrets are encrypted** in state -- never use `pulumi config set` without `--secret` for sensitive values
- **Stack exports contain secrets** in plaintext -- handle with care
## Output Format
Present results as a structured report:
```
Managing Pulumi Report
══════════════════════
Resources discovered: [count]
Resource Status Key Metric Issues
──────────────────────────────────────────────
[name] [ok/warn] [value] [findings]
Summary: [total] resources | [ok] healthy | [warn] warnings | [crit] critical
Action Items: [list of prioritized findings]
```
Target ≤50 lines of output. Use tables for multi-resource comparisons.
## Anti-Hallucination Rules
1. **NEVER assume resource names** — always discover via CLI/API in Phase 1 before referencing in Phase 2.
2. **NEVER fabricate metric names or dimensions** — verify against the service documentation or `--help` output.
3. **NEVER mix CLI commands between service versions** — confirm which version/API you are targeting.
4. **ALWAYS use the discovery → verify → analyze chain** — every resource referenced must have been discovered first.
5. **ALWAYS handle empty results gracefully** — an empty response is valid data, not an error to retry.
## Counter-Rationalizations
| Shortcut | Counter | Why |
|----------|---------|-----|
| "I'll skip discovery and check known resources" | Always run Phase 1 discovery first | Resource names change, new resources appear — assumed names cause errors |
| "The user only asked for a quick check" | Follow the full discovery → analysis flow | Quick checks miss critical issues; structured analysis catches silent failures |
| "Default configuration is probably fine" | Audit configuration explicitly | Defaults often leave logging, security, and optimization features disabled |
| "Metrics aren't needed for this" | Always check relevant metrics when available | API/CLI responses show current state; metrics reveal trends and intermittent issues |
| "I don't have access to that" | Try the command and report the actual error | Assumed permission failures prevent useful investigation; actual errors are informative |
## Common Pitfalls
- **Pending operations**: If a previous update was interrupted, stack may have pending operations -- use `pulumi cancel` or `pulumi stack export/import` to fix
- **Secret provider mismatch**: Changing secrets provider requires re-encrypting all secrets -- backup first
- **Stack references**: Deleting a stack that other stacks reference will break those references
- **Language runtime**: Pulumi requires the correct language runtime (Node.js, Python, Go, etc.) installed
- **State corruption**: Never manually edit exported state -- use `pulumi state delete` or `pulumi state unprotect`
- **Provider version drift**: Different stacks may use different provider versions -- pin in package files
- **Refresh vs preview**: `pulumi refresh` updates state from cloud; `pulumi preview` shows config-vs-state diff
- **Protected resources**: Resources with `protect: true` cannot be deleted -- unprotect first with `pulumi state unprotect`
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!