<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0"><channel><title>Pulumi Blog: Configuration management</title><link>https://www.pulumi.com/blog/tag/configuration-management/</link><description>Pulumi blog posts: Configuration management.</description><language>en-us</language><pubDate>Thu, 23 Jul 2026 00:00:00 +0000</pubDate><item><title>Preview ESC Changes with Environment Overrides</title><link>https://www.pulumi.com/blog/preview-esc-environment-changes-with-draft-references/</link><pubDate>Thu, 23 Jul 2026 00:00:00 +0000</pubDate><guid>https://www.pulumi.com/blog/preview-esc-environment-changes-with-draft-references/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/preview-esc-environment-changes-with-draft-references/index.png" /&gt;
&lt;p&gt;&lt;a href="https://www.pulumi.com/docs/esc/"&gt;Pulumi ESC&lt;/a&gt; makes it easy to store configuration and secrets for your Pulumi programs, and with &lt;a href="https://www.pulumi.com/docs/esc/concepts/approvals/"&gt;Approvals for ESC&lt;/a&gt; you can review and approve changes before they go live. The new &lt;code&gt;--override-env&lt;/code&gt; flag lets you preview any environment change, including an unapproved draft, to see exactly how it would affect your stack before it becomes the latest version.&lt;/p&gt;
&lt;h2 id="example-scenario"&gt;Example scenario&lt;/h2&gt;
&lt;p&gt;Your team stores production app configuration in ESC and has enabled &lt;a href="https://www.pulumi.com/docs/esc/concepts/approvals/"&gt;Approvals&lt;/a&gt; to keep bad values out of critical infrastructure. But one important question remains: how can reviewers properly validate a configuration change before approving it?&lt;/p&gt;
&lt;h2 id="introducing-draft-references-and-the-override-env-flag"&gt;Introducing: draft references and the &amp;ndash;override-env flag&lt;/h2&gt;
&lt;p&gt;We are introducing a new &lt;code&gt;--override-env&lt;/code&gt; flag to the Pulumi CLI that works with every Pulumi operation that can consume ESC environments: &lt;code&gt;preview&lt;/code&gt;, &lt;code&gt;up&lt;/code&gt;, &lt;code&gt;refresh&lt;/code&gt;, and &lt;code&gt;destroy&lt;/code&gt;. This makes it easy to test configuration changes on the fly, giving your team the confidence to validate them as part of the review process.&lt;/p&gt;
&lt;h3 id="example-usages"&gt;Example usages&lt;/h3&gt;
&lt;p&gt;The basic usage is &lt;code&gt;--override-env &amp;lt;env&amp;gt;=&amp;lt;replacement&amp;gt;&lt;/code&gt;, and you can override multiple environments at once!
In this example, we are running a &lt;code&gt;pulumi preview&lt;/code&gt; with environments &lt;code&gt;app/myenv&lt;/code&gt; and &lt;code&gt;app/myenv2&lt;/code&gt; replaced by their draft versions (denoted by &lt;code&gt;@draft:&amp;lt;draft-id&amp;gt;&lt;/code&gt;).&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;pulumi preview \
--override-env &amp;#34;app/myenv=app/myenv@draft:123e4567-e89b-12d3-a456-426614174000&amp;#34; \
--override-env &amp;#34;app/myenv2=app/myenv2@draft:123e4567-e89b-12d3-a456-426614174000&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;--override-env&lt;/code&gt; flag not only works with draft references, but for any environment too! Here is an example of deploying your stack with your AWS test environment:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;pulumi up --override-env &amp;#34;aws-login/prod=aws-login/testing&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Note: &lt;code&gt;--override-env&lt;/code&gt; can also override environments that are imported (directly or indirectly) from the ESC environment in your stack config. This allows you to override any environment in the import chain for full flexibility.&lt;/p&gt;
&lt;h2 id="ways-to-use-it"&gt;Ways to use it&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Validate a draft ESC environment with your stack before approving&lt;/li&gt;
&lt;li&gt;One-off debugging without editing stack config&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="get-started"&gt;Get started&lt;/h2&gt;
&lt;p&gt;Draft references and &lt;code&gt;--override-env&lt;/code&gt; are available today in the Pulumi CLI. Upgrade to the &lt;a href="https://www.pulumi.com/docs/install/"&gt;latest release&lt;/a&gt; and try it out! To learn more:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/docs/esc/"&gt;Pulumi ESC documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/docs/esc/concepts/approvals/"&gt;Approvals for ESC&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pulumi.com/docs/esc/get-started/"&gt;Get started with Pulumi ESC&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description><author>Sean Yeh</author><category>esc</category><category>features</category><category>configuration-management</category></item><item><title>Announcing Doppler Providers for Pulumi ESC: Dynamic Login and Dynamic Secrets</title><link>https://www.pulumi.com/blog/esc-doppler-providers-launch/</link><pubDate>Thu, 26 Jun 2025 00:00:00 +0000</pubDate><guid>https://www.pulumi.com/blog/esc-doppler-providers-launch/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/esc-doppler-providers-launch/index.png" /&gt;
&lt;p&gt;We are excited to announce support for &lt;a href="https://doppler.com/"&gt;Doppler&lt;/a&gt; within &lt;a href="https://www.pulumi.com/product/esc"&gt;Pulumi ESC&lt;/a&gt;! Pulumi ESC centralizes secrets and configuration management, providing a unified source of truth across your environments. With the addition of Doppler, a popular secrets management platform, ESC further extends its ecosystem, enabling seamless and secure access to secrets stored across diverse systems.&lt;/p&gt;
&lt;p&gt;This release introduces two distinct dynamic providers for Doppler, each designed to improve security and streamline your workflows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.pulumi.com/docs/esc/integrations/dynamic-login-credentials/doppler-login/"&gt;&lt;code&gt;doppler-login&lt;/code&gt;&lt;/a&gt; (Dynamic Login):&lt;/strong&gt; This provider securely generates short-lived OIDC access tokens for authenticating &lt;em&gt;to&lt;/em&gt; Doppler. Static, long-lived credentials are a significant security risk. The &lt;code&gt;doppler-login&lt;/code&gt; provider directly addresses this by generating temporary, just-in-time credentials using OIDC. &lt;strong&gt;Use this provider when you need temporary credentials to interact directly with Doppler&lt;/strong&gt;, for instance, using the Doppler CLI or SDKs in local development or CI/CD pipelines, without storing long-lived static tokens. ESC manages the OIDC flow, providing a fresh token when needed.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.pulumi.com/docs/esc/integrations/dynamic-secrets/doppler-secrets/"&gt;&lt;code&gt;doppler-secrets&lt;/code&gt;&lt;/a&gt; (Dynamic Secrets):&lt;/strong&gt; This provider dynamically fetches secrets stored &lt;em&gt;within&lt;/em&gt; your Doppler configs and makes them available within the Pulumi ESC environment. &lt;strong&gt;Use this provider when you need specific secrets &lt;em&gt;from&lt;/em&gt; Doppler to configure your applications or infrastructure managed via ESC.&lt;/strong&gt; This centralizes secret consumption, allowing you to access Doppler secrets using the same consistent ESC patterns used for AWS, Azure, GCP, Infisical, Vault, 1Password, and more.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Pulumi ESC acts as a robust &lt;strong&gt;secrets broker&lt;/strong&gt; provider consistent API interface for all your tools, applications and workflows. It securely handles &lt;em&gt;both&lt;/em&gt; the generation of temporary authentication credentials (like with &lt;code&gt;doppler-login&lt;/code&gt;) and the fetching of application secrets (like with &lt;code&gt;doppler-secrets&lt;/code&gt;) from various providers such as Doppler, cloud platforms (&lt;a href="https://www.pulumi.com/docs/esc/integrations/dynamic-secrets/aws-secrets/"&gt;AWS&lt;/a&gt;, &lt;a href="https://www.pulumi.com/docs/esc/integrations/dynamic-secrets/azure-secrets/"&gt;Azure&lt;/a&gt;, &lt;a href="https://www.pulumi.com/docs/esc/integrations/dynamic-secrets/gcp-secrets/"&gt;GCP&lt;/a&gt;), and other secret managers (&lt;a href="https://www.pulumi.com/docs/esc/integrations/dynamic-secrets/infisical-secrets/"&gt;Infisical&lt;/a&gt;, &lt;a href="https://www.pulumi.com/docs/esc/integrations/dynamic-secrets/vault-secrets/"&gt;Vault&lt;/a&gt;, &lt;a href="https://www.pulumi.com/docs/esc/integrations/dynamic-secrets/1password-secrets/"&gt;1Password&lt;/a&gt;). Once centralized in ESC, these secrets and configurations are consistently available for you to consume via ESC&amp;rsquo;s many developer friendly methods including the &lt;a href="https://www.pulumi.com/docs/esc/development/languages-sdks/"&gt;ESC SDK&lt;/a&gt;, &lt;a href="https://www.pulumi.com/docs/iac/cli/commands/pulumi_env/"&gt;Pulumi CLI&lt;/a&gt;, &lt;a href="https://www.pulumi.com/docs/esc/integrations/kubernetes/external-secrets-operator/"&gt;Kubernetes External Secrets Operator&lt;/a&gt;, &lt;a href="https://www.pulumi.com/docs/esc/integrations/kubernetes/secret-store-csi-driver/"&gt;CSI Driver&lt;/a&gt;, or sync them to various platforms where they are needed such as &lt;a href="https://github.com/pulumi/esc-examples/tree/main/sync/github-secrets"&gt;GitHub Secrets&lt;/a&gt;, &lt;a href="https://github.com/pulumi/esc-examples/tree/main/sync/aws-secrets-manager"&gt;AWS Secrets Manager&lt;/a&gt;, and more!&lt;/p&gt;
&lt;h2 id="getting-started-using-the-doppler-providers"&gt;Getting Started: Using the Doppler Providers&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s walk through how to configure and use each provider.&lt;/p&gt;
&lt;h3 id="prerequisites"&gt;Prerequisites&lt;/h3&gt;
&lt;p&gt;Your Doppler workplace must be on the Team or Enterprise plan in order to use OIDC (via service account identities).&lt;/p&gt;
&lt;p&gt;Configure Doppler for OpenID Connect(OIDC) before you try out the providers. Follow the steps in &lt;a href="https://www.pulumi.com/docs/esc/environments/configuring-oidc/doppler/"&gt;Doppler OIDC documentation&lt;/a&gt;. This involves creating a Service Account Identity in Doppler, with OIDC authentication pointing to &lt;code&gt;https://api.pulumi.com/oidc&lt;/code&gt;, and configuring the audience and subject claims. Note down the &lt;strong&gt;Identity ID&lt;/strong&gt;.&lt;/p&gt;
&lt;h3 id="how-to-use-the-doppler-login-provider-dynamic-authentication"&gt;How to Use the doppler-login Provider (Dynamic Authentication)&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Create a Pulumi ESC environment (e.g., &lt;code&gt;pulumi-org/doppler-auth/oidc-login&lt;/code&gt;) with the following environment definition and update the &lt;code&gt;identityId&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# Environment: pulumi-org/doppler-auth/oidc-login&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;values&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;doppler&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Configure the Dynamic Login provider using OIDC&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;login&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;fn::open::doppler-login&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;oidc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;identityId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;&amp;lt;your-identity-id&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Replace with your Doppler Identity ID&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Expose the token as an environment variable for easy consumption&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;environmentVariables&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;DOPPLER_TOKEN&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;${doppler.login.accessToken}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Save the environment.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Validate the environment by clicking on Open in the Pulumi Cloud console, or running &lt;code&gt;pulumi env open pulumi-org/doppler-auth/oidc-login&lt;/code&gt; in your CLI. The output will include the &lt;code&gt;doppler.login.accessToken&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Usage Example: Run Doppler CLI commands dynamically:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pulumi env run pulumi-org/doppler-auth/oidc-login -- doppler secrets download --no-file --format&lt;span class="o"&gt;=&lt;/span&gt;json --project&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;your-project-id&amp;gt; --config&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;your-config-id&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# The DOPPLER_TOKEN env var is automatically injected&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="how-to-use-the-doppler-secrets-provider-dynamically-fetching-secrets"&gt;How to Use the doppler-secrets Provider (Dynamically Fetching Secrets)&lt;/h3&gt;
&lt;p&gt;Use this provider to pull secrets &lt;em&gt;from&lt;/em&gt; Doppler &lt;em&gt;into&lt;/em&gt; your ESC environment for consumption by your applications, CI/CD systems, Pulumi IaC, Terraform and more!&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Create an ESC environment where you need the secrets (e.g., &lt;code&gt;pulumi-org/my-app/dev&lt;/code&gt;).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Import&lt;/strong&gt; the dynamic login environment (if using OIDC for authentication, which is recommended). This makes the temporary Doppler token available.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Configure the &lt;code&gt;doppler-secrets&lt;/code&gt; provider, referencing the imported login details. See example below.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Specify the secrets to fetch using the &lt;code&gt;get&lt;/code&gt; block. Replace placeholders.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# Environment: pulumi-org/my-app/dev&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;imports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Import the environment performing Dynamic Login (recommended)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;pulumi-org/doppler-auth/oidc-login&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Use the path to your login environment&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;values&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Define a structure to hold secrets fetched from Doppler&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;dopplerSecrets&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;fn::open::doppler-secrets&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Authenticate using the token from the imported Dynamic Login environment&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;login&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;${doppler.login}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Pass the login object from the import&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Specify the Doppler project and config to retrieve secrets from&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;project&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;example-project&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;dev&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Specify secrets to retrieve from Doppler&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;get&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Define names for the secrets as they will appear in ESC&amp;#39;s output under &amp;#39;dopplerSecrets&amp;#39;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# This is the name within ESC&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;API_KEY&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# The name of the secret in Doppler&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;appSecret&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Pull another secret into ESC&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;APP_SECRET&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Optionally, map fetched secrets to environment variables for application consumption&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;environmentVariables&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;API_KEY&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;${dopplerSecrets.apiKey}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;APP_SECRET&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;${dopplerSecrets.appSecret}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Save the environment.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Validate the environment by clicking on Open in the Pulumi Cloud console, or running &lt;code&gt;pulumi env open pulumi-org/my-app/dev&lt;/code&gt; in your CLI. The output will show the imported &lt;code&gt;doppler.login&lt;/code&gt;, the fetched secrets under &lt;code&gt;dopplerSecrets&lt;/code&gt;, and the mapped &lt;code&gt;environmentVariables&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Usage Example:&lt;/strong&gt; Run an application that needs these secrets:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pulumi env run pulumi-org/my-app/dev -- node app.js
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# The API_KEY and APP_SECRET env vars are automatically injected&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;The new &lt;code&gt;doppler-login&lt;/code&gt; and &lt;code&gt;doppler-secrets&lt;/code&gt; providers for Pulumi ESC offer powerful and secure ways to interact with Doppler. Use &lt;code&gt;doppler-login&lt;/code&gt; for dynamic, short-lived OIDC authentication when interacting directly with Doppler APIs or CLIs. Use &lt;code&gt;doppler-secrets&lt;/code&gt; to securely fetch secrets &lt;em&gt;from&lt;/em&gt; Doppler &lt;em&gt;into&lt;/em&gt; your centralized ESC environment. Together, they enhance your security posture and simplify configuration management.&lt;/p&gt;
&lt;p&gt;We encourage you to explore these new capabilities. Dive into the &lt;a href="https://www.pulumi.com/docs/esc/integrations/dynamic-login-credentials/doppler-login/"&gt;doppler-login&lt;/a&gt;, &lt;a href="https://www.pulumi.com/docs/esc/integrations/dynamic-secrets/doppler-secrets/"&gt;doppler-secrets&lt;/a&gt; for detailed configuration options, check out the broader &lt;a href="https://www.pulumi.com/docs/esc/"&gt;Pulumi ESC Documentation&lt;/a&gt;, and share your feedback or ask questions in the &lt;a href="https://slack.pulumi.com/"&gt;Pulumi Community Slack&lt;/a&gt;.&lt;/p&gt;</description><author>Robert Harris</author><category>esc</category><category>secrets</category><category>doppler</category><category>features</category><category>configuration-management</category><category>dynamic-secrets</category><category>oidc</category></item><item><title>From Configuration Chaos to Programming Languages</title><link>https://www.pulumi.com/blog/config-chaos-to-programming-languages/</link><pubDate>Tue, 03 Jun 2025 00:00:00 +0000</pubDate><guid>https://www.pulumi.com/blog/config-chaos-to-programming-languages/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/config-chaos-to-programming-languages/index.png" /&gt;
&lt;p&gt;&lt;em&gt;This post is based on our video interview with Daniel Ward, a Software Developer/Consultant at Lean TECHniques and Microsoft MVP. Daniel shares his strategies for moving teams from configuration chaos to programming languages for infrastructure, including the 10% rule for change, viral adoption, and why Pulumi beats YAML for complex systems. Watch the video below or read on. - Adam Gordon Bell&lt;/em&gt;&lt;/p&gt;
&lt;div class="note note-info"&gt;
&lt;div class="icon-and-line"&gt;
&lt;svg xmlns="http://www.w3.org/2000/svg" class="ph-icon ph-icon--fill" fill="currentColor" aria-hidden="true" focusable="false"&gt;&lt;use href="https://www.pulumi.com/icons/sprite.70121449e0dde6f8c01ff68423fffaa0336ecc73c7bbc87506404126694ca58c.svg#p-info-fill"/&gt;&lt;/svg&gt;
&lt;div class="line"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="content"&gt;
Since this post was published, Pulumi has added first-class support for HashiCorp
Configuration Language (HCL). You can now write Pulumi programs in HCL directly, alongside
general-purpose languages like TypeScript, Python, Go, and C#. To see how it works, see
&lt;a href="https://www.pulumi.com/docs/iac/languages-sdks/hcl/"&gt;Pulumi HCL&lt;/a&gt;.
&lt;/div&gt;
&lt;/div&gt;
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;"&gt;
&lt;iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/3VKbaNtbdSs?rel=0?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"&gt;&lt;/iframe&gt;
&lt;/div&gt;
&lt;p&gt;Imagine your infrastructure codebase has evolved from a few files to thousands of lines across dozens of configuration files. Your team spends hours deciphering CloudFormation templates, your AWS CDK deployments take 30+ minutes, and introducing any change becomes a multi-day effort. This is the reality many organizations face when their infrastructure-as-code approach outgrows their tooling.&lt;/p&gt;
&lt;p&gt;As a consultant and developer who helps organizations improve their software delivery processes, I&amp;rsquo;ve seen firsthand how the right technologies—specifically using actual programming languages like C#—can transform infrastructure management instead of forcing teams to use declarative configuration files.&lt;/p&gt;
&lt;h2 id="my-background-coaching-teams-through-technical-transformation"&gt;My Background: Coaching Teams Through Technical Transformation&lt;/h2&gt;
&lt;p&gt;My background is primarily as a .NET developer—I&amp;rsquo;m now a Microsoft MVP in my first year—though I work with TypeScript and other languages as needed. About six years ago, I moved into consulting, or what we call &amp;ldquo;coaching&amp;rdquo; at Lean Techniques.&lt;/p&gt;
&lt;p&gt;The idea isn&amp;rsquo;t just to write code for clients or tell them what to do and leave. Our goal is that once we leave, they don&amp;rsquo;t need us anymore. We&amp;rsquo;re essentially trying to put ourselves out of a job.&lt;/p&gt;
&lt;p&gt;Organizations bring me in for various reasons—from implementing automated testing after costly failures to migrating from mainframes to the cloud. Sometimes it&amp;rsquo;s about product delivery challenges, like month-long sprints that never complete on time.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s about bringing places up to a modern standard. As we say at Lean Techniques, turning IT from a cost center into a competitive advantage.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;If you’re ready to move from sprawling configuration files to code-centric infrastructure, here are eight practical steps to guide you:&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="1-follow-the-10-rule-for-sustainable-change"&gt;1. Follow the 10% Rule for Sustainable Change&lt;/h2&gt;
&lt;p&gt;One of my guiding principles comes from Gerald Weinberg&amp;rsquo;s book &amp;ldquo;The Secrets of Consulting&amp;rdquo;: the 10% rule. When entering a new team or organization, don&amp;rsquo;t try to improve more than 10% at a time.&lt;/p&gt;
&lt;img src="secrets.jpg" alt="The Secrets of Consulting book cover" style="width: 40%; float: left; margin-right: 20px; margin-bottom: 10px;"&gt;
&lt;p&gt;There are a few reasons for this. One is that you can actually end up making the client look bad. If you improve everything at once, their boss might ask why this consultant fixed everything in six months when the team couldn&amp;rsquo;t fix it in five years.&lt;/p&gt;
&lt;p&gt;But there&amp;rsquo;s a deeper reason related to social dynamics. Any social group, in programming or outside of work—if you come in new and try to change how the group works before familiarizing yourself with it, people will be resistant. They&amp;rsquo;ll ask &amp;ldquo;Who do you think you are? You just got here!&amp;rdquo; And they&amp;rsquo;re right—you could be wrong about some things. You have to understand how they work to understand what the problems are.&lt;/p&gt;
&lt;p&gt;This applies directly to introducing new technologies like infrastructure as code. Rather than overhauling everything at once, I recommend starting small.&lt;/p&gt;
&lt;p&gt;If a place is completely new to infrastructure as code, I&amp;rsquo;ll tell them to start small. None of their engineers know how to do this yet, and I&amp;rsquo;m not going to do all the work for them and leave, because then none of their engineers will know how to maintain it.&lt;/p&gt;
&lt;h2 id="2-quantify-the-cost-of-inaction-to-overcome-resistance"&gt;2. Quantify the Cost of Inaction to Overcome Resistance&lt;/h2&gt;
&lt;p&gt;Even with a measured approach, resistance is inevitable. I&amp;rsquo;ve experienced teams that are exceptionally open to improvement, often coming from difficult situations and eager for change. I&amp;rsquo;ve also worked with teams that resist most suggestions, where engineers feel the consultant was forced upon them by management.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s always easier if you can do pull-based versus push-based change—where the team has asked for your help instead of the manager telling them &amp;ldquo;I&amp;rsquo;m inflicting this help on you.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;For those looking to influence change within their organization, I&amp;rsquo;ve found that influencing upper-level management comes down to numbers. They deal with too many teams to get into specifics—they want numbers. If you can show how many hours your team spends each week manually pushing code or waiting on another team, and multiply that by engineer salaries, you&amp;rsquo;re showing how much money is being wasted.&lt;/p&gt;
&lt;p&gt;This approach is far more effective than what can come across as &amp;ldquo;Here&amp;rsquo;s a new tool I want to play with&amp;rdquo;—an anti-pattern that reinforces the stereotype of technical people just wanting to use new technologies.&lt;/p&gt;
&lt;h2 id="3-build-consensus-with-nemawashi-conversations"&gt;3. Build Consensus with Nemawashi Conversations&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;ve found a Japanese concept called &amp;ldquo;nemawashi&amp;rdquo; (literally &amp;ldquo;turning the roots&amp;rdquo;) provides another effective approach to organizational change:&lt;/p&gt;
&lt;p&gt;&lt;img src="nemawashi.jpeg" alt="Nemawashi: Building consensus through individual conversations"&gt;&lt;/p&gt;
&lt;p&gt;Before introducing an idea to a manager or the whole team, individually go to every person on the team first and get their thoughts. If most people respond positively, you can then approach the decision-maker saying, &amp;ldquo;Everyone on the team wants this—what do you think?&amp;rdquo;&lt;/p&gt;
&lt;p&gt;This isn&amp;rsquo;t just about collecting checkmarks but genuinely gathering feedback. If you&amp;rsquo;re getting pushback from every single person, maybe it&amp;rsquo;s not as great an idea as you thought. Either way, you learn something from it.&lt;/p&gt;
&lt;h2 id="4-drive-viral-adoption-through-early-wins"&gt;4. Drive Viral Adoption Through Early Wins&lt;/h2&gt;
&lt;p&gt;Rather than forcing change on resistant teams, I prefer what I call &amp;ldquo;viral adoption&amp;rdquo;:&lt;/p&gt;
&lt;p&gt;We try to work with teams that ask for our help instead of being pushed onto teams. People are way less resistant if you can show them you&amp;rsquo;re making their job easier. We work with one team who wants our help, make them really effective, and then other teams notice: &amp;ldquo;How come they&amp;rsquo;re releasing so many times a week? How do they have so few defects? How is their pipeline so fast?&amp;rdquo;&lt;/p&gt;
&lt;p&gt;This success creates natural curiosity, leading other teams to either request similar help or study and adopt the successful team&amp;rsquo;s practices. Either way, I&amp;rsquo;m happy that things are improving.&lt;/p&gt;
&lt;h2 id="5-align-dev-and-ops-with-infrastructure-as-code"&gt;5. Align Dev and Ops with Infrastructure as Code&lt;/h2&gt;
&lt;p&gt;When it comes to infrastructure as code specifically, I&amp;rsquo;ve noticed it&amp;rsquo;s becoming table stakes for many organizations, though implementation quality varies widely.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s hard to have actual continuous delivery without infrastructure as code. Without it, developers can&amp;rsquo;t define their own infrastructure and have to wait on another team to do it. By continuous, I mean teams should be able to deploy every 30 minutes if they want. If you have to wait one to three business days for the operations team to create your resources, that&amp;rsquo;s not continuous.&lt;/p&gt;
&lt;p&gt;Resistance to infrastructure as code typically comes from two directions:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;From developers&lt;/strong&gt;: &amp;ldquo;I already have my plate full—now I have to learn cloud and deployment too?&amp;rdquo;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;From operations&lt;/strong&gt;: &amp;ldquo;That&amp;rsquo;s my job—I don&amp;rsquo;t want to lose it.&amp;rdquo;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I see this as a win-win opportunity for both sides. For operations teams, the job shifts from mundane tasks like &amp;ldquo;create a lambda for me&amp;rdquo; or &amp;ldquo;replace this code bundle&amp;rdquo; to more creative platform engineering work. For developers, the benefit is clear: no more waiting on operations to proceed with their work.&lt;/p&gt;
&lt;h2 id="6-invest-in-platform-engineering-for-reusable-components"&gt;6. Invest in Platform Engineering for Reusable Components&lt;/h2&gt;
&lt;p&gt;Platform engineering has emerged as a solution to these challenges. Instead of every team reinventing solutions for common needs like logging, monitoring, or deployment pipelines, platform teams create standardized, reusable components.&lt;/p&gt;
&lt;p&gt;It seems wasteful if every single team has to manage their own side of the Splunk instance or Dynatrace. These are solved problems that every team needs. A platform team can look across the organization, see what can be standardized, and remove those problems from individual teams.&lt;/p&gt;
&lt;p&gt;This approach is particularly powerful with tools like Pulumi, which allows creating reusable component resources for common patterns: &amp;ldquo;It&amp;rsquo;s very common for teams to create a Lambda-backed API Gateway or a Lambda hooked up to SQS. These are super common things, so here&amp;rsquo;s a component resource for that so you don&amp;rsquo;t have to write it yourself.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;The key difference in mindset is that platform teams aren&amp;rsquo;t enforcing rules—they&amp;rsquo;re building tools that make developers&amp;rsquo; lives easier. Instead of saying &amp;ldquo;You must do logging this way,&amp;rdquo; it&amp;rsquo;s &amp;ldquo;Here&amp;rsquo;s an endpoint you can use—you&amp;rsquo;re good to go.&amp;rdquo;&lt;/p&gt;
&lt;h2 id="7-avoid-yaml-pitfalls-embrace-programming-languages"&gt;7. Avoid YAML Pitfalls: Embrace Programming Languages&lt;/h2&gt;
&lt;p&gt;One of my pain points is the limitations of configuration languages like YAML for complex infrastructure. I recently gave a presentation about a GitHub Actions workflow that grew to over 1,000 lines, calling shared actions that call other shared actions, making it nearly impossible to understand what&amp;rsquo;s happening.&lt;/p&gt;
&lt;p&gt;I couldn&amp;rsquo;t use breakpoints or the normal libraries I would use. I&amp;rsquo;ve seen a 69,000-line YAML file for Prometheus and Kubernetes—that&amp;rsquo;s an auto-generated example, but even a thousand lines calling several other files is too much.&lt;/p&gt;
&lt;p&gt;The fundamental issue is abstraction. Programming languages allow loops, conditionals, and functions to remove repetition and build larger structures. Configuration languages often lack these capabilities, leading to copy-pasting and unmanageable growth.&lt;/p&gt;
&lt;p&gt;With declarative approaches, you end up using a lot of magic strings. It&amp;rsquo;s easy to forget one when you change values. The tooling is also an issue—I&amp;rsquo;m familiar with IDEs and libraries for programming languages, but the equivalent tools for YAML just aren&amp;rsquo;t as mature.&lt;/p&gt;
&lt;h2 id="8-choose-pulumi-for-flexible-code-first-iac"&gt;8. Choose Pulumi for Flexible, Code-First IaC&lt;/h2&gt;
&lt;p&gt;When comparing infrastructure-as-code options, I see three major players: AWS CDK, Terraform, and Pulumi. While AWS CDK offers similar capabilities to Pulumi for AWS resources, it relies on CloudFormation under the hood:&lt;/p&gt;
&lt;p&gt;CloudFormation is just a black box—it&amp;rsquo;s proprietary. If something goes wrong, you have to hope someone&amp;rsquo;s already asked about it on GitHub. When deployments take 15-30 minutes, there&amp;rsquo;s not much you can do—it&amp;rsquo;s just how CloudFormation works.&lt;/p&gt;
&lt;p&gt;Compared to Terraform, which uses HCL (HashiCorp Configuration Language), Pulumi offers the flexibility of actual programming languages:&lt;/p&gt;
&lt;p&gt;There&amp;rsquo;s nothing wrong with declarative approaches in some cases, but at a certain point—when you have big systems and chunks of resources you want to share between teams—it becomes more cumbersome than helpful. That&amp;rsquo;s why Terraform is working on their own CDK now.&lt;/p&gt;
&lt;p&gt;What sets Pulumi apart is its flexibility: Even if you have platform teams who aren&amp;rsquo;t developers and want to set standards, they can use YAML with Pulumi and then transform those component resources into other languages for dev teams to use. You get the best of all worlds.&lt;/p&gt;
&lt;h2 id="start-small-think-big-small-changes-big-impact"&gt;Start Small, Think Big: Small Changes, Big Impact&lt;/h2&gt;
&lt;p&gt;Whether you&amp;rsquo;re introducing infrastructure as code or any significant technical change, my advice remains consistent: start small, focus on solving real problems, and let success spread naturally.&lt;/p&gt;
&lt;p&gt;By understanding the human elements of change—the 10% rule, nemawashi, and viral adoption—you can transform resistance into enthusiasm. And by choosing tools like Pulumi that bridge the gap between developers and operations, you can create infrastructure that&amp;rsquo;s both powerful and maintainable.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m currently writing a blog series on Pulumi at &lt;a href="https://daninacan.com"&gt;daninacan.com&lt;/a&gt;. I also speak at conferences occasionally, so check out my speaking page if you&amp;rsquo;re interested.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Ready to escape configuration chaos? Start small, focus on solving real problems, and &lt;a href="https://www.pulumi.com/docs/get-started/"&gt;get started with Pulumi&lt;/a&gt; to leverage the full power of programming languages for infrastructure. Join &lt;a href="https://slack.pulumi.com/"&gt;our community Slack&lt;/a&gt; to connect with engineers making the same transformation.&lt;/em&gt;&lt;/p&gt;</description><author>Daniel Ward</author><author>Adam Gordon Bell</author><category>infrastructure-as-code</category><category>consulting</category><category>configuration-management</category><category>programming-languages</category></item><item><title>Announcing Snowflake Dynamic and Rotated Credentials with Pulumi ESC</title><link>https://www.pulumi.com/blog/esc-snowflake-providers-launch/</link><pubDate>Thu, 01 May 2025 00:00:00 +0000</pubDate><guid>https://www.pulumi.com/blog/esc-snowflake-providers-launch/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/esc-snowflake-providers-launch/index.png" /&gt;
&lt;p&gt;Snowflake is the data cloud powerhouse for countless businesses, critical for everything from customer dashboards to billing pipelines. The stakes are immense: this data must be strictly secured and always available. But managing this with static credentials or manual key rotation creates persistent security vulnerabilities and introduces operational instability, risking disruptions during clumsy updates. &lt;a href="https://www.pulumi.com/product/esc"&gt;Pulumi ESC&lt;/a&gt; eliminates this dilemma with two purpose-built Snowflake integrations:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://www.pulumi.com/docs/esc/integrations/dynamic-login-credentials/snowflake-login/"&gt;&lt;code&gt;snowflake-login&lt;/code&gt;&lt;/a&gt;:&lt;/strong&gt; Provides dynamic, short-lived OIDC tokens for temporary authentication &lt;em&gt;to&lt;/em&gt; Snowflake.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://www.pulumi.com/docs/esc/integrations/rotated-secrets/snowflake-user/"&gt;&lt;code&gt;snowflake-user&lt;/code&gt;&lt;/a&gt;:&lt;/strong&gt; Automates the rotation of RSA keypair secrets &lt;em&gt;for&lt;/em&gt; Snowflake users, essential for secure key-pair authentication.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Pulumi ESC allows you to securely manage and consume these Snowflake credentials in your applications, development workflows through &lt;a href="https://www.pulumi.com/docs/esc/development/languages-sdks/"&gt;ESC SDK&lt;/a&gt;, &lt;a href="https://www.pulumi.com/docs/iac/cli/commands/pulumi_env/"&gt;Pulumi CLI&lt;/a&gt;, &lt;a href="https://www.pulumi.com/docs/esc/integrations/kubernetes/"&gt;Kubernetes integrations&lt;/a&gt;, and more!&lt;/p&gt;
&lt;h2 id="snowflake-login-dynamic-oidc-authentication-for-temporary-access"&gt;snowflake-login: Dynamic OIDC Authentication for Temporary Access&lt;/h2&gt;
&lt;p&gt;Use the &lt;code&gt;snowflake-login&lt;/code&gt; provider when you need temporary, just-in-time credentials to interact with Snowflake, such as from local development environments, CI/CD pipelines, or scripts. It leverages OIDC to mint short-lived access tokens, eliminating the need to store static tokens.&lt;/p&gt;
&lt;p&gt;This approach significantly reduces the attack surface by removing long-lived credentials required for &lt;em&gt;authentication&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Setup:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Configure OIDC in Snowflake:&lt;/strong&gt; Create a Security Integration in Snowflake to trust the Pulumi OIDC provider (&lt;code&gt;https://api.pulumi.com/oidc&lt;/code&gt;), map the appropriate user claims and create a Snowflake user. Check out the &lt;a href="https://www.pulumi.com/docs/esc/integrations/dynamic-login-credentials/snowflake-login/#configuring-oidc-for-snowflake"&gt;docs&lt;/a&gt;] for more details&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Configure ESC Environment:&lt;/strong&gt; Define the &lt;code&gt;snowflake-login&lt;/code&gt; provider in your ESC environment, specifying the Snowflake account and the user configured for OIDC.&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# my-org/logins/snowflake&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;values&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;snowflake&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;login&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;fn::open::snowflake-login&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;oidc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;account&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;myorganization-account&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ESC_LOGIN_USER&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ESC_ROLE &lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Optional&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;When this environment is opened, ESC securely handles the OIDC flow and makes the temporary token available under &lt;code&gt;snowflake.login.token&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="snowflake-user-automated-rotation-for-rsa-key-secrets"&gt;snowflake-user: Automated Rotation for RSA Key Secrets&lt;/h2&gt;
&lt;p&gt;For applications or services using Snowflake&amp;rsquo;s key-pair authentication, maintaining the security of those RSA keys is crucial. The &lt;code&gt;snowflake-user&lt;/code&gt; rotator automates the lifecycle management of these keys as &lt;strong&gt;rotated secrets&lt;/strong&gt; within ESC. This rotater uses the same two-secret rotation strategy we use in rest of ESC&amp;rsquo;s &lt;a href="https://www.pulumi.com/docs/esc/integrations/rotated-secrets/"&gt;rotated secrets&lt;/a&gt; providers. This eliminates manual rotation toil and ensures keys are regularly refreshed according to policy, enhancing the security of the &lt;em&gt;user secret&lt;/em&gt; itself. Check out the rotated secrets &lt;a href="https://www.pulumi.com/blog/esc-rotated-secrets-launch/#introducing-esc-rotated-secrets"&gt;blog post&lt;/a&gt; to learn more about its benefits.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Setup:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Prepare Snowflake:&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Create the &lt;a href="https://www.pulumi.com/docs/esc/integrations/rotated-secrets/snowflake-user/#step-1-create-the-target-user"&gt;target user&lt;/a&gt; (e.g., &lt;code&gt;MY_APP_SNOWFLAKE_USER&lt;/code&gt;) whose keys need rotation.&lt;/li&gt;
&lt;li&gt;Set up a dedicated &lt;a href="https://www.pulumi.com/docs/esc/integrations/rotated-secrets/snowflake-user/#step-2-create-a-rotator-role"&gt;rotation role&lt;/a&gt; with &lt;code&gt;OWNERSHIP&lt;/code&gt; permission over the users you wish to rotate, so it can modify their keys.&lt;/li&gt;
&lt;li&gt;Create a &lt;a href="https://www.pulumi.com/docs/esc/integrations/rotated-secrets/snowflake-user/#step-3-create-a-rotation-service-user"&gt;service user&lt;/a&gt; using the rotation role, and &lt;a href="https://www.pulumi.com/docs/esc/integrations/rotated-secrets/snowflake-user/#step-4-set-up-oidc-for-the-rotation-service-user"&gt;setup OIDC&lt;/a&gt; to allow ESC to assume the role for rotation.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rotation Environment:&lt;/strong&gt; Define the rotation, importing the managing credentials and specifying the target user.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# Environment: my-org/rotators/snowflake-app-key&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;values&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;rotatedKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;fn::rotate::snowflake-user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;inputs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;login&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;${environments.logins.snowflake.snowflake.login}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;#reference credentials created using `snowflake-login`&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;targetUser&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ESC_ROTATION_DEMO_USER&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# User whose keys rotate&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;After setup, use the triple-dot menu -&amp;gt; “Rotate Secrets” in the Pulumi Cloud UI and ensure rotation happens. Once you rotate a couple of time and ensured everything works well, navigate to the “Secret Rotation” tab for your Rotation environment in the Pulumi Cloud console and define the rotation schedule.&lt;/p&gt;
&lt;h2 id="when-to-use-dynamic-login-vs-rotated-secrets"&gt;When to Use Dynamic Login vs. Rotated Secrets&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left"&gt;&lt;strong&gt;Feature&lt;/strong&gt;&lt;/th&gt;
&lt;th style="text-align: left"&gt;&lt;strong&gt;&lt;code&gt;snowflake-login&lt;/code&gt; (Dynamic OIDC Login)&lt;/strong&gt;&lt;/th&gt;
&lt;th style="text-align: left"&gt;&lt;strong&gt;&lt;code&gt;snowflake-user&lt;/code&gt; (Rotated Secrets)&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;&lt;strong&gt;Credential Type&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;Short-lived OIDC access token&lt;/td&gt;
&lt;td style="text-align: left"&gt;Long-lived RSA Private Key secret (managed by ESC) + Public Keys (in Snowflake)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;&lt;strong&gt;Primary Use Case&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;Temporary authentication &lt;em&gt;to&lt;/em&gt; Snowflake (CLI, scripts, dev, CI/CD).&lt;/td&gt;
&lt;td style="text-align: left"&gt;Key-pair authentication &lt;em&gt;for&lt;/em&gt; long-lived applications/services connecting to Snowflake.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;&lt;strong&gt;Ideal Scenario&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;Short-lived tasks; frequent, temporary access needs.&lt;/td&gt;
&lt;td style="text-align: left"&gt;Applications needing persistent connections; keys required at deploy time; apps sensitive to auth blips.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;&lt;strong&gt;Lifecycle&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;Generated on-demand, expires quickly (minutes/hours).&lt;/td&gt;
&lt;td style="text-align: left"&gt;Rotated automatically on a schedule (e.g., days/months).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;&lt;strong&gt;Connection Impact&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;Requires re-authentication or new token fetch when token expires.&lt;/td&gt;
&lt;td style="text-align: left"&gt;Rotation is typically seamless; two-key strategy avoids connection drops if apps update keys promptly.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;&lt;strong&gt;Benefit Focus&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;Eliminates static &lt;em&gt;authentication&lt;/em&gt; tokens/credentials.&lt;/td&gt;
&lt;td style="text-align: left"&gt;Automates lifecycle management of user &lt;em&gt;key-pair secrets&lt;/em&gt;, ensures key freshness.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Pulumi ESC&amp;rsquo;s new Snowflake integrations provide robust solutions for modern credential management challenges. Use &lt;code&gt;snowflake-login&lt;/code&gt; for secure, temporary OIDC-based access and &lt;code&gt;snowflake-user&lt;/code&gt; to automate the rotation of critical RSA key secrets. By adopting these capabilities, you can significantly enhance your Snowflake security posture, reduce operational overhead, and simplify compliance.&lt;/p&gt;
&lt;p&gt;Explore the detailed documentation for &lt;a href="https://www.pulumi.com/docs/esc/integrations/dynamic-login-credentials/snowflake-login/"&gt;&lt;code&gt;snowflake-login&lt;/code&gt;&lt;/a&gt; and &lt;a href="https://www.pulumi.com/docs/esc/integrations/rotated-secrets/snowflake-user/"&gt;&lt;code&gt;snowflake-user&lt;/code&gt;&lt;/a&gt;, and see how Pulumi ESC can centralize and secure your configuration and secrets across all your environments. Join the conversation in the &lt;a href="https://slack.pulumi.com/"&gt;Pulumi Community Slack&lt;/a&gt; or our &lt;a href="https://github.com/pulumi/esc"&gt;GitHub repository&lt;/a&gt;.&lt;/p&gt;</description><author>Claire Gaestel</author><author>Arun Loganathan</author><category>esc</category><category>secrets</category><category>features</category><category>snowflake</category><category>rotation</category><category>dynamic-login</category><category>oidc</category><category>security</category><category>configuration-management</category></item><item><title>Announcing Infisical Providers for Pulumi ESC: Dynamic Login and Dynamic Secrets</title><link>https://www.pulumi.com/blog/esc-infisical-providers-launch/</link><pubDate>Mon, 28 Apr 2025 00:00:00 +0000</pubDate><guid>https://www.pulumi.com/blog/esc-infisical-providers-launch/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/esc-infisical-providers-launch/index.png" /&gt;
&lt;p&gt;We are thrilled to announce enhanced integration support for &lt;a href="https://infisical.com/"&gt;Infisical&lt;/a&gt; within &lt;a href="https://www.pulumi.com/product/esc"&gt;Pulumi ESC&lt;/a&gt;! Pulumi ESC centralizes secrets and configuration management, providing a unified source of truth across your environments. With the addition of Infisical, a popular open-source secrets management platform, ESC further extends its ecosystem, enabling seamless and secure access to secrets stored across diverse systems.&lt;/p&gt;
&lt;p&gt;This release introduces two distinct dynamic providers for Infisical, each designed to improve security and streamline your workflows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.pulumi.com/docs/esc/integrations/dynamic-login-credentials/infisical-login/"&gt;&lt;code&gt;infisical-login&lt;/code&gt;&lt;/a&gt; (Dynamic Login):&lt;/strong&gt; This provider securely generates short-lived OIDC access tokens for authenticating &lt;em&gt;to&lt;/em&gt; Infisical. Static, long-lived credentials are a significant security risk. The &lt;code&gt;infisical-login&lt;/code&gt; provider directly addresses this by generating temporary, just-in-time credentials using OIDC. &lt;strong&gt;Use this provider when you need temporary credentials to interact directly with Infisical&lt;/strong&gt;, for instance, using the Infisical CLI or SDKs in local development or CI/CD pipelines, without storing long-lived static tokens. ESC manages the OIDC flow, providing a fresh token when needed.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.pulumi.com/docs/esc/integrations/dynamic-secrets/infisical-secrets/"&gt;&lt;code&gt;infisical-secrets&lt;/code&gt;&lt;/a&gt; (Dynamic Secrets):&lt;/strong&gt; This provider dynamically fetches secrets stored &lt;em&gt;within&lt;/em&gt; your Infisical projects and makes them available within the Pulumi ESC environment. &lt;strong&gt;Use this provider when you need specific secrets &lt;em&gt;from&lt;/em&gt; Infisical to configure your applications or infrastructure managed via ESC.&lt;/strong&gt; This centralizes secret consumption, allowing you to access Infisical secrets using the same consistent ESC patterns used for AWS, Azure, GCP, Vault, 1Password, and more.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Pulumi ESC acts as a robust &lt;strong&gt;secrets broker&lt;/strong&gt; provider consistent API interface for all your tools, applications and workflows. It securely handles &lt;em&gt;both&lt;/em&gt; the generation of temporary authentication credentials (like with &lt;code&gt;infisical-login&lt;/code&gt;) and the fetching of application secrets (like with &lt;code&gt;infisical-secrets&lt;/code&gt;) from various providers such as Infisical, cloud platforms (&lt;a href="https://www.pulumi.com/docs/esc/integrations/dynamic-secrets/aws-secrets/"&gt;AWS&lt;/a&gt;, &lt;a href="https://www.pulumi.com/docs/esc/integrations/dynamic-secrets/azure-secrets/"&gt;Azure&lt;/a&gt;, &lt;a href="https://www.pulumi.com/docs/esc/integrations/dynamic-secrets/gcp-secrets/"&gt;GCP&lt;/a&gt;), and other secret managers (&lt;a href="https://www.pulumi.com/docs/esc/integrations/dynamic-secrets/vault-secrets/"&gt;Vault&lt;/a&gt;, &lt;a href="https://www.pulumi.com/docs/esc/integrations/dynamic-secrets/1password-secrets/"&gt;1Password&lt;/a&gt;). Once centralized in ESC, these secrets and configurations are consistently available for you to consume via ESC&amp;rsquo;s many developer friendly methods including the &lt;a href="https://www.pulumi.com/docs/esc/development/languages-sdks/"&gt;ESC SDK&lt;/a&gt;, &lt;a href="https://www.pulumi.com/docs/iac/cli/commands/pulumi_env/"&gt;Pulumi CLI&lt;/a&gt;, &lt;a href="https://www.pulumi.com/docs/esc/integrations/kubernetes/external-secrets-operator/"&gt;Kubernetes External Secrets Operator&lt;/a&gt;, &lt;a href="https://www.pulumi.com/docs/esc/integrations/kubernetes/secret-store-csi-driver/"&gt;CSI Driver&lt;/a&gt;, or sync them to various platforms where they are needed such as &lt;a href="https://github.com/pulumi/esc-examples/tree/main/sync/github-secrets"&gt;GitHub Secrets&lt;/a&gt;, &lt;a href="https://github.com/pulumi/esc-examples/tree/main/sync/aws-secrets-manager"&gt;AWS Secrets Manager&lt;/a&gt;, and more!&lt;/p&gt;
&lt;h2 id="getting-started-using-the-infisical-providers"&gt;Getting Started: Using the Infisical Providers&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s walk through how to configure and use each provider.&lt;/p&gt;
&lt;h3 id="prerequisites"&gt;Prerequisites&lt;/h3&gt;
&lt;p&gt;Configure Infisical for OpenID Connect(OIDC) before you try out the providers. Follow the steps in &lt;a href="https://www.pulumi.com/docs/esc/environments/configuring-oidc/infisical/"&gt;Infisical OIDC documentation&lt;/a&gt;. This involves creating an Identity in Infisical, adding OIDC authentication pointing to &lt;code&gt;https://api.pulumi.com/oidc&lt;/code&gt;, and configuring the audience and subject claims. Note down the &lt;strong&gt;Identity ID&lt;/strong&gt;.&lt;/p&gt;
&lt;h3 id="how-to-use-the-infisical-login-provider-dynamic-authentication"&gt;How to Use the infisical-login Provider (Dynamic Authentication)&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Create a Pulumi ESC environment (e.g., &lt;code&gt;pulumi-org/infisical-auth/oidc-login&lt;/code&gt;) with the following environment definition and update the &lt;code&gt;identityId&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# Environment: pulumi-org/infisical-auth/oidc-login&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;values&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;infisical&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Configure the Dynamic Login provider using OIDC&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;login&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;fn::open::infisical-login&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;oidc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;identityId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;&amp;lt;your-identity-id&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Replace with your Infisical Identity ID&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Expose the token as an environment variable for easy consumption&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;environmentVariables&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;INFISICAL_TOKEN&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;${infisical.login.accessToken}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Save the environment.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Validate the environment by clicking on Open in the Pulumi Cloud console, or running &lt;code&gt;pulumi env open pulumi-org/infisical-auth/oidc-login&lt;/code&gt; in your CLI. The output will include the infisical.login.accessToken.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Usage Example: Run Infisical CLI commands dynamically:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pulumi env run pulumi-org/infisical-auth/oidc-login -- infisical secrets get API_KEY --projectId&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;your-project-id&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# The INFISICAL_TOKEN env var is automatically injected&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="how-to-use-the-infisical-secrets-provider-dynamically-fetching-secrets"&gt;How to Use the infisical-secrets Provider (Dynamically Fetching Secrets)&lt;/h3&gt;
&lt;p&gt;Use this provider to pull secrets &lt;em&gt;from&lt;/em&gt; Infisical &lt;em&gt;into&lt;/em&gt; your ESC environment for consumption by your applications, CI/CD systems, Pulumi IaC, Terraform and more!&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Create an ESC environment where you need the secrets (e.g., &lt;code&gt;pulumi-org/my-app/dev&lt;/code&gt;).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Import&lt;/strong&gt; the dynamic login environment (if using OIDC for authentication, which is recommended). This makes the temporary Infisical token available.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Configure the &lt;code&gt;infisical-secrets&lt;/code&gt; provider, referencing the imported login details. See example below.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Specify the secrets to fetch using the &lt;code&gt;get&lt;/code&gt; block. Replace placeholders.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# Environment: pulumi-org/my-app/dev&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;imports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Import the environment performing Dynamic Login (recommended)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;pulumi-org/infisical-auth/oidc-login&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Use the path to your login environment&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;values&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Define a structure to hold secrets fetched from Infisical&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;infisicalSecrets&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;fn::open::infisical-secrets&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Authenticate using the token from the imported Dynamic Login environment&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;login&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;${infisical.login}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Pass the login object from the import&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Specify secrets to retrieve from Infisical&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;get&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Define names for the secrets as they will appear in ESC&amp;#39;s output under &amp;#39;infisicalSecrets&amp;#39;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# This is the name within ESC&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;projectId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;&amp;lt;your-infisical-project-id&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;environment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;prod&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# The Infisical environment slug (e.g., &amp;#39;prod&amp;#39;, &amp;#39;dev&amp;#39;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;secretKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;api-key&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# The key of the secret in Infisical&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;appSecret&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Pull another secret `app-secret` into ESC&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;projectId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;&amp;lt;your-infisical-project-id&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;environment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;dev&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;secretKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;app-secret&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Optionally, map fetched secrets to environment variables for application consumption&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;environmentVariables&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;API_KEY&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;${infisicalSecrets.apiKey}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;APP_SECRET&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;${infisicalSecrets.appSecret}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Save the environment.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Validate the environment by clicking on Open in the Pulumi Cloud console, or running &lt;code&gt;pulumi env open pulumi-org/my-app/dev&lt;/code&gt; in your CLI. The output will show the imported &lt;code&gt;infisical.login&lt;/code&gt;, the fetched secrets under &lt;code&gt;infisicalSecrets&lt;/code&gt;, and the mapped &lt;code&gt;environmentVariables&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Usage Example:&lt;/strong&gt; Run an application that needs these secrets:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pulumi env run pulumi-org/my-app/dev -- node app.js
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# The API_KEY and APP_SECRET env vars are automatically injected&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;The new &lt;code&gt;infisical-login&lt;/code&gt; and &lt;code&gt;infisical-secrets&lt;/code&gt; providers for Pulumi ESC offer powerful and secure ways to interact with Infisical. Use &lt;code&gt;infisical-login&lt;/code&gt; for dynamic, short-lived OIDC authentication when interacting directly with Infisical APIs or CLIs. Use &lt;code&gt;infisical-secrets&lt;/code&gt; to securely fetch secrets &lt;em&gt;from&lt;/em&gt; Infisical &lt;em&gt;into&lt;/em&gt; your centralized ESC environment. Together, they enhance your security posture and simplify configuration management.&lt;/p&gt;
&lt;p&gt;We encourage you to explore these new capabilities. Dive into the &lt;a href="https://www.pulumi.com/docs/esc/integrations/dynamic-login-credentials/infisical-login/"&gt;infisical-login&lt;/a&gt;, &lt;a href="https://www.pulumi.com/docs/esc/integrations/dynamic-secrets/infisical-secrets/"&gt;infisical-secrets&lt;/a&gt; for detailed configuration options, check out the broader &lt;a href="https://www.pulumi.com/docs/esc/"&gt;Pulumi ESC Documentation&lt;/a&gt;, and share your feedback or ask questions in the &lt;a href="https://slack.pulumi.com/"&gt;Pulumi Community Slack&lt;/a&gt;.&lt;/p&gt;</description><author>Boris Schlosser</author><author>Arun Loganathan</author><category>esc</category><category>secrets</category><category>infisical</category><category>features</category><category>configuration-management</category><category>dynamic-secrets</category><category>oidc</category></item><item><title>Pulumi ESC: Discovering Environment Imports</title><link>https://www.pulumi.com/blog/esc-imports-discoverability/</link><pubDate>Fri, 13 Dec 2024 00:00:00 -0700</pubDate><guid>https://www.pulumi.com/blog/esc-imports-discoverability/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/esc-imports-discoverability/index.png" /&gt;
&lt;p&gt;Managing secrets and configuration across multiple environments and stacks can easily become complex, leading to duplicated values, inconsistencies, and security risks. &lt;a href="https://www.pulumi.com/product/esc"&gt;Pulumi ESC&lt;/a&gt; solves this with composable environments via &lt;a href="https://www.pulumi.com/docs/esc/environments/imports/"&gt;imports&lt;/a&gt;, allowing you to define configuration once and reuse it organization-wide. Now, with the new capabilities to discover environment imports, you gain unprecedented visibility and control, simplifying the management of even the most complex infrastructure and applications.&lt;/p&gt;
&lt;h2 id="understanding-pulumi-esc-imports"&gt;Understanding Pulumi ESC Imports&lt;/h2&gt;
&lt;p&gt;Pulumi ESC lets you define secrets and configuration as code collections called &lt;a href="https://www.pulumi.com/docs/esc/environments/working-with-environments/"&gt;environments&lt;/a&gt;. These environments can import other environments, creating a hierarchical structure that promotes reusability, and reduces duplication and sprawl. You can centralize secrets and configuration within ESC and use them across &lt;a href="https://www.pulumi.com/docs/esc/integrations/infrastructure/pulumi-iac/"&gt;Pulumi IaC Stacks&lt;/a&gt;, &lt;a href="https://www.pulumi.com/docs/pulumi-cloud/insights/accounts/"&gt;Pulumi Insights Accounts&lt;/a&gt;, and various other platforms through our &lt;a href="https://www.pulumi.com/docs/esc/integrations/"&gt;integrations&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;By using &lt;a href="https://www.pulumi.com/docs/esc/environments/versioning/#tagging-versions"&gt;version tags&lt;/a&gt;, imports can target specific versions of an environment. This locks down the configuration used by dependents, ensuring stability and preventing unintended changes from rolling out to your critical environments.&lt;/p&gt;
&lt;h2 id="whats-new"&gt;What&amp;rsquo;s New?&lt;/h2&gt;
&lt;p&gt;We&amp;rsquo;ve added powerful discoverability features to give you clear insight into your environment dependencies:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;New &amp;ldquo;Imported By&amp;rdquo; tab&lt;/strong&gt;: Easily understand downstream dependencies by clicking the &amp;ldquo;Imported By&amp;rdquo; tab for each environment. This tab shows all environments and stacks that import a specific environment, including the specific tagged version used. Filter and sort by imported versions and downstream resources to narrow in on the resources that will be affected by a change you are trying to make.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Warnings for deletions and tag movements&lt;/strong&gt;: Pulumi ESC now warns you about the potential impact of deleting an environment or modifying version tags before you make the change, helping you avoid disruptions.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Enhanced environment page&lt;/strong&gt;: The Environments page now clearly indicates if an environment is used by other environments, stacks, or insights accounts, providing valuable relationship context at a glance.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pulumi IaC stack visibility&lt;/strong&gt;: Environment import information is also available on the Stacks page and within individual stack overview pages.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="imported-by.png" alt="Screenshot of the Pulumi ESC &amp;lsquo;Imported By&amp;rsquo; tab showing environment dependencies"&gt;&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Pulumi ESC&amp;rsquo;s import feature is a paradigm shift in how you manage your secrets and configuration. The new suite of import discoverability features gives you the confidence to manage complex deployments with ease. Explore the new features and share your feedback through our &lt;a href="https://www.pulumi.com/community/"&gt;Community Slack&lt;/a&gt; or &lt;a href="https://github.com/pulumi/esc/issues/new/choose"&gt;GitHub Repo&lt;/a&gt;.&lt;/p&gt;</description><author>Sean Yeh</author><author>Arun Loganathan</author><category>esc</category><category>secrets</category><category>configuration-management</category><category>features</category><category>releases</category></item><item><title>Pulumi ESC Table Editor Now Supports Dynamic Credential and Secret Integrations</title><link>https://www.pulumi.com/blog/esc-table-editor-provider-config-support/</link><pubDate>Tue, 10 Sep 2024 00:00:00 -0700</pubDate><guid>https://www.pulumi.com/blog/esc-table-editor-provider-config-support/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/esc-table-editor-provider-config-support/index.png" /&gt;
&lt;p&gt;We are pleased to announce a major update to the &lt;a href="https://www.pulumi.com/product/esc"&gt;Pulumi ESC&lt;/a&gt;’s Table Editor: full support for provider configurations is now live! When we &lt;a href="https://www.pulumi.com/blog/esc-key-value-table-editor-launch"&gt;first introduced the ESC Table view&lt;/a&gt;, our goal was to offer a user-friendly interface for managing complex configuration and secrets for your applications and infrastructure. This has empowered teams to focus on what they do best—building and deploying software.&lt;/p&gt;
&lt;p&gt;In our initial launch, the Table Editor allowed you to perform CRUD operations on your secrets and plaintext values, decrypt secrets, import environments, and manage variables—all within a visual interface. Today, we’re taking the next step by enabling full read-write support for provider configurations within the Table Editor. This new capability allows you to add, edit, and manage your provider configurations directly from the table view, offering a more integrated and seamless experience.&lt;/p&gt;
&lt;h2 id="primer-on-esc-provider-configuration"&gt;Primer on ESC Provider Configuration&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://www.pulumi.com/docs/esc/providers/"&gt;Pulumi ESC’s provider ecosystem&lt;/a&gt; is one of its most powerful features. It supports two categories of providers:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Dynamic Cloud Provider Credentials&lt;/strong&gt;: Dynamically acquire credentials from cloud providers like &lt;a href="https://www.pulumi.com/docs/esc/providers/aws-login/"&gt;AWS&lt;/a&gt;, &lt;a href="https://www.pulumi.com/docs/esc/providers/azure-login/"&gt;Azure&lt;/a&gt;, &lt;a href="https://www.pulumi.com/docs/esc/providers/gcp-login/"&gt;GCP&lt;/a&gt;, and &lt;a href="https://www.pulumi.com/docs/esc/providers/vault-login/"&gt;Vault&lt;/a&gt; at runtime, eliminating the need for static, long-lived credentials. This enhances security by removing the reliance on dotenv files, locally stored secrets, or long-lived credentials in CI/CD environments, strengthening your workflows’ overall security.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Dynamic Secret Retrieval&lt;/strong&gt;: ESC retrieves secrets from external secrets managers, such as &lt;a href="https://www.pulumi.com/docs/esc/providers/aws-secrets/"&gt;AWS Secrets Manager&lt;/a&gt;, &lt;a href="https://www.pulumi.com/docs/esc/providers/1password-secrets/"&gt;1Password&lt;/a&gt;, and &lt;a href="https://www.pulumi.com/docs/esc/providers/vault-secrets/"&gt;HashiCorp Vault&lt;/a&gt;, securely pulling them directly into your environments. Whether you are migrating or utilizing Pulumi ESC’s rich toolset, you can retrieve sensitive information at runtime and apply it seamlessly to your applications.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="enhancing-the-table-editor-provider-configuration-support"&gt;Enhancing the Table Editor: Provider Configuration Support&lt;/h2&gt;
&lt;p&gt;With the addition of provider configuration support in the Table view, incorporating Pulumi ESC provider capabilities into your workflow is now more straightforward. A clean, user-friendly form provides step-by-step guidance, promoting best practices like &lt;a href="https://www.pulumi.com/docs/esc/environments/configuring-oidc"&gt;OIDC&lt;/a&gt; adoption and the secure handling of sensitive data. This streamlined approach reduces the need for external documentation, making the entire process more intuitive and efficient.&lt;/p&gt;
&lt;p&gt;&lt;img src="esc-table-editor-provider-config.png" alt="Table view"&gt;&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;The new provider configuration support in the ESC Table view marks another step in our efforts to simplify and enhance the developer experience. We’re eager to see how you’ll leverage this new capability to streamline your workflows and strengthen your infrastructure’s security. As always, your feedback is invaluable to our development process, and we’re committed to continually improving the Table Editor and other Pulumi tools based on your needs. Please share your feedback with us &lt;a href="https://github.com/pulumi/esc/issues/new/choose"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Check out our &lt;a href="https://www.pulumi.com/docs/esc"&gt;documentation&lt;/a&gt; to learn more about Pulumi ESC.&lt;/p&gt;</description><author>Kimberley Mackenzie</author><author>Arun Loganathan</author><category>esc</category><category>secrets</category><category>configuration-management</category><category>features</category><category>releases</category></item><item><title>Introducing Pulumi ESC Support in Automation API and the Pulumi Service Provider</title><link>https://www.pulumi.com/blog/esc-automation-api-pulumi-service-provider-launch/</link><pubDate>Wed, 05 Jun 2024 00:00:00 -0500</pubDate><guid>https://www.pulumi.com/blog/esc-automation-api-pulumi-service-provider-launch/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/esc-automation-api-pulumi-service-provider-launch/index.png" /&gt;
&lt;p&gt;We&amp;rsquo;re excited to announce two powerful new capabilities for &lt;a href="https://www.pulumi.com/product/esc"&gt;Pulumi Environments Secrets and Configurations&lt;/a&gt; (ESC) that supercharge how you manage and control your infrastructure and application secrets and configurations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Pulumi Service Provider Support for ESC Environments&lt;/strong&gt;: Manage your environments as code right alongside your infrastructure including fine-grained access control using &lt;a href="https://www.pulumi.com/registry/packages/pulumiservice/"&gt;Pulumi Service Provider&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Automation API Enhancements for ESC&lt;/strong&gt;: Seamlessly integrate ESC Environments into your &lt;a href="https://www.pulumi.com/automation/"&gt;Automation API&lt;/a&gt;-based Pulumi projects.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These updates build upon Pulumi ESC&amp;rsquo;s commitment to simplify and streamline secrets and configuration management providing you with greater control, security, and automation capabilities.&lt;/p&gt;
&lt;h2 id="manage-esc-environments-as-code-with-the-pulumi-service-provider"&gt;Manage ESC Environments as Code with the Pulumi Service Provider&lt;/h2&gt;
&lt;p&gt;You can now manage your Pulumi ESC &lt;a href="https://www.pulumi.com/docs/esc/environments/"&gt;Environments&lt;/a&gt; directly within the Pulumi Service using the powerful Pulumi Service Provider. This means you can define environments, add &lt;a href="https://www.pulumi.com/docs/esc/environments/#tagging-versions"&gt;version tags&lt;/a&gt;, and even control access using familiar Infrastructure as Code (IaC) practices ensuring consistency and repeatability across your deployments.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s a glimpse of what you can achieve:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Programmatically create and manage ESC Environments&lt;/strong&gt;: Define environments alongside your infrastructure code for a unified workflow.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Add version tags to environments&lt;/strong&gt;: Add tags when you are creating the environment.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Enforce granular team permissions&lt;/strong&gt;: Control who can &lt;a href="https://www.pulumi.com/docs/esc/environments/#organization-wide-permissions"&gt;read, open, or modify&lt;/a&gt; your environments ensuring secure collaboration and preventing unauthorized access.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Bringing Pulumi ESC Environments support into the Pulumi Service Provider empowers you to manage your entire infrastructure and application landscape through a unified approach.&lt;/p&gt;
&lt;p&gt;Pulumi Service Provider ESC capabilities are available for TypeScript/JavaScript, Go, Python, C#, Java, and YAML. See our &lt;a href="https://www.pulumi.com/registry/packages/pulumiservice/api-docs/environment/"&gt;Environment&lt;/a&gt;, &lt;a href="https://www.pulumi.com/registry/packages/pulumiservice/api-docs/environmentversiontag/"&gt;Environment Version Tag&lt;/a&gt;, and &lt;a href="https://www.pulumi.com/registry/packages/pulumiservice/api-docs/teamenvironmentpermission/"&gt;Environment Permissions&lt;/a&gt; Pulumi Service Provider docs. Here are examples of creating environments in TypeScript/JavaScript, Go, and Python:&lt;/p&gt;
&lt;div&gt;
&lt;pulumi-chooser type="language" options="typescript,python,go" mode=""&gt;&lt;/pulumi-chooser&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;pulumi-choosable type="language" values="typescript" mode=""&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="kr"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;service&lt;/span&gt; &lt;span class="kr"&gt;from&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;@pulumi/pulumiservice&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="kr"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;pulumi&lt;/span&gt; &lt;span class="kr"&gt;from&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;@pulumi/pulumi&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;environment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Environment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;testing-environment&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;organization&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;service-provider-test-org&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;testing-environment-ts&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;yaml&lt;/span&gt;: &lt;span class="kt"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;pulumi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;asset&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;StringAsset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="sb"&gt;`values:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sb"&gt; myKey1: &amp;#34;myValue1&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sb"&gt; myNestedKey:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sb"&gt; myKey2: &amp;#34;myValue2&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sb"&gt; myNumber: 1`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/pulumi-choosable&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;pulumi-choosable type="language" values="python" mode=""&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;pulumi&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;pulumi_pulumiservice&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Environment&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;environment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Environment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;testing-environment&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;organization&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;service-provider-test-org&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;testing-environment-py&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;yaml&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;pulumi&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StringAsset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; values:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; myKey1: &amp;#34;myValue1&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; myNestedKey:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; myKey2: &amp;#34;myValue2&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; myNumber: 1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/pulumi-choosable&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;pulumi-choosable type="language" values="go" mode=""&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;package&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;main&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;github.com/pulumi/pulumi-pulumiservice/sdk/go/pulumiservice&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;github.com/pulumi/pulumi/sdk/v3/go/pulumi&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;pulumi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nx"&gt;pulumi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;pulumiservice&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;NewEnvironment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;testing-environment&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nx"&gt;pulumiservice&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;EnvironmentArgs&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;pulumi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;testing-environment-go&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Organization&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;pulumi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;service-provider-test-org&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Yaml&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;pulumi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;NewStringAsset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;`
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; values:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; myKey1: &amp;#34;myValue1&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; myNestedKey:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; myKey2: &amp;#34;myValue2&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt; myNumber: 1`&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/pulumi-choosable&gt;
&lt;/div&gt;
&lt;h2 id="streamline-automated-workflows-with-automation-api-enhancements"&gt;Streamline Automated Workflows with Automation API Enhancements&lt;/h2&gt;
&lt;p&gt;We&amp;rsquo;re expanding the powerful Pulumi Automation API to include new methods for interacting with Pulumi ESC Environments programmatically. This enables you to seamlessly integrate environment management into your automated workflows and build sophisticated custom tooling.&lt;/p&gt;
&lt;p&gt;The new Automation API methods for ESC include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;addEnvironments(...)&lt;/code&gt;: Append environments in order to your Pulumi stack&amp;rsquo;s &lt;a href="https://www.pulumi.com/docs/esc/environments/#using-environments-with-pulumi-iac"&gt;import&lt;/a&gt; list.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;listEnvironments()&lt;/code&gt;: Retrieve a list of environments currently imported into your stack.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;removeEnvironment(environment)&lt;/code&gt;: Remove a specific environment from your stack&amp;rsquo;s import list.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These additions provide the building blocks for advanced automation scenarios such as dynamically configuring applications based on environments, managing environment dependencies, and integrating ESC into CI/CD pipelines.&lt;/p&gt;
&lt;p&gt;Pulumi ESC Automation API capabilities are available for &lt;a href="https://www.pulumi.com/docs/reference/pkg/nodejs/pulumi/pulumi/classes/automation.Stack.html#addEnvironments"&gt;TypeScript/JavaScript&lt;/a&gt;, &lt;a href="https://pkg.go.dev/github.com/pulumi/pulumi/sdk/v3@v3.117.0/go/auto#LocalWorkspace.AddEnvironments"&gt;Go&lt;/a&gt;, and &lt;a href="https://www.pulumi.com/docs/reference/pkg/python/pulumi/#pulumi.automation.LocalWorkspace.add_environments"&gt;Python&lt;/a&gt;. Here are some examples:&lt;/p&gt;
&lt;div&gt;
&lt;pulumi-chooser type="language" options="typescript,python,go" mode=""&gt;&lt;/pulumi-chooser&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;pulumi-choosable type="language" values="typescript" mode=""&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="kr"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;pulumi&lt;/span&gt; &lt;span class="kr"&gt;from&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;@pulumi/pulumi&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="kr"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;automation&lt;/span&gt; &lt;span class="kr"&gt;from&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;@pulumi/pulumi/automation&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;manageEnvironments() {&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;projectName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;myProject&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;stackName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;dev&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// Set up your stack options. Here we&amp;#39;re using an empty program
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// since we&amp;#39;re only manipulating environments, not deploying resources.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;stackArgs&lt;/span&gt;: &lt;span class="kt"&gt;automation.InlineProgramArgs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;stackName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;projectName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;program&lt;/span&gt;: &lt;span class="kt"&gt;async&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// Create or select an existing stack.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;stack&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;automation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;LocalWorkspace&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createOrSelectStack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;stackArgs&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// Add environments to your stack&amp;#39;s configuration.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// This is like adding them to the `imports` section of an ESC environment.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;stack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addEnvironments&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;env1&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;env2&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// The stack&amp;#39;s configuration now includes `env1` and `env2`.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// List the environments currently configured for the stack.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;environments&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;stack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;listEnvironments&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Current environments:&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;environments&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Output: [&amp;#34;env1&amp;#34;, &amp;#34;env2&amp;#34;]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// Remove an environment from the stack&amp;#39;s configuration.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;stack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;removeEnvironment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;env1&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// The stack&amp;#39;s configuration now only includes `env2`.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// List environments again to confirm the removal.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;updatedEnvironments&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;stack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;listEnvironments&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Updated environments:&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;updatedEnvironments&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Output: [&amp;#34;env2&amp;#34;]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Call the async function to execute.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;manageEnvironments&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/pulumi-choosable&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;pulumi-choosable type="language" values="python" mode=""&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;pulumi&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;pulumi.automation&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;LocalWorkspace&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ProjectSettings&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Stack&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;manage_environments&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;stack_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;dev&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;project_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;myProject&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# Define the project settings.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;project_settings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ProjectSettings&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;project_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;runtime&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;python&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# Create a LocalWorkspace with the project settings.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;workspace&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;LocalWorkspace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;work_dir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# Use the current directory as the working directory&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;project_settings&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;project_settings&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# Create or select an existing stack.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;stack&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Stack&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stack_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;stack_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;workspace&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;workspace&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# Add environments to the stack&amp;#39;s configuration.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;stack&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_environments&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;env1&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;env2&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# List the environments associated with the stack.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;environments&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;stack&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;list_environments&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Current environments:&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;environments&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# Output: [&amp;#39;env1&amp;#39;, &amp;#39;env2&amp;#39;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# Remove an environment from the stack&amp;#39;s configuration.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;stack&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;remove_environment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;env1&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# List the environments again to verify the removal.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;updated_environments&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;stack&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;list_environments&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Updated environments:&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;updated_environments&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# Output: [&amp;#39;env2&amp;#39;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Run the function to manage environments.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;manage_environments&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/pulumi-choosable&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;pulumi-choosable type="language" values="go" mode=""&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;package&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;main&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;context&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;fmt&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;log&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;github.com/pulumi/pulumi/sdk/v3/go/auto&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;github.com/pulumi/pulumi/sdk/v3/go/common/tokens&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;github.com/pulumi/pulumi/sdk/v3/go/common/workspace&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Background&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;projectName&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;myProject&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;stackName&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;dev&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// Define the project configuration.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;workspace&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Project&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;tokens&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;PackageName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;projectName&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Runtime&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;workspace&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;NewProjectRuntimeInfo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;go&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// Create a workspace with the project configuration.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// Here we&amp;#39;re using an empty program since we&amp;#39;re only manipulating environments, not deploying resources.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;NewLocalWorkspace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Project&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Program&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Fatalf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Failed to create workspace: %v&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// Create or select an existing stack.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;stack&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UpsertStack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;stackName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Fatalf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Failed to create or select stack: %v&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// Add environments to the stack&amp;#39;s configuration.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// This is like adding them to the `imports` section of an ESC environment.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;stack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddEnvironments&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;env1&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;env2&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Fatalf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Failed to add environments: %v&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// The stack&amp;#39;s configuration now includes `env1` and `env2`.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// List the environments associated with the stack.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;envs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;stack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ListEnvironments&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Fatalf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Failed to list environments: %v&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Current environments:&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;envs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// Output: map[env1:{env1} env2:{env2}]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// Remove an environment from the stack&amp;#39;s configuration.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;stack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;RemoveEnvironment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;env1&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Fatalf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Failed to remove environment: %v&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// The stack&amp;#39;s configuration now only includes `env2`.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// List the environments again to confirm the removal.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;envs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;stack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ListEnvironments&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Fatalf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Failed to list environments: %v&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Updated environments:&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;envs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// Output: map[env2:{env2}]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/pulumi-choosable&gt;
&lt;/div&gt;
&lt;h2 id="whats-coming-in-the-future"&gt;What’s Coming in the Future&lt;/h2&gt;
&lt;p&gt;We have exciting plans to further enhance these capabilities. Here&amp;rsquo;s a sneak peek at what&amp;rsquo;s on the horizon:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Pulumi service Provider&lt;/strong&gt;: Capabilities to Open, Read, and List any environment versions and version tags&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Automation API&lt;/strong&gt;: Capabilities to author new environments, and assign version tags&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Need more features or want to share feedback? We encourage you to open new issues on our &lt;a href="https://github.com/pulumi/esc/issues/new/choose"&gt;GitHub repository&lt;/a&gt; or upvote existing &lt;a href="https://github.com/pulumi/esc/issues"&gt;ones&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="get-started-today"&gt;Get Started Today!&lt;/h2&gt;
&lt;p&gt;These powerful new features are available now! We&amp;rsquo;re excited to see how you leverage these updates to simplify your secrets and configuration management, enhance your security posture, and unlock new levels of automation.&lt;/p&gt;
&lt;p&gt;To learn more and start leveraging the enhanced capabilities of Pulumi ESC check out the following resources:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Pulumi Service Provider for ESC &lt;a href="https://www.pulumi.com/registry/packages/pulumiservice/api-docs/environment/"&gt;Environment&lt;/a&gt;, &lt;a href="https://www.pulumi.com/registry/packages/pulumiservice/api-docs/environmentversiontag/"&gt;Environment Version Tag&lt;/a&gt;, and &lt;a href="https://www.pulumi.com/registry/packages/pulumiservice/api-docs/teamenvironmentpermission/"&gt;Environment Permissions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Pulumi ESC Automation API in &lt;a href="https://www.pulumi.com/docs/reference/pkg/nodejs/pulumi/pulumi/classes/automation.Stack.html#addEnvironments"&gt;TypeScript/JavaScript&lt;/a&gt;, &lt;a href="https://pkg.go.dev/github.com/pulumi/pulumi/sdk/v3@v3.117.0/go/auto#LocalWorkspace.AddEnvironments"&gt;Go&lt;/a&gt;, and &lt;a href="https://www.pulumi.com/docs/reference/pkg/python/pulumi/#pulumi.automation.LocalWorkspace.add_environments"&gt;Python&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description><author>Arun Loganathan</author><author>Iaroslav Titov</author><category>esc</category><category>secrets</category><category>configuration-management</category><category>features</category></item><item><title>Introducing the Table Editor for Pulumi ESC</title><link>https://www.pulumi.com/blog/esc-key-value-table-editor-launch/</link><pubDate>Tue, 26 Mar 2024 00:00:00 -0700</pubDate><guid>https://www.pulumi.com/blog/esc-key-value-table-editor-launch/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/esc-key-value-table-editor-launch/index.png" /&gt;
&lt;p&gt;We&amp;rsquo;re excited to announce the launch of the Pulumi Environments, Secrets, and Configurations (&lt;a href="https://www.pulumi.com/product/esc"&gt;ESC&lt;/a&gt;) Table Editor. At Pulumi, we&amp;rsquo;re committed to providing flexible solutions that cater to diverse development needs and practices. This latest addition underscores our dedication to this principle by offering a user-friendly interface for managing complex configurations and secrets.&lt;/p&gt;
&lt;p&gt;Pulumi ESC simplifies the management of secrets and configurations by reducing duplication and drift, empowering development teams to focus on building and deploying. The existing YAML-based code editor offers a native way for developers to author and manage configurations.&lt;/p&gt;
&lt;p&gt;The Table Editor we are launching today introduces an alternate visual interface for handling configuration tasks, enabling the direct input of plaintext and secret values. Key capabilities of the Table Editor include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;CRUD Operations&lt;/strong&gt;: Perform Create, Read, Update, and Delete (CRUD) operations on your secrets and plaintext values&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Decrypting Secrets&lt;/strong&gt;: Safely decrypt secrets one at a time, directly within the editor&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Environment Imports&lt;/strong&gt;: &lt;a href="https://www.pulumi.com/docs/esc/environments/#importing-other-environments"&gt;Import environments&lt;/a&gt; and define the order of imports to suit your project&amp;rsquo;s needs&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Variables Projections&lt;/strong&gt;: Make variables available as &lt;a href="https://www.pulumi.com/docs/esc/environments/#using-environments-with-pulumi-iac"&gt;Pulumi Config&lt;/a&gt;, &lt;a href="https://www.pulumi.com/docs/esc/environments/#projecting-environment-variables"&gt;environment variables&lt;/a&gt;, and files, streamlining your deployment and runtime configuration.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Interpolations and References&lt;/strong&gt;: Add references to existing path-values, or add &lt;a href="https://www.pulumi.com/docs/esc/environments/#interpolating-values"&gt;interpolations&lt;/a&gt; to dynamically generate values&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="esc-key-value-table-editor.png" alt="Table Editor"&gt;&lt;/p&gt;
&lt;p&gt;In the current release of the Table view, &lt;a href="https://www.pulumi.com/docs/esc/integrations"&gt;provider configurations&lt;/a&gt; and functions are set to read-only.&lt;/p&gt;
&lt;h2 id="whats-next"&gt;What’s Next?&lt;/h2&gt;
&lt;p&gt;Looking to the future, we are already working on the next set of enhancements for the Table view. Soon, you will have the capability to add and edit provider configurations directly within the table view.&lt;/p&gt;
&lt;p&gt;Pulumi ESC&amp;rsquo;s diverse array of providers not only allows teams to dynamically acquire cloud provider credentials at runtime, thus eliminating the need for static, long-lived credentials but also enables retrieving secrets from external secrets managers, such as AWS Secrets Manager and HashiCorp Vault, directly within ESC. This means users can seamlessly pull and utilize secrets within ESC, enhancing security and flexibility. The upcoming provider configuration support in the Table view will offer a guided experience, simplifying the process of leveraging Pulumi ESC&amp;rsquo;s comprehensive set of providers.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;The launch of the Table view marks an important step in our mission to make infrastructure as code more accessible and manageable for developers.&lt;/p&gt;
&lt;p&gt;Your &lt;a href="https://github.com/pulumi/esc/issues/new/choose"&gt;feedback&lt;/a&gt; is the cornerstone of our development process. As we look ahead, we&amp;rsquo;re focusing on incorporating your insights to further enhance the Table view. Together, we can continue to refine and advance Pulumi ESC, making it an even more powerful tool for the developer community.&lt;/p&gt;
&lt;p&gt;Check out our &lt;a href="https://www.pulumi.com/docs/esc"&gt;documentation&lt;/a&gt; to learn more about Pulumi ESC.&lt;/p&gt;</description><author>Arun Loganathan</author><author>Kimberley Mackenzie</author><category>esc</category><category>secrets</category><category>configuration-management</category><category>features</category></item></channel></rss>