<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0"><channel><title>Pulumi Blog: Sean Yeh</title><link>https://www.pulumi.com/blog/author/sean-yeh/</link><description>Pulumi blog posts: Sean Yeh.</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>Introducing ESC Secret Rotation Webhooks</title><link>https://www.pulumi.com/blog/introducing-esc-secret-rotation-webhooks/</link><pubDate>Fri, 26 Jun 2026 00:00:00 +0000</pubDate><guid>https://www.pulumi.com/blog/introducing-esc-secret-rotation-webhooks/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/introducing-esc-secret-rotation-webhooks/index.png" /&gt;
&lt;p&gt;&lt;a href="https://www.pulumi.com/docs/esc/"&gt;Pulumi ESC&lt;/a&gt; centralizes your secrets and configuration, and it can &lt;a href="https://www.pulumi.com/docs/esc/concepts/rotators/"&gt;automatically rotate secrets&lt;/a&gt; on a schedule so credentials never go stale. But a rotation is only useful if the systems that depend on it know it happened. ESC secret rotation webhooks close that gap by notifying you the moment a secret rotates.&lt;/p&gt;
&lt;h2 id="introducing-secret-rotation-webhooks"&gt;Introducing secret rotation webhooks&lt;/h2&gt;
&lt;p&gt;With &lt;a href="https://www.pulumi.com/docs/esc/concepts/webhooks/"&gt;ESC webhooks&lt;/a&gt;, you can react to rotations automatically. When ESC rotates an environment&amp;rsquo;s secrets, a webhook can be configured to trigger on either success or failure. Use it to notify your team in Slack, refresh services that hold the old credential, or catch a failed rotation before it causes an outage.&lt;/p&gt;
&lt;h2 id="how-to-configure"&gt;How to configure&lt;/h2&gt;
&lt;h3 id="pulumi-cloud-console"&gt;Pulumi Cloud Console&lt;/h3&gt;
&lt;p&gt;Using the Pulumi Cloud Console, you can now configure webhooks for &amp;ldquo;Environment rotation succeeded&amp;rdquo; and &amp;ldquo;Environment rotation failed&amp;rdquo; in your ESC Environment&amp;rsquo;s Settings page (under &lt;strong&gt;Settings&lt;/strong&gt; -&amp;gt; &lt;strong&gt;Notifications&lt;/strong&gt;).&lt;/p&gt;
&lt;p&gt;&lt;img src="./rotation-webhook-triggers.png" alt="ESC webhook trigger settings with &amp;ldquo;Environment rotation succeeded&amp;rdquo; and &amp;ldquo;Environment rotation failed&amp;rdquo; selected"&gt;&lt;/p&gt;
&lt;h3 id="pulumi-service-provider"&gt;Pulumi Service Provider&lt;/h3&gt;
&lt;p&gt;You can use the Pulumi Service Provider in your Pulumi program to configure webhooks. Here is an example in TypeScript:&lt;/p&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;const&lt;/span&gt; &lt;span class="nx"&gt;environmentWebhook&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;Webhook&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;env-webhook&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;active&lt;/span&gt;: &lt;span class="kt"&gt;true&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;displayName&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;env-webhook&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;organizationName&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;my-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;projectName&lt;/span&gt;: &lt;span class="kt"&gt;environment.project&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;environmentName&lt;/span&gt;: &lt;span class="kt"&gt;environment.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="nx"&gt;payloadUrl&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;https://example.com&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;filters&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;WebhookFilters&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;EnvironmentRotationSucceeded&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;WebhookFilters&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;EnvironmentRotationFailed&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;h3 id="pulumi-cli"&gt;Pulumi CLI&lt;/h3&gt;
&lt;p&gt;You can also use the Pulumi CLI to configure the webhook:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;pulumi env webhook new my-org/project/env env-webhook \
--url https://example.com \
--event environment_rotation_succeeded \
--event environment_rotation_failed
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="get-started"&gt;Get started&lt;/h2&gt;
&lt;p&gt;Secret rotation webhooks are available now for all Pulumi ESC environments. See the &lt;a href="https://www.pulumi.com/docs/esc/concepts/webhooks/"&gt;webhooks documentation&lt;/a&gt; to get started, and share your feedback on our &lt;a href="https://github.com/pulumi/esc"&gt;GitHub repository&lt;/a&gt;.&lt;/p&gt;</description><author>Sean Yeh</author><category>esc</category><category>rotation</category><category>secrets</category></item><item><title>Automate Azure App Secret Rotation with ESC</title><link>https://www.pulumi.com/blog/automate-azure-app-secret-rotation-with-esc/</link><pubDate>Mon, 06 Apr 2026 00:00:00 +0000</pubDate><guid>https://www.pulumi.com/blog/automate-azure-app-secret-rotation-with-esc/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/automate-azure-app-secret-rotation-with-esc/index.png" /&gt;
&lt;p&gt;&lt;a href="https://learn.microsoft.com/en-us/entra/fundamentals/whatis"&gt;Microsoft Entra ID&lt;/a&gt; (formerly Azure Active Directory) is Azure&amp;rsquo;s identity and access management service. Any time your application needs to authenticate with Entra ID, you create an &lt;strong&gt;app registration&lt;/strong&gt; and give it a &lt;a href="https://learn.microsoft.com/en-us/entra/identity-platform/how-to-add-credentials?tabs=client-secret"&gt;client secret&lt;/a&gt; that proves its identity. But those secrets expire, and if you don&amp;rsquo;t rotate them in time, your app loses access.&lt;/p&gt;
&lt;p&gt;If you or your team manages Azure app registrations, you know that keeping track of client secrets is a constant hassle. Forgetting to rotate them before they expire can lead to broken authentication and unexpected outages. With &lt;a href="https://www.pulumi.com/docs/esc"&gt;Pulumi ESC&lt;/a&gt;&amp;rsquo;s &lt;code&gt;azure-app-secret&lt;/code&gt; rotator, you can automate client secret rotation for your Azure apps, so you never have to worry about expired credentials again.&lt;/p&gt;
&lt;h2 id="setup"&gt;Setup&lt;/h2&gt;
&lt;h3 id="prerequisites"&gt;Prerequisites&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;An Azure App Registration&lt;/li&gt;
&lt;li&gt;An &lt;a href="https://www.pulumi.com/docs/esc/integrations/dynamic-login-credentials/azure-login/"&gt;azure-login&lt;/a&gt; environment
&lt;ul&gt;
&lt;li&gt;Note for OIDC users: Since Azure does not support wildcard subject matches, you will need to add a &lt;a href="https://www.pulumi.com/docs/esc/guides/configuring-oidc/azure/#add-federated-credentials"&gt;federated credential&lt;/a&gt; for the azure-login environment as well as each environment that imports it.&lt;/li&gt;
&lt;li&gt;The Azure identity used for rotation must have the &lt;code&gt;Application.ReadWrite.All&lt;/code&gt; Graph API permission, or the identity must be added as an Owner of the specific app registration whose secrets will be rotated.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="how-it-works"&gt;How it works&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s assume your azure-login environment looks like this:&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;# my-org/logins/production&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;azure&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::azure-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;clientId&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-client-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;tenantId&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-tenant-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;subscriptionId&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-subscription-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;oidc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&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;Create a new environment for your rotator. If you have the existing credentials, set them in the &lt;a href="https://www.pulumi.com/docs/esc/environments/syntax/builtin-functions/fn-rotate/#parameters"&gt;state&lt;/a&gt; object so the rotator will treat them as the &lt;code&gt;current&lt;/code&gt; credentials.&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;# my-org/rotators/secret-rotator&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;appSecret&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::azure-app-secret&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.production.azure.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;clientId&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;target-app-client-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;lifetimeInDays&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;180&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# How long each new secret is valid (max 730 days)&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;state&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;current&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;secretId&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;secret-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;secretValue&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::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;&amp;lt;secret-value&amp;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;p&gt;The &lt;code&gt;lifetimeInDays&lt;/code&gt; field controls how long each generated secret remains valid before it expires. Azure allows a maximum of 730 days (two years), but shorter lifetimes are recommended for better security. Make sure to set a rotation &lt;a href="https://www.pulumi.com/docs/esc/environments/rotation/#schedule"&gt;schedule&lt;/a&gt; that runs before the lifetime expires so your credentials are always fresh.&lt;/p&gt;
&lt;p&gt;Azure app registrations can have at most two client secrets at any given time, so the rotator maintains a &lt;code&gt;current&lt;/code&gt; and &lt;code&gt;previous&lt;/code&gt; secret. When a rotation occurs, the existing &lt;code&gt;current&lt;/code&gt; secret becomes the &lt;code&gt;previous&lt;/code&gt; secret, and a new secret is created to take its place as the new &lt;code&gt;current&lt;/code&gt;. This ensures a smooth rollover with no downtime, since the previous secret remains valid until the next rotation.&lt;/p&gt;
&lt;p&gt;Once this is set up, you&amp;rsquo;re ready to go! You never need to worry about your client secrets expiring, and you will always have the latest credentials in your ESC Environment.&lt;/p&gt;
&lt;h2 id="learn-more"&gt;Learn more&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;fn::rotate::azure-app-secret&lt;/code&gt; rotator is available now in all Pulumi ESC environments. For more information, check out the &lt;a href="https://www.pulumi.com/docs/esc/integrations/rotated-secrets/azure-app-secret/"&gt;fn::rotate::azure-app-secret documentation&lt;/a&gt;!&lt;/p&gt;</description><author>Sean Yeh</author><category>esc</category><category>azure</category></item><item><title>Lock Down Values in Pulumi ESC with fn::final</title><link>https://www.pulumi.com/blog/esc-fn-final/</link><pubDate>Tue, 17 Mar 2026 11:00:00 -0700</pubDate><guid>https://www.pulumi.com/blog/esc-fn-final/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/esc-fn-final/index.png" /&gt;
&lt;p&gt;&lt;a href="https://www.pulumi.com/docs/esc/"&gt;Pulumi ESC (Environments, Secrets, and Configuration)&lt;/a&gt; allows you to compose environments by importing configuration and secrets from other environments, but this also means a child environment can silently override a value set by a parent. When that value is a security policy or a compliance setting, an accidental override can cause real problems. With the new &lt;a href="https://www.pulumi.com/docs/esc/environments/syntax/builtin-functions/fn-final/"&gt;fn::final&lt;/a&gt; built-in function, you can mark values as final, preventing child environments from overriding them. If a child environment tries to override a final value, ESC raises a warning and preserves the original value.&lt;/p&gt;
&lt;h2 id="how-it-works"&gt;How it works&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s say you have a parent environment that sets the AWS region for all deployments. You can use &lt;code&gt;fn::final&lt;/code&gt; to ensure no child environment can change it:&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;# project/parent-env&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;aws-region&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::final&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;us-east-1&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;If a child environment tries to override the final value, ESC raises a &lt;code&gt;cannot override final value&lt;/code&gt; warning.&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;# project/child-env&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="l"&gt;project/parent-env&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;aws-region&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;eu-west-1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# raises a warning&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;This evaluates to:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&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="nt"&gt;&amp;#34;aws-region&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;us-east-1&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;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In this scenario, the ESC environment is still valid, but the final value remains unchanged.&lt;/p&gt;
&lt;h2 id="when-to-use-fnfinal"&gt;When to use fn::final&lt;/h2&gt;
&lt;p&gt;Use &lt;code&gt;fn::final&lt;/code&gt; for:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Security-sensitive values that shouldn&amp;rsquo;t be changed&lt;/li&gt;
&lt;li&gt;Compliance or policy settings enforced by a platform team&lt;/li&gt;
&lt;li&gt;Shared base environments where certain values must remain consistent&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="getting-started"&gt;Getting started&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;fn::final&lt;/code&gt; function is available now in all Pulumi ESC environments. For more information, check out the &lt;a href="https://www.pulumi.com/docs/esc/environments/syntax/builtin-functions/fn-final/"&gt;fn::final documentation&lt;/a&gt;!&lt;/p&gt;</description><author>Pablo Terradillos</author><author>Sean Yeh</author><category>esc</category><category>features</category></item><item><title>Introducing the new and improved ESC Editor</title><link>https://www.pulumi.com/blog/new-esc-editor/</link><pubDate>Thu, 15 Jan 2026 08:00:00 -0500</pubDate><guid>https://www.pulumi.com/blog/new-esc-editor/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/new-esc-editor/index.png" /&gt;
&lt;p&gt;Pulumi ESC is Pulumi Cloud’s centralized solution for managing secrets and configuration across every vault and cloud provider you use. It helps teams secure their configuration while adopting modern best practices like short-lived credentials with OIDC and automated secret rotation.&lt;/p&gt;
&lt;p&gt;Whether you’re configuring Pulumi programs, powering applications and services, or managing credentials for tools like the AWS CLI, ESC provides a single, consistent way to do it safely and at scale.&lt;/p&gt;
&lt;p&gt;Behind the scenes, ESC integrates with multiple cloud providers and secret managers, supports composable environments, and offers rich built-in functions, from simple value transformations to encoding files as Base64.&lt;/p&gt;
&lt;p&gt;With this level of power, usability matters more than ever.
That’s why today we’re introducing the new and improved Pulumi ESC Web Editor, designed to make managing secrets and configuration easier, faster, and more intuitive.&lt;/p&gt;
&lt;p&gt;Today, you can create and manage your Pulumi ESC configuration in multiple ways, such as using the CLI &lt;code&gt;set&lt;/code&gt; and &lt;code&gt;edit&lt;/code&gt; commands, or through our &lt;a href="https://www.pulumi.com/docs/esc/development/vs-code-extension/"&gt;VS Code extension&lt;/a&gt;. For many users, however, their first experience with ESC happens in the Pulumi Cloud Console.&lt;/p&gt;
&lt;p&gt;Based on feedback from users of both our YAML Document view and Table view in the Console, we&amp;rsquo;ve been working hard to create a new and improved unified editor experience that makes ESC even easier to work with. One of the most notable improvements is a brand new &lt;strong&gt;Inspect&lt;/strong&gt; tab that lets you easily edit secrets and gain deeper insights into your configuration. With this new UI, you can now freely switch between writing YAML and using rich UI elements to manipulate your environment—and the editor keeps everything in sync, with clear, in-context information about what you&amp;rsquo;re doing and what&amp;rsquo;s possible at every step.&lt;/p&gt;
&lt;p&gt;Let’s explore some of these use cases!&lt;/p&gt;
&lt;h2 id="adding-and-editing-secrets"&gt;Adding and editing secrets&lt;/h2&gt;
&lt;p&gt;Adding secrets is now as simple as selecting &lt;strong&gt;Secret&lt;/strong&gt; from the &lt;strong&gt;Add new&lt;/strong&gt; menu.
&lt;img src="menu.png" alt="&amp;ldquo;Screenshot of add new menu&amp;rdquo;"&gt;&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;Inspect&lt;/strong&gt; tab lets you view and edit your secret securely, automatically encrypting it as ciphertext in your environment definition. No more worrying about accidentally exposing sensitive values!&lt;/p&gt;
&lt;p&gt;&lt;img src="secrets.png" alt="&amp;ldquo;Screenshot of secret editor&amp;rdquo;"&gt;&lt;/p&gt;
&lt;h2 id="using-providers-and-built-in-functions"&gt;Using providers and built-in functions&lt;/h2&gt;
&lt;p&gt;ESC offers a large library of &lt;a href="https://www.pulumi.com/docs/esc/integrations/"&gt;providers&lt;/a&gt; and &lt;a href="https://www.pulumi.com/docs/esc/environments/syntax/builtin-functions/"&gt;built-in functions&lt;/a&gt; to use in your environment. The new editor makes discovering and using them effortless.&lt;/p&gt;
&lt;div class="flex flex-col md:flex-row gap-4 my-4"&gt;
&lt;img src="providers.png" alt="Screenshot of adding providers" class="w-full" /&gt;
&lt;/div&gt;
&lt;div class="flex flex-col md:flex-row gap-4 my-4"&gt;
&lt;img src="functions.png" alt="Screenshot of adding functions" class="w-full" /&gt;
&lt;/div&gt;
&lt;p&gt;When you add a provider or function, the editor inserts it with example values to get you started quickly. The &lt;strong&gt;Inspect&lt;/strong&gt; tab provides instant access to documentation, so you can more easily configure the integrations.&lt;/p&gt;
&lt;p&gt;&lt;img src="provider-docs.png" alt="&amp;ldquo;Screenshot of Provider documentation&amp;rdquo;"&gt;&lt;/p&gt;
&lt;h2 id="exporting-configurations"&gt;Exporting configurations&lt;/h2&gt;
&lt;p&gt;Consuming your configuration where you need it is now easier than ever. The &lt;strong&gt;Export&lt;/strong&gt; menu in the &lt;strong&gt;Inspect&lt;/strong&gt; sidebar lets you quickly expose values as Pulumi config for your stacks, or as environment variables in your shell.&lt;/p&gt;
&lt;p&gt;&lt;img src="exports.png" alt="&amp;ldquo;Screenshot of Exporting configurations&amp;rdquo;"&gt;&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;The new Pulumi ESC Editor brings together the best of both worlds: the power of the YAML editor with the ease of UI controls. Try it out today in the Pulumi Cloud Console and let us know what you think!&lt;/p&gt;</description><author>Sean Yeh</author><author>Vic Fernandez</author><author>Pablo Terradillos</author><category>esc</category><category>features</category></item><item><title>New Pulumi ESC Onboarding and OIDC Provider Experience</title><link>https://www.pulumi.com/blog/esc-new-onboarding/</link><pubDate>Fri, 17 Oct 2025 16:00:00 -0300</pubDate><guid>https://www.pulumi.com/blog/esc-new-onboarding/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/esc-new-onboarding/index.png" /&gt;
&lt;p&gt;Pulumi ESC (Environments, Secrets, and Configuration) provides centralized secrets management and configuration orchestration across your infrastructure and applications. Today, we’re excited to introduce a redesigned onboarding experience and a simpler, automated way to set up Pulumi ESC as an OpenID Connect (OIDC) provider.&lt;/p&gt;
&lt;h2 id="a-new-and-refreshed-onboarding-experience"&gt;A new and refreshed onboarding experience&lt;/h2&gt;
&lt;p&gt;Pulumi ESC helps you manage configuration for Pulumi programs, handle secret rotation, and centralize secrets stored across multiple providers.&lt;/p&gt;
&lt;p&gt;We’ve now started simplifying these workflows from the moment you create a new Environment. The redesigned onboarding experience helps you get the most out of ESC.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.pulumi.com/blog/esc-new-onboarding/esc-onboarding-1.png" alt="The new Pulumi ESC onboarding experience provides a stylish look"&gt;&lt;/p&gt;
&lt;h2 id="using-pulumi-esc-as-an-oidc-provider"&gt;Using Pulumi ESC as an OIDC Provider&lt;/h2&gt;
&lt;p&gt;Among its many uses, &lt;a href="https://www.pulumi.com/docs/esc/environments/configuring-oidc/"&gt;Pulumi ESC can act as an OpenID Connect (OIDC) provider&lt;/a&gt;, issuing short-lived, signed tokens that external systems can exchange for temporary cloud credentials. This eliminates hard-coded credentials and improves your security posture.&lt;/p&gt;
&lt;p&gt;Other Pulumi offerings, such as &lt;a href="https://www.pulumi.com/product/pulumi-insights/"&gt;Pulumi Insights&lt;/a&gt;, use this mechanism to securely scan resources across your organization.&lt;/p&gt;
&lt;h2 id="a-simpler-way-to-set-up-oidc-for-your-cloud-providers"&gt;A simpler way to set up OIDC for your cloud providers&lt;/h2&gt;
&lt;p&gt;Setting up an OIDC provider manually can involve multiple steps and be error-prone. To simplify this, Pulumi ESC now offers automated setup for AWS, Azure, and Google Cloud directly from the onboarding flow.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.pulumi.com/blog/esc-new-onboarding/esc-onboarding-2.png" alt="The new Onboarding experience offers a Login Provider Setup for the most popular cloud providers"&gt;&lt;/p&gt;
&lt;p&gt;For each login provider, we offer different setup options to suit your needs. You can log in with your cloud credentials and let Pulumi Cloud handle the rest, or you can create your resources from your own machine using the Pulumi CLI.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.pulumi.com/blog/esc-new-onboarding/esc-onboarding-3.png" alt="You can setup OIDC Providers via multiple options such as giving pulumi permissions through SSO or via executing a program on your local cli."&gt;&lt;/p&gt;
&lt;p&gt;Previously, you had to go to the AWS Console to create an identity provider, create and configure an IAM Role, and set up the trust policy before finally creating your ESC Environment.&lt;/p&gt;
&lt;p&gt;Now, you can just use SSO, giving Pulumi Cloud permissions to create the necessary resources automatically.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.pulumi.com/blog/esc-new-onboarding/esc-onboarding-4.png" alt="To setup AWS via SSO you need to provide the SSO start URL and SSO region"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.pulumi.com/blog/esc-new-onboarding/esc-onboarding-5.png" alt="AWS will prompt you for permissions to pulumi to create the necessary resources"&gt;&lt;/p&gt;
&lt;p&gt;After we have finished setting up the trust relationship with AWS, we&amp;rsquo;ll set up a new ESC environment for you under the specified project.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.pulumi.com/blog/esc-new-onboarding/esc-onboarding-6.png" alt="A new environment will be created under the project and name you specify"&gt;&lt;/p&gt;
&lt;p&gt;Once setup is complete, your new environment is ready to issue short-lived credentials.&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 aws-login/tehsis-env -- aws s3 ls
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You can now access your cloud resources securely, without worrying about managing long-lived credentials.&lt;/p&gt;
&lt;h2 id="whats-next"&gt;What&amp;rsquo;s next?&lt;/h2&gt;
&lt;p&gt;This is just the beginning of our work to simplify Pulumi ESC setup and onboarding. We’re continuing to refine how teams configure, secure, and manage environments to make getting started with ESC as smooth as possible.&lt;/p&gt;
&lt;p&gt;Try &lt;a href="https://www.pulumi.com/docs/esc/environments/"&gt;Pulumi ESC&lt;/a&gt; today and see how it can streamline your secrets and configuration management!&lt;/p&gt;</description><author>Pablo Terradillos</author><author>Sean Yeh</author><category>esc</category></item><item><title>Introducing Automated Database Credential Rotation for PostgreSQL and MySQL in Pulumi ESC</title><link>https://www.pulumi.com/blog/esc-db-secrets-rotation-launch/</link><pubDate>Wed, 30 Apr 2025 00:00:00 +0000</pubDate><guid>https://www.pulumi.com/blog/esc-db-secrets-rotation-launch/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/esc-db-secrets-rotation-launch/index.png" /&gt;
&lt;p&gt;Securing access to critical data stores is paramount in today&amp;rsquo;s cloud-native world. Yet, managing database credentials often involves static, long-lived passwords – a significant security blind spot. These static secrets, frequently embedded in application configurations or accessible to multiple team members, represent a prime target for attackers. Manually rotating these credentials is a cumbersome, error-prone task that’s often neglected, leaving databases vulnerable for extended periods. Building on our commitment to robust secrets management, we are excited to launch &lt;strong&gt;Automated Database Credential Rotation&lt;/strong&gt; for &lt;strong&gt;PostgreSQL and MySQL&lt;/strong&gt; in &lt;a href="https://www.pulumi.com/product/esc"&gt;Pulumi ESC!&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="the-persistent-challenge-of-static-database-secrets"&gt;The Persistent Challenge of Static Database Secrets&lt;/h2&gt;
&lt;p&gt;Relying on static database credentials introduces substantial risks, which automated rotation helps mitigate:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Security Vulnerabilities &amp;amp; Exposure:&lt;/strong&gt; Static credentials, if compromised through leaks, phishing, or unauthorized access, provide long-term access to attackers. Automated rotation significantly shrinks this window of opportunity.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Operational &amp;amp; Compliance Burdens:&lt;/strong&gt; Manually rotating database credentials is complex, error-prone, and requires careful coordination to avoid downtime. These manual rotations are hard to audit and demonstrate compliance with regulations like SOC 2, GDPR, or HIPAA (which often mandate rotation).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Network Complexity &amp;amp; The DIY Burden:&lt;/strong&gt; Databases in private networks (like AWS VPCs) require secure access for rotation. We provide an open-source &lt;strong&gt;Lambda connector&lt;/strong&gt; for AWS VPCs. While homegrown solutions can bridge the network gap, building and maintaining the &lt;em&gt;actual rotation logic&lt;/em&gt; (state, error handling, two-secret strategy) is complex. Crucially, DIY approaches typically lack integrated revision history, centralized auditing, and unified management provided by platforms like Pulumi ESC, increasing operational overhead.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tooling, Ecosystem, and Cloud-Native Connectivity:&lt;/strong&gt; Despite cloud IAM authentication options, many standard tools (GUIs, BI, ETL), legacy apps, and even certain cloud-native configurations (multi-cloud, specific Kubernetes setups) still rely on username/password. Direct IAM integration isn&amp;rsquo;t always feasible or practical, making automated rotation of traditional credentials essential for broad compatibility and security.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Pulumi ESC addresses these challenges by automating the secrets rotation process, including connectivity options for databases in private AWS networks using our Lambda connector, and allows you to consume them in your applications through ESC&amp;rsquo;s various developer-friendly methods including &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;, etc.&lt;/p&gt;
&lt;h2 id="introducing-esc-rotated-secrets-for-databases"&gt;Introducing ESC Rotated Secrets for Databases&lt;/h2&gt;
&lt;p&gt;Pulumi ESC’s &lt;a href="https://www.pulumi.com/docs/esc/integrations/rotated-secrets/"&gt;Rotated Secrets&lt;/a&gt; capability now extends to your critical databases, bringing automation and enhanced security to credential lifecycle management. We are adding support for the following databases and connectivity options:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left"&gt;Database&lt;/th&gt;
&lt;th style="text-align: center"&gt;Publicly Accessible&lt;/th&gt;
&lt;th style="text-align: center"&gt;AWS VPCs&lt;/th&gt;
&lt;th style="text-align: center"&gt;Azure VNETs&lt;/th&gt;
&lt;th style="text-align: center"&gt;GCloud VPCs&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;&lt;a href="https://www.pulumi.com/docs/esc/integrations/rotated-secrets/postgres/"&gt;&lt;strong&gt;PostgreSQL&lt;/strong&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;✅&lt;/td&gt;
&lt;td style="text-align: center"&gt;✅ &lt;small&gt;(via Lambda)&lt;/small&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;Planned &lt;small&gt;(&lt;a href="https://github.com/pulumi/esc/issues/521"&gt;upvote issue&lt;/a&gt;)&lt;/small&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;Planned &lt;small&gt;(&lt;a href="https://github.com/pulumi/esc/issues/522"&gt;upvote issue&lt;/a&gt;)&lt;/small&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;&lt;a href="https://www.pulumi.com/docs/esc/integrations/rotated-secrets/mysql/"&gt;&lt;strong&gt;MySQL&lt;/strong&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;✅&lt;/td&gt;
&lt;td style="text-align: center"&gt;✅ &lt;small&gt;(via Lambda)&lt;/small&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;Planned &lt;small&gt;(&lt;a href="https://github.com/pulumi/esc/issues/521"&gt;upvote issue&lt;/a&gt;)&lt;/small&gt;&lt;/td&gt;
&lt;td style="text-align: center"&gt;Planned &lt;small&gt;(&lt;a href="https://github.com/pulumi/esc/issues/522"&gt;upvote issue&lt;/a&gt;)&lt;/small&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Key benefits include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Automated Rotation Schedules:&lt;/strong&gt; Effortlessly define rotation frequencies (daily, weekly, monthly) that align with your security policies, eliminating manual toil and ensuring consistency.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;On-Demand Rotation:&lt;/strong&gt; Instantly rotate credentials in response to security events, personnel changes, or policy updates with a single click or command.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Seamless ESC Environment Integration:&lt;/strong&gt; Manage rotated database credentials alongside all your other application configurations within ESC Environments, leveraging composition and environment inheritance.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Two-Secret Strategy:&lt;/strong&gt; ESC maintains both the current and previous valid credentials simultaneously. This prevents application downtime during rotation, as instances can gracefully transition to the new credential.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Auditing and Tracking:&lt;/strong&gt; Maintain a complete audit trail of credential rotations, including who initiated the rotation and when, simplifying compliance and governance.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Admin and Creator Control:&lt;/strong&gt; Securely configure rotation using privileged database &amp;ldquo;managing user&amp;rdquo; credentials stored within ESC, keeping them separate from the rotated credentials consumed by applications.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Configure Webhooks for Automation:&lt;/strong&gt; Trigger notifications, CI/CD pipelines (e.g., Pulumi Deployments to update application stacks), or custom workflows upon successful rotation, keeping dependent systems synchronized.&lt;/li&gt;
&lt;/ul&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;The following setup guide provides a detailed walkthrough for rotating &lt;a href="https://www.pulumi.com/docs/esc/integrations/rotated-secrets/postgres/"&gt;&lt;strong&gt;PostgreSQL&lt;/strong&gt;&lt;/a&gt; credentials for an &lt;strong&gt;AWS RDS instance hosted within a private VPC&lt;/strong&gt;, which requires the AWS Lambda-based connector. For publicly accessible databases (PostgreSQL or MySQL), you can use the simpler &lt;strong&gt;Direct Connect&lt;/strong&gt; method documented on the respective integration pages. Please refer to the &lt;a href="https://www.pulumi.com/docs/esc/integrations/rotated-secrets/mysql/"&gt;&lt;strong&gt;MySQL&lt;/strong&gt;&lt;/a&gt; documentation page for specific instructions on MySQL rotation (both Direct Connect and Lambda Connector).&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="how-to-set-up-and-use-rotation-for-aws-rds-postgresql-running-in-vpc"&gt;How to Set Up and Use Rotation for AWS RDS PostgreSQL running in VPC&lt;/h2&gt;
&lt;p&gt;Setting up rotation for AWS RDS or Aurora PostgreSQL databases running inside an AWS VPC involves &lt;a href="https://www.pulumi.com/docs/esc/environments/rotation/db-user-setup/"&gt;creating the required users&lt;/a&gt; within your database, deploying the AWS Lambda connector infrastructure via a Pulumi template, configuring ESC environments, and scheduling the rotation.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Understanding the AWS Lambda Connector:&lt;/strong&gt; The open-source &lt;a href="https://github.com/pulumi/templates/tree/master/esc-connector-lambda-typescript"&gt;ESC Lambda connector&lt;/a&gt; acts as a secure proxy for database credential rotation within your VPC. It enables Pulumi ESC to safely rotate database credentials without needing direct network access from ESC to your database and without exposing your database to external networks. This connector is currently required to rotate credentials for PostgreSQL or MySQL databases hosted within an AWS VPC. Note: The AWS Lambda Connector is only available to Enterprise and Business Critical customers.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 1: Prepare Your PostgreSQL Database Users&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;You&amp;rsquo;ll need two &lt;em&gt;types&lt;/em&gt; of users configured, resulting in &lt;em&gt;three&lt;/em&gt; specific database user accounts:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Managing User:&lt;/strong&gt; A privileged user that ESC will use (via the Lambda connector) to perform the password rotations. This user needs permissions to change the passwords of the application users.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Application User 1 and Application User 2:&lt;/strong&gt; The two application users whose passwords ESC will manage. ESC rotates between these two users, ensuring two users are always active as applications gradually phase out the &lt;code&gt;previous&lt;/code&gt; user credentials.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Connect to the database as a superuser and run the following SQL commands:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Create the application users whose passwords you want ESC to rotate automatically:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;```sql
CREATE USER user1 WITH PASSWORD 'initial_password';
GRANT SELECT, INSERT, UPDATE ON yourDatabase TO user1;
CREATE USER user2 WITH PASSWORD 'initial_password';
GRANT SELECT, INSERT, UPDATE ON yourDatabase TO user2;
```
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create the designated &amp;ldquo;managing user&amp;rdquo; account with privileges to modify passwords for the application users:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;```sql
CREATE USER managing_user WITH PASSWORD 'manager_password';
ALTER USER managing_user WITH CREATEROLE;
GRANT user1 TO managing_user WITH ADMIN OPTION;
GRANT user2 TO managing_user WITH ADMIN OPTION;
```
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Step 2: Bootstrap Rotation Infrastructure (Lambda Connector) and Create ESC Environments&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;To rotate credentials for PostgreSQL databases within AWS VPCs securely, you need to configure an &lt;a href="https://www.pulumi.com/docs/esc/environments/rotation/aws-lambda/"&gt;AWS Lambda function (the connector)&lt;/a&gt; within your VPC and create the corresponding ESC environments.&lt;/p&gt;
&lt;p&gt;If your PostgreSQL instance is running on AWS RDS, we recommend using our &lt;a href="https://github.com/pulumi/templates/tree/master/esc-connector-lambda-typescript"&gt;Pulumi Template&lt;/a&gt; to simplify the process of creating the Lambda function, associated AWS IAM Roles, Security Groups, and the basic ESC environment structure. You can start it from the &lt;a href="https://app.pulumi.com/new?template=https://github.com/pulumi/templates/esc-connector-lambda-typescript"&gt;Pulumi console&lt;/a&gt; or by running the following command in your terminal:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Run &lt;code&gt;pulumi new esc-connector-lambda-typescript&lt;/code&gt; in your terminal.&lt;/li&gt;
&lt;li&gt;This command initializes a new Pulumi project designed to provision the necessary AWS Lambda connector resources and create the ESC environments.&lt;/li&gt;
&lt;li&gt;Follow the prompts. You will first provide a &lt;strong&gt;Pulumi project name&lt;/strong&gt; (e.g., &lt;code&gt;my-db-rotation-infra&lt;/code&gt;). Then, you will be prompted for configuration values like:
&lt;ul&gt;
&lt;li&gt;Your target AWS Region (&lt;code&gt;aws:region&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;The RDS Database Identifier (&lt;code&gt;rdsDbIdentifier&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;The specific &lt;strong&gt;name for the ESC rotation environment&lt;/strong&gt; (e.g., &lt;code&gt;postgresrotation/Rotator&lt;/code&gt;). This environment will contain the two application users&amp;rsquo; credentials and configuration for rotation.&lt;/li&gt;
&lt;li&gt;The specific &lt;strong&gt;name for the ESC managing credentials environment&lt;/strong&gt; (e.g., &lt;code&gt;postgresrotation/ManagingCreds&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;pulumi up&lt;/code&gt; to deploy the AWS resources and create the ESC environments using the names you provided.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Step 3: Configure ESC Environments and Test&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The Pulumi template creates two ESC environments with most of the configuration pre-filled. You need to update them with your specific PostgreSQL user credentials and database name.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Managing Credentials Environment (e.g., &lt;code&gt;postgresrotation/ManagingCreds&lt;/code&gt;):&lt;/strong&gt; Navigate to this environment in the Pulumi Cloud console. Update the managing user&amp;rsquo;s username and password. The &lt;code&gt;awsLogin&lt;/code&gt; section, which provides credentials for the Lambda connector to assume, should be pre-filled by the template.&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;# postgresrotation/ManagingCreds&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;managingUser&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;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;managing_user&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Replace with your managing user&amp;#39;s name&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;password&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;# Securely replace the placeholder with your managing user&amp;#39;s password using fn::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 class="nt"&gt;fn::secret&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;ciphertext&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ZXNjeA...&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Replace with your encrypted password&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;awsLogin&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::aws-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;duration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;1h&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;roleArn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;arn:aws:iam::616138583583:role/PulumiEscSecretRotatorLambda-InvocationRole-7e4646f&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Example Role ARN populated by template&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;sessionName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;pulumi-esc-secret-rotator-${esc.context.environment}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Example Session Name populated by template&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;&lt;strong&gt;Rotation Environment (e.g., &lt;code&gt;&amp;lt;project-name&amp;gt;/Rotator&lt;/code&gt;):&lt;/strong&gt; Navigate to this environment. Most fields related to the Lambda connector (Lambda ARN, host, port, references) are pre-filled by the template outputs. You &lt;em&gt;must&lt;/em&gt; update the database name and the application usernames mapping. Note the &lt;code&gt;connector.awsLambda&lt;/code&gt; block indicating the use of the Lambda connector.&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;# postgresrotation/Rotator&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;dbRotator&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::postgres&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;database&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 AWS Lambda connector for private VPC access&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;connector&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;awsLambda&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.postgresrotation.ManagingCreds.awsLogin}&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;lambdaArn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;arn:aws:lambda:us-west-2:616138583583:function:PulumiEscSecretRotatorLambda-Function-d9932fe&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Example Lambda ARN populated by template&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;# Database connection details (used by the Lambda connector)&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;database&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;mydb&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Replace with your DB name&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;host&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;tf-20250428212643894700000001.cluster-chuqccm8uxqx.us-west-2.rds.amazonaws.com&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Example Host populated by template&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;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;5432&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Example Port populated by template&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;managingUser&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.postgresrotation.ManagingCreds.managingUser}&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;# List of application users whose passwords will be rotated&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;rotateUsers&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;username1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;user1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Replace DB username if different from logical name&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;username2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;user2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# Replace DB username if different from logical name&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;# state section is automatically managed by ESC after first rotation&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;# Do not provide state unless migrating existing, known credentials.&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;# state:&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;# current:&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;# password:&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;# fn::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 class="c"&gt;# ciphertext: ZXNjeAAAA...&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;# username: user1&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;# previous:&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;# password:&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;# fn::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 class="c"&gt;# ciphertext: ZXNje21AA...&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;# username: user2&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;&lt;strong&gt;Test with Manual Rotation:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Use the triple-dot menu -&amp;gt; &amp;ldquo;Rotate Secrets&amp;rdquo; in the Pulumi Cloud UI for the Rotator environment.&lt;/li&gt;
&lt;li&gt;Alternatively, use the Pulumi CLI: &lt;code&gt;pulumi env rotate &amp;lt;your-org&amp;gt;/&amp;lt;project-name&amp;gt;/Rotator&amp;gt;&lt;/code&gt; (e.g., &lt;code&gt;pulumi env rotate myorg/postgresrotation/Rotator&lt;/code&gt;). Remember to replace &lt;code&gt;&amp;lt;your-org&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;project-name&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Perform a rotation. If you &lt;em&gt;didn&amp;rsquo;t&lt;/em&gt; provide the &lt;code&gt;state&lt;/code&gt; block, this first rotation generates a new password for the user designated as &lt;code&gt;current&lt;/code&gt; (e.g., &lt;code&gt;user1&lt;/code&gt; associated with &lt;code&gt;username1&lt;/code&gt;) and updates it in the database via the Lambda connector. The &lt;code&gt;dbRotator&lt;/code&gt; value in ESC will now show this user/password under &lt;code&gt;current&lt;/code&gt;, and the &lt;code&gt;state&lt;/code&gt; block will be populated.&lt;/li&gt;
&lt;li&gt;Perform a &lt;em&gt;second&lt;/em&gt; rotation. Observe how the previous &lt;code&gt;current&lt;/code&gt; user (&lt;code&gt;user1&lt;/code&gt;/&lt;code&gt;username1&lt;/code&gt;) and its password become the &lt;code&gt;previous&lt;/code&gt; entry in the ESC value. The system now rotates the password for the &lt;em&gt;other&lt;/em&gt; user (&lt;code&gt;user2&lt;/code&gt;/&lt;code&gt;username2&lt;/code&gt;), makes it the new &lt;code&gt;current&lt;/code&gt;, and updates the database accordingly. Subsequent rotations cycle between &lt;code&gt;user1&lt;/code&gt; and &lt;code&gt;user2&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Check the Environment Revision History in the Pulumi Cloud console to track the changes to the &lt;code&gt;current&lt;/code&gt; and &lt;code&gt;previous&lt;/code&gt; state fields after each rotation.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Step 4: Schedule Automated Rotations&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Once you are satisfied that manual rotations via the Lambda connector are working correctly, navigate to the &amp;ldquo;Secret Rotation&amp;rdquo; tab for your Rotator environment (e.g., &lt;code&gt;postgresrotation/Rotator&lt;/code&gt;) in the Pulumi Cloud console.&lt;/li&gt;
&lt;li&gt;Define your desired automated rotation schedule (e.g., every 30 days). ESC will automatically trigger rotations according to this schedule, ensuring your credentials stay fresh without manual intervention.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="whats-next"&gt;What’s Next?&lt;/h2&gt;
&lt;p&gt;This launch significantly enhances database security posture through automation for PostgreSQL and MySQL, but we&amp;rsquo;re just getting started. We plan to expand our rotated secrets capabilities:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;More Databases:&lt;/strong&gt; Support for &lt;a href="https://github.com/pulumi/esc/issues/525"&gt;MongoDB&lt;/a&gt;, &lt;a href="https://github.com/pulumi/esc/issues/526"&gt;Microsoft SQL Server&lt;/a&gt;, &lt;a href="https://github.com/pulumi/esc/issues/527"&gt;Oracle&lt;/a&gt;, and others.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Databases in Private Networks on Other Clouds:&lt;/strong&gt; Rotation solutions for databases hosted in private networks within &lt;a href="https://github.com/pulumi/esc/issues/521"&gt;Azure&lt;/a&gt;, &lt;a href="https://github.com/pulumi/esc/issues/522"&gt;Google Cloud&lt;/a&gt;, and more.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Have a specific database or integration in mind? Upvote existing issues or open a new request in our &lt;a href="https://github.com/pulumi/esc/issues"&gt;GitHub repository&lt;/a&gt;!&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Pulumi ESC&amp;rsquo;s Automated Database Credential Rotation drastically simplifies a critical security task. By automating the rotation of &lt;strong&gt;PostgreSQL&lt;/strong&gt; and &lt;strong&gt;MySQL&lt;/strong&gt; credentials, ESC reduces operational overhead, minimizes the risk associated with static secrets, and helps you meet compliance requirements more easily. Whether your databases are publicly accessible (using Direct Connect) or in private AWS networks (using the Lambda connector), ESC provides a unified way to manage their lifecycle securely.&lt;/p&gt;
&lt;p&gt;We encourage you to explore the &lt;a href="https://www.pulumi.com/docs/esc/"&gt;Pulumi ESC documentation&lt;/a&gt; and try out rotated database secrets for &lt;a href="https://www.pulumi.com/docs/esc/integrations/rotated-secrets/postgres/"&gt;PostgreSQL&lt;/a&gt; and &lt;a href="https://www.pulumi.com/docs/esc/integrations/rotated-secrets/mysql/"&gt;MySQL&lt;/a&gt;. Your feedback is invaluable – please share your experiences and suggestions on our &lt;a href="https://github.com/pulumi/esc"&gt;GitHub repository&lt;/a&gt;. Secure your databases with automated rotation and build with confidence!&lt;/p&gt;</description><author>Sean Yeh</author><author>Iaroslav Titov</author><author>Arun Loganathan</author><category>esc</category><category>secrets</category><category>features</category><category>rotation</category><category>database</category><category>security</category></item><item><title>Announcing AWS Systems Manager - Parameter Store Support for Pulumi ESC</title><link>https://www.pulumi.com/blog/pulumi-esc-aws-parameter-store-support/</link><pubDate>Mon, 16 Dec 2024 12:00:00 -0600</pubDate><guid>https://www.pulumi.com/blog/pulumi-esc-aws-parameter-store-support/</guid><description>
&lt;img src="https://www.pulumi.com/images/generated/blog/pulumi-esc-aws-parameter-store-support/index.png" /&gt;
&lt;p&gt;We are super excited to announce integration support for AWS Systems Manager - Parameter Store within Pulumi Environments, Secrets, and Configuration (&lt;a href="https://www.pulumi.com/product/esc"&gt;ESC&lt;/a&gt;). Parameter Store is a popular managed service by AWS for storing and managing secrets and other configuration, and its integration with ESC has been highly requested among the community.&lt;/p&gt;
&lt;p&gt;With the AWS Parameter Store ESC Provider, development teams can now import their AWS Parameter Store parameters as &lt;a href="https://www.pulumi.com/docs/esc/environments/working-with-environments/#projecting-environment-variables"&gt;environment variables&lt;/a&gt; or as &lt;a href="https://www.pulumi.com/docs/esc/integrations/infrastructure/pulumi-iac/"&gt;Pulumi Config&lt;/a&gt; in their workflows, all in a secure and convenient way.&lt;/p&gt;
&lt;p&gt;As we continue to expand our roster of integrations, it&amp;rsquo;s easier now than ever to manage and use secrets and configuration all in one place by using ESC. If you or your team are users of AWS Parameter Store, say goodbye to managing multiple configuration sources and give this provider a try!&lt;/p&gt;
&lt;h2 id="how-does-it-work"&gt;How does it work?&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Add parameters to AWS Parameter Store.&lt;/li&gt;
&lt;li&gt;Use &lt;a href="https://www.pulumi.com/docs/esc/integrations/dynamic-login-credentials/aws-login/"&gt;aws-login&lt;/a&gt; to authenticate with AWS.&lt;/li&gt;
&lt;li&gt;Define a path name, and enter the parameter name you want to retrieve. This will be imported into the path name that you have defined.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;AWS Parameter Store provider syntax:&lt;/strong&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="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;params&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::aws-parameter-store&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;region&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;us-west-1&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;${aws.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;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="nt"&gt;myKey&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;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;/myNamespace/myKey&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;myKeyByVersion&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;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;/myNamespace/myKey:1&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;myKeyByVersionLabel&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;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;/myNamespace/myKey:stable&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;secureKey&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;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;/myNamespace/secureKey&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;decrypt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&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;h2 id="demo"&gt;Demo&lt;/h2&gt;
&lt;p&gt;Now that we know how to use the Pulumi ESC Parameter Store provider, let&amp;rsquo;s use it to pull some parameters!&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Setup &lt;a href="https://www.pulumi.com/docs/esc/environments/configuring-oidc/aws/"&gt;OpenID Connect for AWS&lt;/a&gt;. We will use OIDC to authenticate with AWS.&lt;/li&gt;
&lt;li&gt;Store some parameters in Parameter Store. In the demo, we will store a String &lt;code&gt;/test/api-endpoint&lt;/code&gt; and a SecureString &lt;code&gt;/test/api-key&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Create a new Pulumi ESC Environment with the following definition. Make sure to replace the OIDC &lt;code&gt;roleArn&lt;/code&gt; with your own.&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="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;aws&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::aws-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;duration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;1h&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;roleArn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;arn:aws:iam::123456789:role/esc-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;sessionName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;pulumi-environments-session&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;params&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::aws-parameter-store&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;region&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;us-west-1&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;${aws.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;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="nt"&gt;api-endpoint&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;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;/test/api-endpoint&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&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;/test/api-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="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;decrypt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&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_ENDPOINT&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;${params.api-endpoint}&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;${params.api-key}&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;ul&gt;
&lt;li&gt;Open the environment to ensure we are able to successfully pull the credentials from AWS Parameter Store&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;pulumi env open &amp;lt;project/environment&amp;gt; --format shell&lt;/code&gt; to view the exported environment variables from this ESC environment.&lt;/li&gt;
&lt;li&gt;Use &lt;a href="https://www.pulumi.com/docs/iac/cli/commands/pulumi_env_run/"&gt;pulumi env run&lt;/a&gt; to run any command with these environment variables. For example, we can now run &lt;code&gt;pulumi env run &amp;lt;project/environment&amp;gt; -- &amp;lt;your command&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;pulumi env run&lt;/code&gt; passes the configuration stored under the &lt;code&gt;environmentVariables&lt;/code&gt; section for use with the provided command, without ever storing them locally on your machine.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;We are excited to expand our roster of integrations with the new AWS Parameter Store ESC Provider, providing developers more flexibility and choices. We look forward to seeing what you will create next using Pulumi ESC!&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Visit the &lt;a href="https://www.pulumi.com/docs/esc/integrations/dynamic-secrets/aws-parameter-store/"&gt;AWS Parameter Store Provider Page&lt;/a&gt; for more detailed documentation on this provider.&lt;/li&gt;
&lt;li&gt;Visit our &lt;a href="https://www.pulumi.com/docs/esc/"&gt;Pulumi ESC docs&lt;/a&gt; to learn more about Pulumi ESC and its supported &lt;a href="https://www.pulumi.com/docs/esc/integrations/"&gt;integrations&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As always, we deeply value your insights. Your &lt;a href="https://github.com/pulumi/esc/issues/new/choose"&gt;feedback&lt;/a&gt; is instrumental in helping us refine and enhance our solutions to better align with your needs.&lt;/p&gt;</description><author>Sean Yeh</author><author>Cleve Littlefield</author><category>esc</category><category>secrets</category><category>aws</category><category>features</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></channel></rss>