Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 104 additions & 0 deletions .claude/commands/add-borders.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
---
description: Add 1px grey borders to PNG images in a documentation file.
---

# Usage

`/add-borders <doc-file-path>`

Analyze PNG images referenced in the specified markdown file at {{arg}} and add 1px #999999 (medium grey) borders to any images that don't already have them. This improves visual clarity and consistency of screenshots and diagrams in documentation.

---

## Process

### 1. Verify prerequisites

Before running the border tool, ensure dependencies are installed:

```bash
cd /workspaces/src/pulumi/docs/scripts/image-borders && pipenv install
```

If this is the first run or if Pillow is not yet installed, the installation will complete automatically.

### 2. Run the border addition tool

Execute the Python script with the provided documentation file:

```bash
cd /workspaces/src/pulumi/docs && pipenv run python scripts/image-borders/add_borders.py {{arg}}
```

The script will:
- Parse the markdown file to find all PNG image references
- Check each image's edge pixels to detect existing borders
- Add a 1px #999999 border to images that don't have one
- Skip images that already have a grey border (within tolerance)
- Display a summary of modified and skipped images

### 3. Review the results

The script outputs:
- **Modified**: Images that received new borders
- **Skipped**: Images that already had borders

Example output:
```
Found 3 PNG image(s)

✓ Added border: content/docs/esc/assets/create-environment.png
✓ Added border: content/docs/esc/assets/editor-before-save.png
⊘ Skipped (has border): content/docs/esc/assets/editor-after-save.png

Summary:
Modified: 2
Skipped: 1
```

### 4. Verify the changes

After borders are added:
1. View the modified images to ensure borders look correct
2. Check that border width and color (#CCCCCC) are appropriate
3. Verify the images still display correctly in the documentation

You can preview the documentation locally:
```bash
make serve
```

Then navigate to the affected page at http://localhost:1313

### 5. Commit the changes (if appropriate)

If the borders improve the documentation quality, commit the modified images:

```bash
git add <image-files>
git commit -m "Add 1px borders to documentation images for visual clarity"
```

---

## Options

The script supports additional options:

- `--dry-run` - Show what would be done without making changes
- `--repo-root <path>` - Specify repository root (auto-detected by default)

Example with dry run:
```bash
pipenv run python scripts/image-borders/add_borders.py {{arg}} --dry-run
```

---

## Notes

- The script uses edge pixel analysis to detect existing borders with 80% confidence threshold
- Handles RGBA images (preserves transparency)
- Uses #999999 (medium grey) for visibility on both white and light backgrounds
- Only processes PNG files (ignores JPG, GIF, SVG, etc.)
- Modifies images in place (use git to revert if needed)
13 changes: 10 additions & 3 deletions .claude/commands/glow-up.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,13 @@ Read the entire target file and perform comprehensive analysis:

For each image or diagram referenced in the document:

1. Use the Read tool to view the image
2. Analyze the image for the following issues:
1. **Check for missing borders on PNG images**: Run the border detection script with dry-run mode to deterministically identify which PNG images need borders:
```bash
cd /workspaces/src/pulumi/docs/scripts/image-borders && pipenv run python add_borders.py <file-path> --dry-run
```
The script will report which images would be modified vs skipped.

2. Regardless of existing borders, use the Read tool to view the image and analyze the image for the following issues:

**Screenshots:**
- Missing or inadequate alt text (accessibility requirement)
Expand Down Expand Up @@ -163,6 +168,7 @@ Develop a detailed plan organized by issue category:
- Images to convert to Mermaid/GoAT
- Unnecessary images to remove
- File format or size optimizations
- PNG images that need 1px grey borders for visual clarity

**7. Content enhancements** — List specific recommendations:
- Unclear sections that need rewriting
Expand Down Expand Up @@ -204,7 +210,8 @@ Once approved, implement the changes in logical order:
4. **Style improvements** (remove filler, simplify sentences, active voice)
5. **Link improvements** (improve link text, add cross-references)
6. **Image improvements** (add alt text, remove unnecessary images, flag outdated screenshots)
7. **Content enhancements** (rewrite unclear sections, add context)
7. **Add borders to PNG images** (run `/add-borders <file-path>` if PNG images need borders)
8. **Content enhancements** (rewrite unclear sections, add context)

Use the TodoWrite tool to track progress through the improvements.

Expand Down
11 changes: 11 additions & 0 deletions Pipfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"

[packages]

[dev-packages]

[requires]
python_version = "3.11"
8 changes: 8 additions & 0 deletions STYLE-GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,14 @@ The symbol is not needed in regular in-text links within documentation pages.

---

## Images and Media

- Use relative paths for images stored in the same directory or a subdirectory.
- Provide descriptive alt text for all images.
- For partial screenshots where the image may be hard to distinguish from the page background, add a 1px gray #999999 border.

---

## Notes / Callouts

Use the `{{ notes }}` shortcode sparingly. Supported levels:
Expand Down
2 changes: 1 addition & 1 deletion content/docs/deployments/deployments/cloud-credentials.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ menu:
In order for a Pulumi IaC operation like `update` or `preview` work, the Pulumi CLI must be able to access credentials that will allow it to perform the necessary CRUD operations on the resources in your stack. In order for Pulumi Deployments to access the necessary cloud credentials to run your Pulumi operation there are two common approaches you can take:

1. **Use [Pulumi Deployments' OIDC integration](/docs/deployments/deployments/oidc/)** where possible (we support [AWS](/docs/deployments/deployments/oidc/aws/), [Azure](/docs/deployments/deployments/oidc/azure/), and [Google Cloud](/docs/deployments/deployments/oidc/gcp/)), and store any remaining required secrets or configuration in [Pulumi Deployments Environment Variables](/docs/deployments/deployments/reference/#deployment-settings).
2. **Use [Pulumi ESC](/docs/esc/)** to define an Environment (or Environments), and [import the environment(s) into your stack](/docs/esc/get-started/integrate-with-pulumi-iac/).
2. **Use [Pulumi ESC](/docs/esc/)** to define an Environment (or Environments), and [import the environment(s) into your stack](/docs/esc/guides/integrate-with-pulumi-iac/).

## Choosing between Pulumi ESC Environments and Pulumi Deployments OIDC

Expand Down
Binary file removed content/docs/esc/assets/esc-create-environment.png
Binary file not shown.
127 changes: 98 additions & 29 deletions content/docs/esc/concepts/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
title: Concepts
title_tag: Pulumi ESC Concepts
h1: Pulumi ESC Concepts
meta_desc: Pulumi ESC allows you to compose and manage hierarchical collections of configuration and secrets and consume them in various ways.
meta_desc: Learn the core concepts of Pulumi ESC including environments, providers, composition, and the evaluation model.
menu:
esc:
parent: esc-home
Expand All @@ -12,58 +12,127 @@ aliases:
- /docs/concepts/environments/
---

Pulumi ESC (Environments, Secrets, and Configuration) simplifies how organizations manage secrets and configurations across multiple environments. It enables teams to compose collections of configuration and secrets called *environments*, which can be consumed by various infrastructure and application services. ESC helps ensure security, consistency, and efficiency in handling secrets and configuration.
Pulumi ESC (Environments, Secrets, and Configuration) is a secrets and configuration management system built around four core concepts: environments, sources, targets, and management. Understanding these concepts will help you build a mental model of how ESC works.

Pulumi ESC is offered both as a fully managed cloud service in [Pulumi Cloud](/docs/pulumi-cloud/) and self-hosted for scenarios that require isolated environments. ESC has native integration with several products and other Pulumi products, including Pulumi Infrastructure as Code (IaC). The [pulumi/esc project](https://github.com/pulumi/esc) is open source, and contains the evaluation engine for environments, the `esc` CLI.
Pulumi ESC is available as a fully managed service in [Pulumi Cloud](/docs/pulumi-cloud/) and can be self-hosted for isolated environments. The [pulumi/esc project](https://github.com/pulumi/esc) is open source and contains the evaluation engine and CLI.

{{< figure src="/docs/esc/assets/pulumi_esc.png" caption="Figure: The Pulumi ESC ecosystem.">}}

The diagram above shows four key concepts:
## Core concepts

1. ***Environments***: ESC environments are collections of secrets and configuration. Environments are composable from multiple environments and draw from both static and dynamic sources and can be shared to many targets.
### Environments

2. ***Sources***: ESC can *input* configuration and secrets from a variety of sources, and it has an extensible plugin model for integrating third-party sources. ESC's built-in support for dynamic secret providers, allows for best-practices like generating short-term credentials via OIDC, and dynamically pulling secret values at the time of use, for all major cloud providers.
An environment is a named collection of configuration values and secrets defined in YAML. Environments are the fundamental unit of organization in ESC. Each environment:

3. ***Targets***: ESC *outputs* configuration and secrets to a variety of popular targets. Pulumi ESC has a rich API that allows for easy integration, and provides standard output mechanisms like environment variables and key files.
- Has a unique name within a project (e.g., `my-org/my-project/production`)
- Contains a YAML document that defines values, imports other environments, and configures providers
- Is versioned—every change creates a new version
- Can be tagged for easier reference (e.g., `stable`, `v1.2.3`)
- Is evaluated when opened, resolving all dynamic values and imports

4. ***Management***: ESC environments are centrally managed in Pulumi Cloud, and can be permissioned with RBAC, versioned, tagged, and audited. ESC secrets are encrypted in flight and at rest.
Environments are composable: one environment can import others, inheriting and overriding their values. This enables organizing configuration hierarchically to match team boundaries and security requirements.

## The ESC Approach
### Sources

Pulumi ESC takes a distinct approach to managing secrets and configuration that is different from other secret managers. ESC emphasizes flexibility and an open-ecosystem approach to integrations and is specifically designed for managing secrets and configurations across complex multi-cloud environments. Whether used in conjunction with [Pulumi IaC](/docs/iac/) or as a standalone tool, ESC helps streamline operations, reduce duplication, and enhance security for teams across a wide range of use cases.
ESC pulls configuration and secrets from multiple sources through an extensible provider system:

### Centralized management, composability, and reusability
- **Static values** - Key-value pairs defined directly in the environment YAML
- **Dynamic providers** - Plugins that generate or retrieve values at evaluation time:
- OIDC providers generate short-lived cloud credentials (AWS, Azure, GCP, Vault)
- Secret providers retrieve values from external systems (AWS Secrets Manager, Azure Key Vault, 1Password)
- Login providers authenticate with cloud services

Pulumi ESC aggregates secrets and configuration from different sources into *environments*. These environments can be composed from other environments, allowing for flexible organization and reuse without duplication.
Dynamic providers execute when an environment is opened, not when it's defined. This ensures credentials and secrets are fresh and never stored.

Pulumi ESC provides fine-grained **Role-Based Access Control (RBAC)**, ensuring that only authorized users and teams can access specific environments and retrieve secrets. Audit logs track who accessed or changed the configurations, enhancing security and accountability.
### Targets

ESC outputs configuration and secrets to multiple targets:

- **Environment variables** - Inject secrets into processes via the `esc run` command
- **Configuration APIs** - Access values programmatically through SDKs (TypeScript, Python, Go)
- **Pulumi IaC** - Reference environments in `Pulumi.<stack>.yaml` files
- **CLI output** - View values with `esc env open` or `esc env get`
- **Kubernetes** - Sync secrets to Kubernetes clusters via the ESC operator
- **Other tools** - Integrate with Terraform, Docker, and developer tools

The same environment can output to multiple targets simultaneously, centralizing secrets management across different tools.

### Management

Environments are centrally managed in Pulumi Cloud with:

- **Role-Based Access Control (RBAC)** - Control who can read, write, or delete environments
- **Audit logs** - Track all access and modifications to environments
- **Versioning** - Every change creates a new immutable version
- **Tagging** - Label versions for rollback or staged deployments
- **Encryption** - All secrets are encrypted at rest and in transit
- **Customer-managed keys** - Optionally encrypt with your own keys

## Environment composition

Environments support composition through imports, allowing you to build complex configurations from reusable pieces. Consider this example:

{{< figure src="team_environments.png" caption="Figure: Composable ESC environments facilitate team-based organization.">}}

Pulumi ESC environments can be structured to reflect an organization’s team structure, security boundaries, or deployment targets. The above diagram shows an example of how a customer might organize and compose different security environments.
An organization might structure environments by team and security boundaries:

- **Central platform team** - Owns common configuration like OIDC settings and feature flags
- **Billing service team** - Manages payment processor secrets
- **Communications team** - Manages secrets for mailing and texting services

Each team's environment can be independently permissioned and versioned. Application environments import these base environments and add application-specific configuration. When environments import others, values are merged using JSON Merge Patch semantics—later values override earlier ones.

This structure:

- Reduces duplication by sharing common configuration
- Enforces security boundaries through separate permissions per environment
- Allows teams to update their environments without affecting others
- Enables complex applications to compose from multiple security contexts

## Static vs. dynamic values

ESC supports both static and dynamic values in the same environment:

**Static values** are defined directly in the YAML and evaluated once:

Imagine a hypothetical development organization comprised of a few teams:
```yaml
values:
region: us-west-2
apiEndpoint: https://api.example.com
```

* The *billing service* team, that manages secrets/config for the payment processor
* The *communications* team, that manages secrets/config for the mailing service and texting service.
* The *central platform* team, that owns most common config, including OIDC config and the keys/config for the feature flag system.
**Dynamic values** are generated or retrieved when the environment is opened:

Permissions to these environments can be defined separately to minimize security exposure. They can be reused independently or composed into more complex application scenarios.
```yaml
values:
aws:
login:
fn::open::aws-login:
oidc:
roleArn: arn:aws:iam::123456789012:role/my-role
environmentVariables:
AWS_ACCESS_KEY_ID: ${aws.login.accessKeyId}
```

### Dynamic vs static configurations
Dynamic providers execute during evaluation, generating fresh credentials or retrieving current values. This ensures credentials are short-lived and secrets are never stale.

Pulumi ESC supports both **static** configurations (e.g. simple key-value pairs) and **dynamic** configurations (values retrieved from third-party providers) in the same environment. This allows teams to mix-and-match the type of configuration they need.
## Configuration as code

Pulumi ESC also supports **dynamic secret providers**, such as AWS OIDC, Azure KeyVault, GCP Secrets Manager, and more. This allows teams to pull short-lived credentials or other secrets dynamically from external sources.
ESC environments are defined as YAML documents that can be:

More detail on dynamic secret providers is available in [Adding OIDC and secrets providers](/docs/esc/environments/working-with-environments/#using-secrets-providers-and-oidc). The [providers list](/docs/esc/integrations/) details the currently supported integrations.
- Edited directly in the Pulumi Cloud console
- Modified via the `esc` CLI
- Managed programmatically through SDKs (TypeScript, Python, Go)
- Automated in CI/CD pipelines via the API

### Configuration-as-Code, automation, and integration everywhere
Environments support:

Like our other products, Pulumi ESC uses an "as-code" approach to configuration and secrets. ESC environments can be composed, managed, and accessed using code written in TypeScript, JavaScript, Go, Python, or YAML. The `esc` CLI and our full-featured API allows for scripted use in automated environments like CI/CD. This reduces copy/paste style duplication of credentials and allows for management from a single source of truth. ESC is already deeply integrated into Pulumi IaC and Pulumi Cloud, and provides a number of third-party product integrations both as secrets providers and consumers.
- **Interpolation** - Reference other values with `${path.to.value}` syntax
- **Functions** - Transform values with built-in functions (`fn::secret`, `fn::toJSON`)
- **Type safety** - Values maintain their types (strings, numbers, objects, arrays)

## Learn More
## Learn more

* [How Pulumi ESC Works](/docs/esc/concepts/how-esc-works)
* The [ESC providers](/docs/esc/integrations/) list
* [Environments Overview](/docs/esc/environments/)
- [How Pulumi ESC works](/docs/esc/concepts/how-esc-works) - Architecture and evaluation model
- [ESC providers](/docs/esc/integrations/) - Full list of integrations
- [Environments reference](/docs/esc/environments/) - Complete syntax documentation
2 changes: 1 addition & 1 deletion content/docs/esc/environments/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ menu:
esc:
parent: esc-home
identifier: esc-environments
weight: 4
weight: 5
---

Pulumi ESC (Environments, Secrets, and Configuration) lets you define collections of configuration settings and secrets called _environments_ and use them in any application or service. Environments are YAML documents composed of static key-value pairs, programmatic expressions, dynamically retrieved values from supported providers including all major clouds through OpenID Connect (OIDC), and other Pulumi ESC environments.
Expand Down
Loading
Loading