$npx -y skills add pulumi/agent-skills --skill pulumi-escpulumi-esc is an agent skill published from pulumi/agent-skills, installable through the skills CLI.
| 1 | # Pulumi ESC (Environments, Secrets, and Configuration) |
| 2 | |
| 3 | Pulumi ESC is a centralized service for managing environments, secrets, and configuration across cloud infrastructure and applications. |
| 4 | |
| 5 | ## What is ESC? |
| 6 | |
| 7 | ESC enables teams to: |
| 8 | |
| 9 | - **Centralize secrets and configuration** in one secure location |
| 10 | - **Compose environments** by importing and layering configuration |
| 11 | - **Generate dynamic credentials** via OIDC for AWS, Azure, GCP |
| 12 | - **Integrate external secret stores** (AWS Secrets Manager, Azure Key Vault, Vault, 1Password) |
| 13 | - **Version and audit** all configuration changes |
| 14 | - **Control access** with fine-grained RBAC |
| 15 | |
| 16 | ## Essential CLI Commands |
| 17 | |
| 18 | ```bash |
| 19 | # Create a new environment |
| 20 | pulumi env init <org>/<project-name>/<environment-name> |
| 21 | |
| 22 | # Edit environment (opens in editor) |
| 23 | pulumi env edit <org>/<project-name>/<environment-name> |
| 24 | |
| 25 | # Set values |
| 26 | pulumi env set <org>/<project-name>/<environment-name> <key> <value> |
| 27 | pulumi env set <org>/<project-name>/<environment-name> <key> <value> --secret |
| 28 | |
| 29 | # View definition (secrets hidden) |
| 30 | pulumi env get <org>/<project-name>/<environment-name> |
| 31 | |
| 32 | # Open and resolve (reveals secrets) |
| 33 | pulumi env open <org>/<project-name>/<environment-name> |
| 34 | |
| 35 | # Run command with environment |
| 36 | pulumi env run <org>/<project-name>/<environment-name> -- <command> |
| 37 | |
| 38 | # Link to Pulumi stack |
| 39 | pulumi config env add <project-name>/<environment-name> |
| 40 | ``` |
| 41 | |
| 42 | ## Key Concepts |
| 43 | |
| 44 | ### Command Distinctions |
| 45 | |
| 46 | - **`pulumi env get`**: Shows static definition, secrets appear as `[secret]` |
| 47 | - **`pulumi env open`**: Resolves and reveals all values including secrets and dynamic credentials |
| 48 | - **`pulumi env run`**: Executes commands with environment variables loaded |
| 49 | - **`pulumi config env add`**: Only takes the <project-name>/<environment-name> portion |
| 50 | |
| 51 | ### Environment Structure |
| 52 | |
| 53 | Environments are YAML documents with reserved top-level keys: |
| 54 | |
| 55 | - **`imports`**: Import and compose other environments |
| 56 | - **`values`**: Define configuration and secrets |
| 57 | |
| 58 | Reserved sub-keys under `values`: |
| 59 | |
| 60 | - **`environmentVariables`**: Map values to shell environment variables |
| 61 | - **`pulumiConfig`**: Configure Pulumi stack settings |
| 62 | - **`files`**: Generate files with environment data |
| 63 | |
| 64 | ### Basic Example |
| 65 | |
| 66 | ```yaml |
| 67 | imports: |
| 68 | - common/base-config |
| 69 | |
| 70 | values: |
| 71 | environment: production |
| 72 | region: us-west-2 |
| 73 | |
| 74 | dbPassword: |
| 75 | fn::secret: super-secure-password |
| 76 | |
| 77 | environmentVariables: |
| 78 | AWS_REGION: ${region} |
| 79 | DB_PASSWORD: ${dbPassword} |
| 80 | |
| 81 | pulumiConfig: |
| 82 | aws:region: ${region} |
| 83 | app:dbPassword: ${dbPassword} |
| 84 | ``` |
| 85 | |
| 86 | ### Reading Another Stack's Outputs |
| 87 | |
| 88 | Use the `fn::open::pulumi-stacks` provider to consume another stack's outputs. The |
| 89 | `stacks` and `network` keys below are arbitrary names you choose. Once the function |
| 90 | resolves, it *replaces* `stacks.network` with the named stack's outputs — so the |
| 91 | output names (`vpcId`, `subnetIds`) do not appear in the static YAML; they come from |
| 92 | whatever the producer stack exports. Two things are easy to get wrong: |
| 93 | |
| 94 | - The stack is named by a single project-qualified `stack: <project>/<stackName>` |
| 95 | field — **not** separate `projectName`/`stackName` fields. |
| 96 | - Outputs resolve directly under the stack name — there is **no** `.outputs.` level |
| 97 | (use `${stacks.network.vpcId}`, not `${stacks.network.outputs.vpcId}`). |
| 98 | |
| 99 | Example — replace the stack name and output names with your own: |
| 100 | |
| 101 | ```yaml |
| 102 | values: |
| 103 | stacks: |
| 104 | fn::open::pulumi-stacks: |
| 105 | stacks: |
| 106 | network: # arbitrary local name for the referenced stack |
| 107 | stack: my-project/dev # producer stack to read outputs from |
| 108 | pulumiConfig: |
| 109 | # vpcId / subnetIds are whatever the producer stack exports; after the function |
| 110 | # resolves they are available directly under `stacks.network` (no `.outputs.`). |
| 111 | vpcId: ${stacks.network.vpcId} |
| 112 | subnetIds: ${stacks.network.subnetIds} |
| 113 | ``` |
| 114 | |
| 115 | Full schema: https://www.pulumi.com/docs/esc/providers/pulumi-stacks/ |
| 116 | |
| 117 | ### Viewing an Environment in the Pulumi Cloud Console |
| 118 | |
| 119 | The console URL for an environment is |
| 120 | `https://app.pulumi.com/<org>/esc/<project>/<environment>`. The route segment is |
| 121 | `esc`, not `environments`. |
| 122 | |
| 123 | ## Working with the User |
| 124 | |
| 125 | ### For Simple Questions |
| 126 | |
| 127 | If the user asks basic questions like "How do I create an environment?" or "What's the difference between get and open?", answer directly using the information above. |
| 128 | |
| 129 | ### For Detailed Documentation |
| 130 | |
| 131 | When users need more information, use the web-fetch tool to get content from the official Pulumi ESC documentation: |
| 132 | |
| 133 | - **Complete YAML syntax and functions** → https://www.pulumi.com/docs/esc/environments/syntax/ |
| 134 | - **Provider integrations** (AWS, Azure, GCP, Vault, 1Password): |
| 135 | - AWS: https://www.p |