<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>atmos Blog</title>
        <link>https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog</link>
        <description>atmos Blog</description>
        <lastBuildDate>Wed, 11 Nov 2026 00:00:00 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <item>
            <title><![CDATA[Operation-Scoped Vault and OpenBao Identities]]></title>
            <link>https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/operation-scoped-vault-identities</link>
            <guid>https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/operation-scoped-vault-identities</guid>
            <pubDate>Wed, 11 Nov 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Temporary Vault and OpenBao reader tokens can outlive the lookup that needs them. The opt-in operation lifetime for identity-backed stores gives that lookup a fresh reader identity and completes logout before returning values to its consumer.]]></description>
            <content:encoded><![CDATA[<p>Temporary Vault and OpenBao reader tokens can outlive the lookup that needs them. The opt-in <a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/secrets#track-1--secret-stores-secret-true">operation lifetime for identity-backed stores</a> gives that lookup a fresh reader identity and completes logout before returning values to its consumer.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/operation-scoped-vault-identities#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>A reusable authentication session is useful for repeated commands, but a temporary reader token may need a shorter lifetime: acquire it, fetch the requested secret, and revoke it before another command receives the value. A failed read or an interrupted command needs the same cleanup boundary.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/operation-scoped-vault-identities#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>The new <code>options.identity_lifetime: operation</code> setting is being prepared in <a href="https://github.com/cloudposse/atmos/pull/3668" target="_blank" rel="noopener noreferrer" class="">PR #3668</a> and has not been released. It takes effect only when explicitly configured on a HashiCorp Vault or OpenBao store.</p>
<p>Each operation authenticates the selected target identity afresh and logs out that operation's credentials before returning. Existing sessions for the same target identity, reusable provider sessions, and ancestor identity sessions are preserved. If cleanup fails, Atmos returns an error and withholds read, list, and existence results.</p>
<p>Graceful SIGINT/SIGTERM cancellation gives credential acquisition and cleanup bounded time to finish. Remote revocation depends on the configured identity revoking its token during logout. Forced termination, an unreachable issuer, or an ambiguous network response can prevent confirmed revocation, so short server-enforced token TTLs remain necessary.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/operation-scoped-vault-identities#how-to-use-it" class="hash-link" aria-label="Direct link to How to Use It" title="Direct link to How to Use It" translate="no">​</a></h2>
<p>Configure a dedicated <a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/secrets#track-1--secret-stores-secret-true">native auth identity</a> that emits <code>environment/v1</code> credentials containing <code>VAULT_TOKEN</code> and revokes its issued token on logout. Pin that identity to the store and set its lifetime:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token key atrule">stores</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">vault-secrets</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">type</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> hashicorp</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">vault</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">secret</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token boolean important" style="color:rgb(255, 88, 116)">true</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">identity</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> vault</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">reader</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">options</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">address</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> https</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain">//vault.example.com</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">mount</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> secret</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">identity_lifetime</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> operation</span></span><br></div></code></pre></div></div>
<p>Operation lifetime requires an explicit store identity and an authentication manager that supports operation ownership. Authentication failures do not fall back to static or ambient tokens. The default <code>identity_lifetime: session</code> keeps the existing reusable-session behavior.</p>
<p>See the <a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/secrets#track-1--secret-stores-secret-true">secret-store configuration guide</a> for the identity and cleanup requirements, and the <a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/plugins#official-secret-store-authentication">official secret-store authentication example</a> for connecting fetched values to a command's environment.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/operation-scoped-vault-identities#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>Review <a href="https://github.com/cloudposse/atmos/pull/3668" target="_blank" rel="noopener noreferrer" class="">PR #3668</a> and share feedback on identity isolation, cancellation, and cleanup behavior before release.</p>]]></content:encoded>
            <category>Feature</category>
            <category>Security</category>
        </item>
        <item>
            <title><![CDATA[Clickable Terminal Links]]></title>
            <link>https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/terminal-links</link>
            <guid>https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/terminal-links</guid>
            <pubDate>Tue, 10 Nov 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[When a CLI needs you to open a page in a browser, it usually prints a URL and leaves the rest to you:]]></description>
            <content:encoded><![CDATA[<p>When a CLI needs you to open a page in a browser, it usually prints a URL and leaves the rest to you:
select it, copy it, paste it. Sign-in URLs make that painful. They're full of tokens, they often run
to hundreds of characters, and they wrap across the screen. Atmos can now deliver those links the way
your terminal handles best: as a short clickable link, as a copy on your clipboard, or as the plain URL.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/terminal-links#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>Several Atmos commands hand you a URL to open yourself. <a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/auth/login"><code>atmos auth login</code></a>
shows the AWS sign-in URL in case the browser doesn't open, and
<a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/auth/console"><code>atmos auth console</code></a> shows a console sign-in URL when it doesn't launch a
browser. AWS IAM Identity Center URLs now exceed 500 characters, and console sign-in URLs carry a full
session token. Printing the raw URL was the only option, even though most modern terminals can show a
short label as a clickable hyperlink and every desktop has a clipboard.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/terminal-links#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>A new <a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/settings/terminal#long-urls"><code>settings.terminal.links</code></a> option controls how
Atmos delivers these links:</p>
<ul>
<li class=""><code>auto</code> (default): a short clickable link, such as "Open AWS sign-in", when your terminal is known to
support hyperlinks. Otherwise, the plain URL.</li>
<li class=""><code>osc8</code>: always the clickable link. Use this when your terminal supports hyperlinks but Atmos can't
tell, which is common inside a container or over SSH.</li>
<li class=""><code>clipboard</code>: copy the URL straight to your clipboard. If no clipboard is reachable, Atmos asks the
terminal to copy it and also prints the URL.</li>
<li class=""><code>raw</code>: always the plain URL.</li>
</ul>
<p>In <code>auto</code> mode, Atmos recognizes iTerm2, VS Code, WezTerm, Ghostty, kitty, Windows Terminal, GNOME
Terminal and other VTE-based terminals, Konsole, and Orca. Inside <code>tmux</code> or <code>screen</code>, or anywhere it can't
identify the terminal, it falls back to the plain URL. When output isn't a terminal, such as in CI or
when piped, Atmos always prints the plain URL and never touches the clipboard. Atmos also honors
the <code>FORCE_HYPERLINK</code> convention other command-line tools use: <code>1</code> forces the clickable link and <code>0</code>
turns it off.</p>
<p>The AWS sign-in prompts are tidier too. A URL that fits in 80 columns stays inside the prompt's box. A
longer one is delivered below the box, so the border no longer wraps into the URL or ends up in the text
you copy.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/terminal-links#how-to-use-it" class="hash-link" aria-label="Direct link to How to Use It" title="Direct link to How to Use It" translate="no">​</a></h2>
<p>Most people don't need to change anything: <code>auto</code> already gives you a clickable link in a supported
terminal.</p>
<p>To pick a mode for your project, set it in <code>atmos.yaml</code>:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token key atrule">settings</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">terminal</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">links</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> clipboard   </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># auto, osc8, clipboard, or raw</span></span><br></div></code></pre></div></div>
<p>To override it for a shell session or a single command, use the
<a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/cli/environment-variables"><code>ATMOS_TERMINAL_LINKS</code></a> environment variable or the
<a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/cli/global-flags#core-global-flags"><code>--links</code></a> global flag:</p>
<div class="language-shell codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-shell codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A"><div class="token-line" style="color:#d6deeb"><span class="token builtin class-name" style="color:rgb(255, 203, 139)">export</span><span class="token plain"> </span><span class="token assign-left variable" style="color:rgb(214, 222, 235)">ATMOS_TERMINAL_LINKS</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">osc8</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos auth console --no-open </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--links</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">clipboard</span><br></div></code></pre></div></div>
<p>The flag takes precedence over the environment variable, which takes precedence over <code>atmos.yaml</code>.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/terminal-links#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>If your terminal supports hyperlinks but <code>auto</code> doesn't recognize it, let us know in
<a href="https://github.com/cloudposse/atmos/issues" target="_blank" rel="noopener noreferrer" class="">GitHub Issues</a> so we can add it.</p>]]></content:encoded>
            <category>Feature</category>
            <category>DX</category>
        </item>
        <item>
            <title><![CDATA[Check Out an Exact Commit, Tag, or Ref with atmos git clone --ref]]></title>
            <link>https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/git-clone-ref</link>
            <guid>https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/git-clone-ref</guid>
            <pubDate>Mon, 09 Nov 2026 12:00:00 GMT</pubDate>
            <description><![CDATA[A CI job is supposed to build the commit that triggered it. But a branch name is a moving target: by the]]></description>
            <content:encoded><![CDATA[<p>A CI job is supposed to build the commit that triggered it. But a branch name is a moving target: by the
time the job starts, someone may have pushed again, and a restored checkout cache may already be ahead of
the event. Checking out "the branch" quietly gives you a different revision than the one you were asked to
test. Now <a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/git/clone#flags"><code>atmos git clone --ref</code></a> pins the checkout to an exact commit
SHA, tag, or ref.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/git-clone-ref#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>The <code>--branch</code> flag maps to <code>git clone --branch</code>, which only accepts branch and tag names, not commit
SHAs. Reconciling an existing checkout also fast-forwards to the branch tip. That is the right behavior for
keeping a working copy current, and the wrong behavior when a pipeline must operate on one immutable
revision, such as the event SHA for a plan, an apply, or a <code>describe affected</code> diff.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/git-clone-ref#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>The new <code>--ref</code> flag (or the <code>ATMOS_GIT_REF</code> environment variable) accepts a branch, tag, full ref such as
<code>refs/tags/v1</code>, or a commit SHA. Atmos fetches exactly that ref and checks it out detached:</p>
<ul>
<li class=""><strong>Fresh clones</strong> fetch the requested ref instead of checking out the default branch.</li>
<li class=""><strong>Existing checkouts</strong> move to the requested revision exactly, even when the cached copy is ahead of it.
Nothing is merged or fast-forwarded past it. Uncommitted changes are still refused.</li>
<li class=""><strong>Named repositories and URI queries:</strong> <code>--ref</code> overrides any configured branch.</li>
<li class=""><strong>Submodules</strong> are updated to match when submodules are enabled.</li>
</ul>
<p><code>--ref</code> and <code>--branch</code> are mutually exclusive. The
<a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/git/clone#fork-pr-safety-gate">fork-PR safety gate</a> also applies: in an elevated
<code>pull_request_target</code> or <code>workflow_run</code> event for a fork pull request, an explicit <code>--ref</code> is refused unless
you opt in with <code>--allow-unsafe-fork</code>.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/git-clone-ref#how-to-use-it" class="hash-link" aria-label="Direct link to How to Use It" title="Direct link to How to Use It" translate="no">​</a></h2>
<p>Pin a CI job to its event revision and keep full history for diffs:</p>
<div class="language-shell codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-shell codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A"><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos </span><span class="token function" style="color:rgb(130, 170, 255)">git</span><span class="token plain"> clone </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--ci</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--ref</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"</span><span class="token string variable" style="color:rgb(214, 222, 235)">$GITHUB_SHA</span><span class="token string" style="color:rgb(173, 219, 103)">"</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--depth</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0</span><br></div></code></pre></div></div>
<p>Check out a release tag of a managed repository:</p>
<div class="language-shell codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-shell codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A"><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos </span><span class="token function" style="color:rgb(130, 170, 255)">git</span><span class="token plain"> clone flux-deploy </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--ref</span><span class="token plain"> v1.2.0</span><br></div></code></pre></div></div>
<p>See the <a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/git/clone#flags"><code>atmos git clone</code> reference</a> for every flag.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/git-clone-ref#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>Try <code>--ref</code> in your pipelines and tell us how it works for you in the
<a href="https://cloudposse.com/slack" target="_blank" rel="noopener noreferrer" class="">Cloud Posse Slack</a> or on <a href="https://github.com/cloudposse/atmos/issues" target="_blank" rel="noopener noreferrer" class="">GitHub</a>.</p>]]></content:encoded>
            <category>Feature</category>
        </item>
        <item>
            <title><![CDATA[Bind Published Container Ports to a Specific Interface]]></title>
            <link>https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/container-port-bind</link>
            <guid>https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/container-port-bind</guid>
            <pubDate>Mon, 09 Nov 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Publishing a container port usually exposes it on every network interface of the host. For a local database, an admin portal, or a cloud emulator, that means anything on the same network can reach a service that was only ever meant for your own machine. Container port mappings in Atmos now accept an IP:port string in host, so you can keep a published port on loopback, or on any single interface you choose.]]></description>
            <content:encoded><![CDATA[<p>Publishing a container port usually exposes it on every network interface of the host. For a local database, an admin portal, or a cloud emulator, that means anything on the same network can reach a service that was only ever meant for your own machine. Container port mappings in Atmos now accept an <code>IP:port</code> string in <code>host</code>, so you can keep a published port on loopback, or on any single interface you choose.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/container-port-bind#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>A port mapping such as <code>host: 3000</code> / <code>container: 3000</code> asks the container runtime to listen on <code>0.0.0.0:3000</code>. On a laptop connected to shared Wi-Fi, or on a CI runner, that service becomes reachable from other machines. Restricting it meant dropping down to raw <code>docker run -p 127.0.0.1:3000:3000</code> invocations outside of Atmos.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/container-port-bind#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>The existing <code>host</code> field now accepts either a port number or an <code>IP:port</code> string. For example, <code>host: "127.0.0.1:3000"</code> publishes port 3000 only on loopback. Numeric values retain the runtime's default binding, so existing configuration is unchanged.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/container-port-bind#how-to-use-it" class="hash-link" aria-label="Direct link to How to Use It" title="Direct link to How to Use It" translate="no">​</a></h2>
<p>Set <code>host</code> to an address and port in any entry under <a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/stacks/components/container#port-bindings"><code>run.ports</code></a>:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token key atrule">components</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">container</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">portal</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">image</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> my</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">portal</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain">local</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">run</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">ports</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">          </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> </span><span class="token key atrule">host</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"127.0.0.1:3000"</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">            </span><span class="token key atrule">container</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">3000</span></span><br></div></code></pre></div></div>
<ul>
<li class="">IPv6 addresses require brackets: <code>host: "[::1]:3000"</code>. Use an IP literal, not a hostname.</li>
<li class="">Omitting <code>host</code> or setting it to <code>0</code> lets the runtime assign a free host port. Use <code>host: "127.0.0.1:0"</code> to restrict that automatic assignment to loopback.</li>
<li class="">The same field works in container workflow steps, background container services, and emulators.</li>
</ul>
<p>Binding to loopback narrows where the runtime listens, but it isn't a firewall. Docker Engine versions before 28.0.0 can expose localhost-published ports to hosts on the same network segment, and some network configurations allow direct routing to container ports. See Docker's <a href="https://docs.docker.com/engine/network/port-publishing/" target="_blank" rel="noopener noreferrer" class="">port publishing</a> documentation for details.</p>
<p>Port bindings are fixed when a container is created. After you change one, recreate just that container:</p>
<div class="language-shell codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-shell codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A"><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos container down portal </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-s</span><span class="token plain"> </span><span class="token operator" style="color:rgb(127, 219, 202)">&lt;</span><span class="token plain">stack</span><span class="token operator" style="color:rgb(127, 219, 202)">&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos container up portal </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-s</span><span class="token plain"> </span><span class="token operator" style="color:rgb(127, 219, 202)">&lt;</span><span class="token plain">stack</span><span class="token operator" style="color:rgb(127, 219, 202)">&gt;</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/container-port-bind#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>Questions or ideas for container components? Join us in the <a href="https://cloudposse.com/slack" target="_blank" rel="noopener noreferrer" class="">Cloud Posse community</a> or open an issue on <a href="https://github.com/cloudposse/atmos" target="_blank" rel="noopener noreferrer" class="">GitHub</a>.</p>]]></content:encoded>
            <category>Enhancement</category>
        </item>
        <item>
            <title><![CDATA[Native Atmos CI Support for Gitea Actions]]></title>
            <link>https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/gitea-actions-ci-provider</link>
            <guid>https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/gitea-actions-ci-provider</guid>
            <pubDate>Mon, 09 Nov 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Teams running infrastructure workflows on Gitea can now use Atmos native CI to publish]]></description>
            <content:encoded><![CDATA[<p>Teams running infrastructure workflows on Gitea can now use Atmos native CI to publish
commit statuses and Terraform plan comments directly to their pull requests. Atmos detects
Gitea Actions automatically, so the same CLI commands you run locally can report their
results in your self-hosted Git service.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="whats-supported">What’s Supported<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/gitea-actions-ci-provider#whats-supported" class="hash-link" aria-label="Direct link to What’s Supported" title="Direct link to What’s Supported" translate="no">​</a></h2>
<p>The new <code>gitea-actions</code> provider integrates with Gitea’s API and runner environment:</p>
<ul>
<li class=""><strong>Commit statuses:</strong> Report CI results against the checked-out commit.</li>
<li class=""><strong>Pull request comments:</strong> Publish plan results and update an existing Atmos comment
instead of adding a new comment on every run. Atmos only updates comments owned by
the authenticated account.</li>
<li class=""><strong>Affected-component detection:</strong> Resolve a pull request’s base SHA from its event
payload when the checkout matches the PR head. Push runs use the event’s <code>before</code> SHA.</li>
<li class=""><strong>Runner integration:</strong> Write job outputs and environment files, group logs, and write
summaries when the runner supplies a summary file. Summary display depends on the runner.</li>
</ul>
<p>Gitea runners can also expose GitHub-compatible environment variables. Atmos checks
<code>GITEA_ACTIONS=true</code> to select the Gitea provider, even when <code>GITHUB_ACTIONS=true</code> is present.
It uses Gitea’s API for reporting.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="enable-it-in-your-workflow">Enable It in Your Workflow<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/gitea-actions-ci-provider#enable-it-in-your-workflow" class="hash-link" aria-label="Direct link to Enable It in Your Workflow" title="Direct link to Enable It in Your Workflow" translate="no">​</a></h2>
<p>Enable native CI in <code>atmos.yaml</code>:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token key atrule">ci</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">enabled</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token boolean important" style="color:rgb(255, 88, 116)">true</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">checks</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">enabled</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token boolean important" style="color:rgb(255, 88, 116)">true</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">comments</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">enabled</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token boolean important" style="color:rgb(255, 88, 116)">true</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">behavior</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> upsert</span></span><br></div></code></pre></div></div>
<p>Create a Gitea token with repository status and issue/PR comment access. For a scoped
personal access token, use <code>write:repository</code>, <code>write:issue</code>, and <code>read:user</code>. Store it as
an Actions secret named <code>ATMOS_CI_GITEA_TOKEN</code>.</p>
<p>Once your Gitea job has checked out the repository and installed Atmos and Terraform,
add a plan step to its workflow under <code>.gitea/workflows/</code>:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> Plan infrastructure</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">env</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">ATMOS_CI_GITEA_TOKEN</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> $</span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> secrets.ATMOS_CI_GITEA_TOKEN </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">run</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> atmos terraform plan vpc </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">s dev</span></span><br></div></code></pre></div></div>
<p>Replace <code>vpc</code> and <code>dev</code> with your component and stack. No provider selection is needed.
Atmos derives the API endpoint from the runner; <code>ATMOS_CI_GITEA_API_URL</code> can override it.
HTTPS is required by default. The local emulator can explicitly opt into HTTP with
<code>ATMOS_CI_GITEA_ALLOW_INSECURE=true</code>.</p>
<p>For pull request workflows, check out the event’s <strong>head SHA</strong>, rather than a moving
branch. Checking out that exact revision also gives affected-component detection
a known head and base to compare.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="plan-on-pr-provision-after-merge">Plan on PR, Provision After Merge<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/gitea-actions-ci-provider#plan-on-pr-provision-after-merge" class="hash-link" aria-label="Direct link to Plan on PR, Provision After Merge" title="Direct link to Plan on PR, Provision After Merge" translate="no">​</a></h2>
<p>Use pull request jobs to validate and plan infrastructure changes. After merge, check
out the push event’s commit and create a fresh plan before applying it. The Gitea provider
does not yet resolve merged-PR plan provenance, so it cannot establish that a saved PR
plan is the reviewed plan for the merged commit.</p>
<p>Gitea jobs do not automatically use GitHub artifact storage. Configure a shared
<a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/ci/planfile-storage">planfile store</a> if plans need to survive between jobs; otherwise,
Atmos uses local storage. Remote Actions cache, GitHub Checks annotations, and commit
comments are not supported by this provider.</p>
<p>See the <a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/integrations/gitea-actions">Gitea Actions CI documentation</a> for provider configuration,
credentials, and capability details.</p>]]></content:encoded>
            <category>Feature</category>
            <category>DX</category>
        </item>
        <item>
            <title><![CDATA[Open a Browser from Automation Scripts]]></title>
            <link>https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/starlark-browser-open</link>
            <guid>https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/starlark-browser-open</guid>
            <pubDate>Mon, 09 Nov 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[A custom command that starts a local dashboard usually ends by opening it. Doing that portably has meant]]></description>
            <content:encoded><![CDATA[<p>A custom command that starts a local dashboard usually ends by opening it. Doing that portably has meant
detecting the operating system and shelling out to <code>open</code>, <code>xdg-open</code>, or <code>start</code>, each with its own quoting
rules and failure modes. Atmos automation scripts can now call
<a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/functions/automation/browser.open"><code>browser.open</code></a> to open a URL in the default browser on any platform.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/starlark-browser-open#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>Opening a URL is one of the most common last steps in developer tooling: a local portal, a docs preview, a
login page. Scripts had no built-in way to do it, so each command carried its own operating-system check and
passed the URL through a shell, where a stray character could change what was run.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/starlark-browser-open#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>The new <code>browser.open(url)</code> function uses the same cross-platform browser launcher Atmos already uses
elsewhere. It accepts only absolute HTTP or HTTPS URLs without embedded credentials, so local file paths,
<code>javascript:</code> URLs, and argument-like strings are rejected before anything launches. Launch failures fail the
script with a clear error, and dry runs never open a browser.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/starlark-browser-open#how-to-use-it" class="hash-link" aria-label="Direct link to How to Use It" title="Direct link to How to Use It" translate="no">​</a></h2>
<p>Add it to any <a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/steps/type/script">script step</a> or standalone script:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token key atrule">commands</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> portal</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">commands</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> open</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">description</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> Open the local dashboard</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">steps</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">          </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> </span><span class="token key atrule">type</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> script</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">            </span><span class="token key atrule">interpreter</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> starlark</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">            </span><span class="token key atrule">script</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">|</span><span class="token scalar string" style="color:rgb(173, 219, 103)"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token scalar string" style="color:rgb(173, 219, 103)">              browser.open("http://localhost:3000")</span></span><br></div></code></pre></div></div>
<p>Then run <code>atmos portal open</code>. The function is also available inside helpers loaded with
<a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/functions/automation/module.load"><code>module.load</code></a>.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/starlark-browser-open#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>Try it in your own custom commands and let us know what else your scripts need on
<a href="https://github.com/cloudposse/atmos/issues" target="_blank" rel="noopener noreferrer" class="">GitHub</a> or in the
<a href="https://cloudposse.com/slack" target="_blank" rel="noopener noreferrer" class="">Cloud Posse community Slack</a>.</p>]]></content:encoded>
            <category>Feature</category>
            <category>DX</category>
        </item>
        <item>
            <title><![CDATA[Template Engine Upgrade Drops the End-of-Life AWS SDK from Atmos]]></title>
            <link>https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/gomplate-v5</link>
            <guid>https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/gomplate-v5</guid>
            <pubDate>Fri, 06 Nov 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Most security findings are fixed with a patch or minor release of the affected dependency. Some]]></description>
            <content:encoded><![CDATA[<p>Most security findings are fixed with a patch or minor release of the affected dependency. Some
need a major version upgrade instead: when a dependency's major release line stops being
maintained, its CVEs stay open forever, and every project that pulls it in inherits them. That is
where Atmos was: the template engine it embeds, Gomplate, had moved on from the release line Atmos
used, and that line depended on the AWS SDK for Go v1, which has reached end of support and carries
CVEs no v1 release will ever fix. Atmos never executed the affected code, but no patch or minor
release could clear the findings. The CVEs forced our hand: the template engine now runs on
Gomplate v5, two major versions ahead, and the end-of-life SDK is gone from the Atmos build
entirely.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/gomplate-v5#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>Atmos uses Go templates in many places: stack manifests, vendor manifests, scaffolding,
<code>atmos docs generate</code>, Helm and Kubernetes component templates, and generated backend and varfile
paths. Gomplate supplies most of the template functions and all of the datasources.</p>
<p>Atmos releases used Gomplate v3. Gomplate v3 and v4 are no longer maintained, and both use the
AWS SDK for Go v1. AWS no longer supports that SDK, so its vulnerabilities (GO-2022-0635 and
GO-2022-0646) will never get a fix.</p>
<p>Dependency scanners and OpenSSF Scorecard report a vulnerable library even when your code never
calls it. So every Atmos release showed these findings. The only supported fix was Gomplate v5.
Atmos goes straight from v3 to v5, so this one upgrade brings the breaking changes of
v3 → v4 → v5 together.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/gomplate-v5#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>Atmos now embeds Gomplate v5, which is built on the AWS SDK for Go v2. Upgrading was not optional,
but breaking your stacks along with it would not have been acceptable either. Despite the sheer
number of breaking changes across Gomplate v3 → v4 → v5, we went through them one by one and kept
backward compatibility everywhere it made sense to: we built a compatibility test suite that runs
the same templates through the previous release and this one and compares the results, and added a
shim for every removed function we could restore faithfully. Most stack templates keep working
unchanged, and Sprig functions are still layered on top by default. Each shim logs a warning naming
the replacement the first time a stack manifest calls a removed function, so you can migrate on
your own schedule. A handful of datasource behaviors changed in
ways Atmos cannot paper over with a shim — <a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/gomplate-v5#what-to-check-in-your-stacks" class="">what to check in your stacks</a>
below covers each one. What changed unconditionally is what ships inside the binary: the AWS SDK for
Go v1 is no longer present in any form.</p>
<p>One HashiCorp Vault authentication library still pulled the old SDK in its latest tagged release,
even though its development branch had already been ported to v2. Atmos pins that library to the
ported development revision until HashiCorp tags a release. That pin is temporary. Dependabot will
propose the bump automatically as soon as a tagged release exists, and nothing about how you use
Vault datasources changes in the meantime.</p>
<p>The same upgrade moved the Go cryptography library to a release that closes two SSH-related
denial-of-service advisories (GO-2026-6354 and GO-2026-6355). This is preventative hygiene, not a
response to an exploited issue, but it is one more finding that will no longer appear on a scan of
Atmos.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="what-to-check-in-your-stacks">What to Check in Your Stacks<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/gomplate-v5#what-to-check-in-your-stacks" class="hash-link" aria-label="Direct link to What to Check in Your Stacks" title="Direct link to What to Check in Your Stacks" translate="no">​</a></h2>
<p>Gomplate v5 removed functions it had deprecated in v3 and changed some datasource behavior.
Atmos keeps the removed names working through compatibility shims. Each shim logs a warning that
names its replacement. A compatibility test suite runs the same templates through a v3 build and
this release and compares the results; the sections below list the differences it found. The
shims will be removed in a future major release, so replace the old names now. The
<a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/templates">templates configuration reference</a> and the
<a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/templates/datasources">datasources reference</a> carry the same list.</p>
<h3 class="anchor anchorTargetStickyNavbar_cA1_" id="renamed-functions">Renamed functions<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/gomplate-v5#renamed-functions" class="hash-link" aria-label="Direct link to Renamed functions" title="Direct link to Renamed functions" translate="no">​</a></h3>
<p>Deprecated function names were removed. Replace them with their namespaced equivalents:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Before</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain"></span><span class="token key atrule">enabled</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'{{ conv.Bool .vars.flag }}'</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain"></span><span class="token key atrule">names</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'{{ conv.Slice "a" "b" }}'</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain"></span><span class="token key atrule">cfg</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'{{ conv.Dict "k" "v" }}'</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain"></span><span class="token key atrule">has</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'{{ conv.Has .vars "key" }}'</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain"></span><span class="token key atrule">sorted</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'{{ strings.Sort .vars.list }}'</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain"></span><span class="token key atrule">ip</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'{{ net.ParseIP .vars.addr }}'</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain"></span><span class="token key atrule">cidr</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'{{ net.ParseIPPrefix .vars.cidr }}'</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain" style="display:inline-block"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># After</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain"></span><span class="token key atrule">enabled</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'{{ conv.ToBool .vars.flag }}'</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain"></span><span class="token key atrule">names</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'{{ coll.Slice "a" "b" }}'</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain"></span><span class="token key atrule">cfg</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'{{ coll.Dict "k" "v" }}'</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain"></span><span class="token key atrule">has</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'{{ coll.Has .vars "key" }}'</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain"></span><span class="token key atrule">sorted</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'{{ coll.Sort .vars.list }}'</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain"></span><span class="token key atrule">ip</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'{{ net.ParseAddr .vars.addr }}'</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain"></span><span class="token key atrule">cidr</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'{{ net.ParsePrefix .vars.cidr }}'</span></span><br></div></code></pre></div></div>
<p>The old <code>net</code> functions still return their v3 types (<code>netaddr.IP</code>, <code>netaddr.IPPrefix</code>, and
<code>netaddr.IPRange</code>), so method calls such as <code>.Contains</code> and <code>.Prior</code> keep working. The
replacements return <code>net/netip</code> types, which have different methods.</p>
<p>The unqualified aliases <code>slice</code>, <code>contains</code>, <code>hasPrefix</code>, <code>hasSuffix</code>, <code>split</code>, <code>splitN</code>, and
<code>trim</code> are no longer registered by Gomplate, but your templates keep working with no action needed:</p>
<ul>
<li class=""><code>slice</code>, <code>contains</code>, <code>hasPrefix</code>, <code>hasSuffix</code>, <code>split</code>, and <code>trim</code> resolve to Sprig, as they did
before, because Atmos layered Sprig over Gomplate's aliases. If you have disabled Sprig
(<code>templates.settings.sprig.enabled</code>), an Atmos shim restores Gomplate's versions. For <code>slice</code>,
that is Gomplate's list builder (<code>slice "a" "b"</code>), not Go's builtin.</li>
<li class=""><code>splitN</code> has no Sprig equivalent, so a shim always provides it.</li>
</ul>
<p>Replace shimmed names with their <code>strings.*</code> or <code>coll.*</code> forms when you get the chance, and check
the argument order as you go. With Sprig disabled, the shims keep Gomplate v3's order, with the
input first, while the <code>strings.*</code> functions take the input last so they work in pipelines.
<code>contains "alphabet" "pha"</code> becomes <code>strings.Contains "pha" "alphabet"</code>, and
<code>splitN "a,b,c" "," 2</code> becomes <code>strings.SplitN "," 2 "a,b,c"</code>. <code>slice</code> becomes <code>coll.Slice</code> with
the same arguments.</p>
<h3 class="anchor anchorTargetStickyNavbar_cA1_" id="conversions-and-regular-expressions-now-fail-loudly">Conversions and regular expressions now fail loudly<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/gomplate-v5#conversions-and-regular-expressions-now-fail-loudly" class="hash-link" aria-label="Direct link to Conversions and regular expressions now fail loudly" title="Direct link to Conversions and regular expressions now fail loudly" translate="no">​</a></h3>
<p>Conversion functions such as <code>conv.ToInt64</code>, <code>conv.ToFloat64</code>, and <code>conv.Atoi</code> used to return <code>0</code>
when handed something they could not convert. They now return an error, which surfaces as a
template processing failure; Atmos does not paper over this one, since silently returning <code>0</code> for
bad input is exactly the kind of behavior worth losing. The error message spells out the fix. If a
stack relied on the silent zero, check that the input is a number before converting it:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A"><div class="token-line" style="color:#d6deeb"><span class="token key atrule">retries</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'{{ $r := conv.ToString (index .vars "retries") }}{{ if regexp.Match "^-?[0-9]+$" $r }}{{ conv.ToInt64 $r }}{{ else }}0{{ end }}'</span><br></div></code></pre></div></div>
<p>An empty or non-numeric value renders <code>0</code>, and a whole number converts as before. The example reads
the key with <code>index</code>, which returns nothing for a missing key, so a missing <code>retries</code> also renders
<code>0</code>, even where Atmos treats missing values as errors (for example, in an import rendered with
<code>context</code>). Writing <code>.vars.retries</code> instead would fail on a missing key there before the check runs.</p>
<p>Similarly, the <code>regexp.*</code> functions return an error for an invalid pattern instead of panicking.
The failure is the same as before from your point of view, but the message now names the template
and the pattern.</p>
<h3 class="anchor anchorTargetStickyNavbar_cA1_" id="datasource-subpaths-are-relative-urls">Datasource subpaths are relative URLs<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/gomplate-v5#datasource-subpaths-are-relative-urls" class="hash-link" aria-label="Direct link to Datasource subpaths are relative URLs" title="Direct link to Datasource subpaths are relative URLs" translate="no">​</a></h3>
<p>A second argument to <code>datasource</code> is resolved as a relative URL against the datasource's <code>url</code>.
Directory datasources must end with a trailing <code>/</code>, and a subpath that begins with <code>/</code> replaces
the base path rather than appending to it. Atmos warns when it sees a datasource used this way
without a trailing slash on its URL, but it cannot know whether you meant the old or the new
resolution, so the warning is a prompt to check the stack, not an automatic fix:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token key atrule">settings</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">templates</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">settings</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">gomplate</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">datasources</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">          </span><span class="token key atrule">configs</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">            </span><span class="token key atrule">url</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"file:///configs/"</span><span class="token plain">   </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># trailing slash marks a directory</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain" style="display:inline-block"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain"></span><span class="token key atrule">components</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">terraform</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">app</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">vars</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'{{ (datasource "configs" "app.yaml").name }}'</span><span class="token plain">   </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># reads /configs/app.yaml</span></span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_cA1_" id="aws-parameter-store-values-are-returned-directly">AWS Parameter Store values are returned directly<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/gomplate-v5#aws-parameter-store-values-are-returned-directly" class="hash-link" aria-label="Direct link to AWS Parameter Store values are returned directly" title="Direct link to AWS Parameter Store values are returned directly" translate="no">​</a></h3>
<p>An <code>aws+smp://</code> datasource returns the parameter's value itself rather than an object with a
<code>.Value</code> field. Drop the field access, and if the parameter holds a JSON document, tell the
datasource to parse it with the <code>type</code> query parameter. Atmos recognizes a configured <code>aws+smp://</code>
datasource read with <code>.Value</code> still attached and warns about it, without guessing at what the
parameter actually contains:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token key atrule">settings</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">templates</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">settings</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">gomplate</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">datasources</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">          </span><span class="token key atrule">database</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">            </span><span class="token key atrule">url</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"aws+smp:///myapp/database/config?type=application/json"</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain" style="display:inline-block"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain"></span><span class="token key atrule">components</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">terraform</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">app</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">vars</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Before: '{{ (datasource "database").Value.host }}'</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">db_host</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'{{ (datasource "database").host }}'</span></span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_cA1_" id="smaller-datasource-changes">Smaller datasource changes<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/gomplate-v5#smaller-datasource-changes" class="hash-link" aria-label="Direct link to Smaller datasource changes" title="Direct link to Smaller datasource changes" translate="no">​</a></h3>
<p>Consul directory listings (a <code>consul://</code> URL ending in <code>/</code>) return a list of key names instead of
a map. BoltDB datasources were removed upstream and are no longer available.</p>
<p>S3 datasources reject an object whose checksum does not match, instead of returning its content.</p>
<p>In <code>env://NAME</code>, <code>NAME</code> is the URL host, so older releases read no variable and returned empty
data. That form now fails. Use <code>env:NAME</code> or <code>env:///NAME</code>.</p>
<p>Vault KV v2 datasources detect the mount and add the <code>/data/</code> API segment themselves. Remove
<code>/data/</code> from the URL (<code>.../kv/config</code>, not <code>.../kv/data/config</code>). The result is the secret's data
without the <code>data</code> and <code>metadata</code> wrapper, so read fields directly.</p>
<p>Consul, Vault, SSM, and S3 datasources send different requests to those services. For example,
Vault reads first check the mount type. The values your templates read do not change, but access
policies or proxies that allow only specific requests may need an update. HTTP datasources still
make one GET request per read, as before.</p>
<p>The datasource timeout in <code>atmos.yaml</code> (<code>templates.settings.gomplate.timeout</code>) now applies. Older
releases replaced it with the 5-second default whenever a stack manifest did not set its own
timeout, so a shorter global timeout was ignored. If a datasource takes longer than your global
timeout, raise the timeout in <code>atmos.yaml</code> or in that stack's settings.</p>
<h3 class="anchor anchorTargetStickyNavbar_cA1_" id="new-colljq-and-tmpl">New: <code>coll.JQ</code> and <code>tmpl</code><a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/gomplate-v5#new-colljq-and-tmpl" class="hash-link" aria-label="Direct link to new-colljq-and-tmpl" title="Direct link to new-colljq-and-tmpl" translate="no">​</a></h3>
<p><code>coll.JQ</code> runs a jq expression on a value, and the <code>tmpl</code> namespace (<code>tmpl.Inline</code>, <code>tmpl.Exec</code>)
renders nested templates. Neither was available in templates before this release.</p>
<h3 class="anchor anchorTargetStickyNavbar_cA1_" id="new-semantic-version-helpers">New: semantic version helpers<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/gomplate-v5#new-semantic-version-helpers" class="hash-link" aria-label="Direct link to New: semantic version helpers" title="Direct link to New: semantic version helpers" translate="no">​</a></h3>
<p>Gomplate v5 adds a <code>semver.*</code> namespace for parsing and comparing versions inside templates, for
example <code>{{ semver.CheckConstraint "&gt;= 1.5.0" .vars.version }}</code>. See the
<a href="https://docs.gomplate.ca/functions/semver/" target="_blank" rel="noopener noreferrer" class="">Gomplate semver reference</a> for the full list.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/gomplate-v5#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>We will fix forward. If a template that worked before this release fails after it, or quietly
renders a different value, and the cause is not on the list above,
<a href="https://github.com/cloudposse/atmos/issues" target="_blank" rel="noopener noreferrer" class="">open an issue</a> with the template expression and the
error. Where a gap can be closed with another compatibility shim, we will close it in a patch
release. The goal of this upgrade was to change what ships in the binary, not what your stacks can
do.</p>]]></content:encoded>
            <category>Security</category>
            <category>Breaking Change</category>
        </item>
        <item>
            <title><![CDATA[Restore Component Details in Bulk Terraform Plan Summaries]]></title>
            <link>https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/bulk-terraform-plan-summaries</link>
            <guid>https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/bulk-terraform-plan-summaries</guid>
            <pubDate>Fri, 30 Oct 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[When a pull request plans changes across many components, you need to see what will change, which plans]]></description>
            <content:encoded><![CDATA[<p>When a pull request plans changes across many components, you need to see what will change, which plans
failed, and which components need no action. Opening a separate log for every component makes that
review slow. Atmos brings back the normal component summaries beneath the bulk-plan overview so you can
review those results together in your CI summary or pull request comment.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/bulk-terraform-plan-summaries#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>Bulk plans used to write the normal summary for every component, including "No Changes" results. In
v1.221.0, we dropped those summaries as part of the refactoring work to support DAGs, where components
run concurrently in dependency order
(<a href="https://github.com/cloudposse/atmos/pull/2577" target="_blank" rel="noopener noreferrer" class="">#2577</a>). Bulk plans showed a single overview table
instead. That overview was helpful for seeing which components changed, but it only expanded failed and
changed components. To review any other plan in detail, you had to open the individual component logs.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/bulk-terraform-plan-summaries#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p><a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/terraform/plan#github-actions-ci-output">Bulk plans</a> keep the aggregate overview
and bring back the normal summary for each executed component, including no-change results, as long
as the summaries fit within the shared size limit. The summaries use the same <a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/ci/templates">CI templates</a>
and configured overrides as single-component plans, ordered by stack and component. Skipped components
remain in the overview with their reason.</p>
<p>Durations are easier to read, using seconds, minutes, and hours.</p>
<p>If the summary cannot fit all component details, Atmos includes a warning with guidance for narrowing
the plan's scope:</p>
<div class="github-alert github-alert-warning">
<p class="github-alert-title">Warning</p>
<p>Output exceeds the maximum summary size. Consider reducing scope using <code>--tags</code> or <code>--labels</code>.</p>
</div>
<p>You can inspect omitted details in component logs. For successful plans, you can also use saved plan
artifacts when available; failed plans do not produce plan artifacts.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/bulk-terraform-plan-summaries#how-to-use-it" class="hash-link" aria-label="Direct link to How to Use It" title="Direct link to How to Use It" translate="no">​</a></h2>
<p>Run a bulk plan in CI as usual; no new configuration is needed:</p>
<div class="language-shell codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-shell codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A"><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos terraform plan </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--all</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-s</span><span class="token plain"> dev </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--ci</span><span class="token plain"> --max-concurrency </span><span class="token number" style="color:rgb(247, 140, 108)">4</span><br></div></code></pre></div></div>
<p>The same summary behavior applies to bulk plans selected with <code>--components</code>, <code>--query</code>, or <code>--affected</code>.</p>
<p>For a report that exceeds the size budget, narrow the selected components using
<a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/terraform/plan#plan-components-by-tags-and-labels">tags or labels</a>:</p>
<div class="language-shell codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-shell codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A"><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos terraform plan </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--all</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-s</span><span class="token plain"> dev </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--ci</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--tags</span><span class="token plain"> production</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos terraform plan </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--all</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-s</span><span class="token plain"> dev </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--ci</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--labels</span><span class="token plain"> cost-center</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">platform</span><br></div></code></pre></div></div>
<p>Replace these selectors with tags or labels defined on your components.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/bulk-terraform-plan-summaries#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>See <a href="https://github.com/cloudposse/atmos/pull/3580" target="_blank" rel="noopener noreferrer" class="">PR #3580</a> for the change, or
<a href="https://github.com/cloudposse/atmos/issues/new/choose" target="_blank" rel="noopener noreferrer" class="">open an issue</a> if a bulk-plan summary is missing
information you need to review your infrastructure changes.</p>]]></content:encoded>
            <category>Bug Fix</category>
            <category>DX</category>
        </item>
        <item>
            <title><![CDATA[Inherited Components Now Use the Backend Key of Their Module]]></title>
            <link>https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/inherited-component-backend-keys</link>
            <guid>https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/inherited-component-backend-keys</guid>
            <pubDate>Fri, 30 Oct 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[A component that inherits metadata.component from a base should behave like one that sets it directly. Until now, parts of Atmos still treated it as a component named after the instance, which caused failed lookups and missed affected components. Fixing that also changes the backend key Atmos generates for these components, so existing projects may need one step when they upgrade.]]></description>
            <content:encoded><![CDATA[<p>A component that inherits <a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/stacks/inherit"><code>metadata.component</code></a> from a base should behave like one that sets it directly. Until now, parts of Atmos still treated it as a component named after the instance, which caused failed lookups and missed affected components. Fixing that also changes the backend key Atmos generates for these components, so existing projects may need one step when they upgrade.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/inherited-component-backend-keys#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>Take a concrete instance that gets its module from an abstract base:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token key atrule">components</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">terraform</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">k8s_nodes/lxd/defaults</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">metadata</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">type</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> abstract</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">component</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> lxd/talos</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">nodes</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">k8s_nodes</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">metadata</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">inherits</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">          </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> k8s_nodes/lxd/defaults</span></span><br></div></code></pre></div></div>
<p>Terraform ran in the <code>lxd/talos-nodes</code> directory, while <code>atmos describe component</code> reported <code>k8s_nodes</code> as the component and template lookups through <code>atmos.Component</code> failed. The instance was using one identity for execution and another for everything around it.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/inherited-component-backend-keys#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>The inherited value is now resolved before anything else consumes it, so the directory, descriptions, lookups, and affected detection all agree. The generated backend key follows the same value, matching a component that sets <code>metadata.component</code> itself:</p>
<table><thead><tr><th>Backend</th><th>Before</th><th>Now</th></tr></thead><tbody><tr><td>S3 <code>workspace_key_prefix</code></td><td><code>k8s_nodes</code></td><td><code>lxd-talos-nodes</code></td></tr><tr><td>GCS <code>prefix</code></td><td><code>k8s_nodes</code></td><td><code>lxd-talos-nodes</code></td></tr><tr><td>AzureRM <code>key</code></td><td><code>k8s_nodes.terraform.tfstate</code></td><td><code>lxd-talos-nodes.terraform.tfstate</code></td></tr></tbody></table>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="before-you-upgrade">Before You Upgrade<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/inherited-component-backend-keys#before-you-upgrade" class="hash-link" aria-label="Direct link to Before You Upgrade" title="Direct link to Before You Upgrade" translate="no">​</a></h2>
<p>This affects instances that inherit <code>metadata.component</code>, use a generated S3, GCS, or AzureRM backend, and don't set <code>metadata.name</code> or an explicit prefix or key. Their state remains at the old key, so Terraform starts from empty state at the new one:</p>
<div><div class="terminal"><div class="window-bar"><div class="window-controls" aria-hidden="true"><div class="control-dot close-dot"></div><div class="control-dot minimize-dot"></div><div class="control-dot maximize-dot"></div></div><div class="window-title">Terminal</div></div><div class="viewport"><div><div class="language-console codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-console codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A"><div class="token-line" style="color:#d6deeb"><span class="token plain">Plan: 1 to add, 0 to change, 0 to destroy.</span><br></div></code></pre></div></div></div></div></div></div>
<p>Applying that plan creates duplicate resources, and a later destroy removes only the duplicates. Review plans for these components after upgrading, and pause any auto-approved applies until you have handled them. <a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/edition">Edition pins</a> have no effect on this change.</p>
<p>To see the key for a component, run <a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/terraform/generate/backend"><code>atmos terraform generate backend</code></a> on the old and new versions and compare the output.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/inherited-component-backend-keys#how-to-use-it" class="hash-link" aria-label="Direct link to How to Use It" title="Direct link to How to Use It" translate="no">​</a></h2>
<p>Pick one of these for each affected instance.</p>
<p><strong>Keep the existing key.</strong> Give the instance a stable <a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/stacks/components/component-metadata#name"><code>metadata.name</code></a>, or set <code>workspace_key_prefix</code> (S3), <code>prefix</code> (GCS), or <code>key</code> (AzureRM) directly:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token key atrule">components</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">terraform</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">k8s_nodes</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">metadata</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> k8s_nodes</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">inherits</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">          </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> k8s_nodes/lxd/defaults</span></span><br></div></code></pre></div></div>
<p><strong>Adopt the new key.</strong> Before the next apply, copy the state of every workspace whose path changes, for example from <code>k8s_nodes/test-k8s_nodes/terraform.tfstate</code> to <code>lxd-talos-nodes/test-k8s_nodes/terraform.tfstate</code>. On S3 that means every named workspace, because the prefix doesn't apply to the <code>default</code> workspace. On GCS and AzureRM it includes <code>default</code> as well. The next plan in each workspace should report <code>No changes</code>.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/inherited-component-backend-keys#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>If this upgrade affects you in a way these steps don't cover, <a href="https://github.com/cloudposse/atmos/issues" target="_blank" rel="noopener noreferrer" class="">open an issue</a> or ask in <a href="https://cloudposse.com/slack" target="_blank" rel="noopener noreferrer" class="">Slack</a>.</p>]]></content:encoded>
            <category>Bug Fix</category>
            <category>Breaking Change</category>
        </item>
        <item>
            <title><![CDATA[Identity-Authenticated Vault Secret Fields]]></title>
            <link>https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/identity-authenticated-vault-secret-fields</link>
            <guid>https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/identity-authenticated-vault-secret-fields</guid>
            <pubDate>Wed, 28 Oct 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Structured secrets rarely agree on a single field name, and an ambient Vault token can silently cross an authentication boundary. That combination forces teams to reshape secret documents or wrap Atmos just to pass one short-lived credential into another identity.]]></description>
            <content:encoded><![CDATA[<p>Structured secrets rarely agree on a single field name, and an ambient Vault token can silently cross an authentication boundary. That combination forces teams to reshape secret documents or wrap Atmos just to pass one short-lived credential into another identity.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/identity-authenticated-vault-secret-fields#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>The <code>auth-secrets</code> plugin could read a store's conventional scalar value, but it could not select an arbitrary field from a Vault or OpenBao KV document. Vault-backed stores also could not consume credentials produced by a native Atmos identity, leaving ambient or static tokens outside the identity chain.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/identity-authenticated-vault-secret-fields#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>Secret references now use <code>path</code> for the document location and can name an exact top-level <code>field</code>. Identities map those credentials into their environment with explicit <code>spec.env</code> templates. Vault and OpenBao stores can also bind to a native Atmos identity that emits <code>environment/v1</code> credentials containing <code>VAULT_TOKEN</code>.</p>
<p>When an identity is configured, its token is exclusive: Atmos does not fall back to <code>options.token</code> or an ambient <code>VAULT_TOKEN</code> if authentication fails. The resolved credentials remain isolated from the Atmos process environment.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/identity-authenticated-vault-secret-fields#how-to-use-it" class="hash-link" aria-label="Direct link to How to Use It" title="Direct link to How to Use It" translate="no">​</a></h2>
<p>Configure a Vault or OpenBao secret store with an <code>identity</code>, then select the source field in an <a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/plugins#official-secret-store-authentication"><code>auth-secrets</code> credential reference</a>:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token key atrule">stores</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">platform</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">type</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> hashicorp</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">vault</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">secret</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token boolean important" style="color:rgb(255, 88, 116)">true</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">identity</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> openbao/session</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">options</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">address</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> https</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain">//openbao.example.com</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">mount</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> secret</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain" style="display:inline-block"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain"></span><span class="token key atrule">auth</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">providers</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">deployment-secrets</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">kind</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> secrets/store</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">spec</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">credentials</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">          </span><span class="token key atrule">token</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">            </span><span class="token key atrule">store</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> platform</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">            </span><span class="token key atrule">path</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> platform/deploy/example</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">            </span><span class="token key atrule">field</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> access_token</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">identities</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">deployment</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">kind</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> secrets/env</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">via</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">provider</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> deployment</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">secrets</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">spec</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">env</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">          </span><span class="token key atrule">SERVICE_TOKEN</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'{{ .credentials.token }}'</span></span><br></div></code></pre></div></div>
<p>The store's <code>openbao/session</code> identity must emit <code>VAULT_TOKEN</code>; the referenced document may use any top-level field name and may still contain a separate legacy <code>value</code> field. The <code>deployment</code> identity maps the selected credential into <code>SERVICE_TOKEN</code> for its child process. For hyphenated credential names, use a template such as <code>{{ index .credentials "api-access-key" }}</code>. Missing credential references fail authentication; plain strings stay literal.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/identity-authenticated-vault-secret-fields#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>Try the native identity chain with a Vault or OpenBao KV v2 store and share feedback on field selection, token lifecycle, and error messages in the Atmos issue tracker.</p>]]></content:encoded>
            <category>Feature</category>
            <category>Security</category>
        </item>
        <item>
            <title><![CDATA[Conditional Retries for Component Error Events]]></title>
            <link>https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/component-error-retry-policies</link>
            <guid>https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/component-error-retry-policies</guid>
            <pubDate>Mon, 26 Oct 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Transient failures need different recovery rules depending on which operation failed. A network timeout during initialization should not restart an entire deployment, and a failed polling request should not repeat a completed mutation. Atmos retry policies let you select the operation, match its failure, and give that invocation a bounded retry budget.]]></description>
            <content:encoded><![CDATA[<p>Transient failures need different recovery rules depending on which operation failed. A network timeout during initialization should not restart an entire deployment, and a failed polling request should not repeat a completed mutation. Atmos <a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/policies/retries">retry policies</a> let you select the operation, match its failure, and give that invocation a bounded retry budget.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/component-error-retry-policies#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>The existing <a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/stacks/components/terraform/retry">component retry configuration</a> matches subprocess output for Terraform, Helmfile, Packer, and Ansible. Teams also need conditions on structured SDK errors and consistent retry controls for native Helm, Kubernetes, CloudFormation, containers, and emulators.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/component-error-retry-policies#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>Policies can now select explicit error events such as <code>terraform.init.error</code> and <code>kubernetes.apply.error</code>. A policy accepts one event, a list, or a component wildcard such as <code>terraform.*.error</code>. The <code>rule</code> selects qualifying failures, and <code>with</code> configures the retry budget and backoff.</p>
<p>An initialization failure during a plan emits <code>terraform.init.error</code>. Terraform output lookups also have separate initialization, workspace, and output events. SDK integrations retry the failed call while preserving earlier successful steps.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/component-error-retry-policies#how-to-use-it" class="hash-link" aria-label="Direct link to How to Use It" title="Direct link to How to Use It" translate="no">​</a></h2>
<p>Save this document in your <a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/policies/configuration">policy directory</a>:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockTitle_JJ7b">policy.d/retries.yaml</div><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token key atrule">apiVersion</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> atmos/v1</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain"></span><span class="token key atrule">kind</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> Policy</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain"></span><span class="token key atrule">metadata</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> retries</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain"></span><span class="token key atrule">spec</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">policies</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">retry-terraform-network-errors</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">description</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">&gt;</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        Retry initialization</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> planning</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> and output retrieval when</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        Terraform encounters transient network failures.</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">on</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> terraform.init.error</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> terraform.plan.error</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> terraform.output.error</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">action</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> retry</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">rule</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> input.output.matches('(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">?</span><span class="token plain">i)connection reset</span><span class="token punctuation" style="color:rgb(199, 146, 234)">|</span><span class="token plain">TLS handshake timeout')</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">with</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">max_attempts</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">3</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">initial_delay</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> 2s</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain" style="display:inline-block"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">retry-kubernetes-unavailable</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">description</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> Retry apply calls when the Kubernetes API is temporarily unavailable.</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">on</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> kubernetes.apply.error</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">action</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> retry</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">rule</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> input.error.message.matches('(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">?</span><span class="token plain">i)service unavailable')</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">with</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">max_attempts</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">3</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">initial_delay</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> 2s</span></span><br></div></code></pre></div></div>
<p>The maximum attempt count includes the first invocation. Each failure receives fresh output and error facts. A selected retry policy supplies one budget; it does not multiply the existing component retry budget. See <a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/policies/retries#retry-settings-and-precedence">retry settings and precedence</a> for ordering, denial handling, and fallback behavior.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/component-error-retry-policies#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>Read the <a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/policies/retries#events">event and failure-input reference</a> to adapt these policies to your components, and share feedback in <a href="https://github.com/cloudposse/atmos/discussions" target="_blank" rel="noopener noreferrer" class="">GitHub Discussions</a>.</p>]]></content:encoded>
            <category>Feature</category>
        </item>
        <item>
            <title><![CDATA[Define Resource Tags Once and Inherit Them Across Stacks]]></title>
            <link>https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/tagging-examples</link>
            <guid>https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/tagging-examples</guid>
            <pubDate>Sun, 25 Oct 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Copying the same resource tags into every component makes ownership changes tedious and lets environments drift.]]></description>
            <content:encoded><![CDATA[<p>Copying the same resource tags into every component makes ownership changes tedious and lets environments drift.
Two focused examples now show how to define shared tags once and inherit them across stacks: one uses AWS provider
default tags, and the other passes tags to Null Label. Each includes a terminal recording and commands you can run locally.</p>
<!-- -->
<div><div class="window_X9dN"><div class="titlebar_DN7h"><span class="dots_R2sg" aria-hidden="true"><i></i><i></i><i></i></span><span class="title_Dael">Inherit AWS default tags</span></div><pre class="screen__b5c noPreWrap_ImkX screenLoading_abuO"><span> </span></pre><div class="controls_eyLV" data-cast-controls="true"><button type="button" class="playButton_kD9r" aria-label="Pause cast"><svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 24 24" aria-hidden="true" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M6 5H8V19H6V5ZM16 5H18V19H16V5Z"></path></svg></button><input aria-label="Cast position" type="range" min="0" max="0" step="0.01" value="0"><span class="time_lEbH">00:00.0<!-- --> / <!-- -->00:00.0</span></div></div><div class="castActions_M13G"><div class="container_zGFV"><div class="group_ncGU" role="group" aria-label="Share this demo"><button type="button" class="primary_hpkh" title="Copy a link to this demo" aria-live="polite"><svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" class="icon_P_nE" aria-hidden="true" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><circle cx="18" cy="5" r="3"></circle><circle cx="6" cy="12" r="3"></circle><circle cx="18" cy="19" r="3"></circle><line x1="8.59" y1="13.51" x2="15.42" y2="17.49"></line><line x1="15.41" y1="6.51" x2="8.59" y2="10.49"></line></svg><span>Share</span></button><button type="button" class="caret_pPxC" aria-expanded="false" aria-label="More share options" title="More share options"><svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" class="icon_P_nE" aria-hidden="true" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><polyline points="6 9 12 15 18 9"></polyline></svg></button></div></div><div class="container_EXko"><button type="button" class="trigger_WxG7" aria-expanded="false" aria-label="Download cast"><svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" class="icon_LbC3" aria-hidden="true" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline points="7 10 12 15 17 10"></polyline><line x1="12" y1="15" x2="12" y2="3"></line></svg><span>Download</span><svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" class="icon_LbC3" aria-hidden="true" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><polyline points="6 9 12 15 18 9"></polyline></svg></button></div></div></div>
<p><a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/examples/tagging-default-tags">View the AWS default tags example</a></p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/tagging-examples#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>A tagging example should make it easy to see where shared tags are defined and what each environment receives.
Adding an organizational hierarchy, Git metadata, CI conditions, and naming rules at the same time makes that
basic behavior harder to follow.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/tagging-examples#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>Each example has one shared component configuration and two stacks, <code>dev</code> and <code>prod</code>:</p>
<ul>
<li class=""><strong>AWS provider default tags:</strong> both stacks inherit <code>managed-by</code> and <code>owner</code>, then add their own <code>environment</code> tag.
Atmos <a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/stacks/providers">generates the provider configuration</a>, so the S3 resource needs no <code>tags</code> argument.</li>
<li class=""><strong>Null Label:</strong> both stacks inherit the same tags and supply a stage to the naming module. The module combines the
supplied tags with generated <code>Name</code>, <code>Namespace</code>, and <code>Stage</code> tags. A built-in <code>terraform_data</code> resource shows the
result without creating cloud resources.</li>
</ul>
<p>The <a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/tutorials/tagging-strategy">tagging strategy tutorial</a> builds on these basics with an organizational hierarchy,
source-control tag tradeoffs, provider limitations, and AWS enforcement guidance. The
<a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/tutorials/share-terraform-code-across-components">shared Terraform code tutorial</a> explains how to distribute common
files such as <code>context.tf</code> across components.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/tagging-examples#how-to-use-it" class="hash-link" aria-label="Direct link to How to Use It" title="Direct link to How to Use It" translate="no">​</a></h2>
<p>The AWS example describes the merged tags without connecting to AWS:</p>
<div class="example_jMgJ"><div class="theme-tabs-container tabs-container tabList_oBn1"><ul role="tablist" aria-orientation="horizontal" class="tabs"><li role="tab" tabindex="-1" aria-selected="false" class="tabs__item tabItem_A3p1">Install Atmos</li><li role="tab" tabindex="0" aria-selected="true" class="tabs__item tabItem_A3p1 tabs__item--active">Try the example</li></ul><div class="margin-top--md"><div role="tabpanel" class="tabItem_gg6W" hidden=""><div class="install-widget install-widget--docs"><div class="install-widget__content"><div class="install-widget__select-wrapper"><span class="install-widget__label">Quick Install</span><select class="install-widget__select" aria-label="Installation method"><option value="0" selected="">Quick Install</option><option value="1">macOS</option><option value="2">Windows</option><option value="3">Docker</option></select><svg class="install-widget__chevron" width="12" height="8" viewBox="0 0 12 8" fill="none"><path d="M1 1.5L6 6.5L11 1.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path></svg></div><div class="install-widget__command"><code class="install-widget__code"><span class="install-widget__command-curl">curl -fsSL</span> <span class="install-widget__command-url">https://atmos.tools/install.sh</span> | <span class="install-widget__command-bash">bash</span></code></div><button class="install-widget__copy" type="button" aria-label="Copy installation command" title="Copy to clipboard"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="5" y="5" width="9" height="9" rx="1" stroke="currentColor" stroke-width="1.5"></rect><path d="M3 11V3C3 2.44772 3.44772 2 4 2H11" stroke="currentColor" stroke-width="1.5"></path></svg></button></div></div><div class="links_ZD8T"><a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/install">Installation guide →</a><a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/examples/tagging-default-tags">Explore the example →</a></div></div><div role="tabpanel" class="tabItem_gg6W"><p>Copy the example into a new directory and make it your own:</p><div class="language-shell codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-shell codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A"><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos init examples/tagging-default-tags</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token builtin class-name" style="color:rgb(255, 203, 139)">cd</span><span class="token plain"> tagging-default-tags</span><br></div></code></pre></div></div><div class="language-shell codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-shell codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A"><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos describe component app </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-s</span><span class="token plain"> dev </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--query</span><span class="token plain"> .providers.aws.default_tags.tags</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos describe component app </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-s</span><span class="token plain"> prod </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--query</span><span class="token plain"> .providers.aws.default_tags.tags</span><br></div></code></pre></div></div><div class="links_ZD8T"><a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/examples/tagging-default-tags">Explore the example →</a><a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/init#examples-and-source-directories">Initialization and repository settings</a></div></div></div></div></div>
<p>The example contains a real S3 bucket component. Planning or applying requires AWS credentials; applying creates
a bucket. Provider default tags apply to supported resources, with exceptions such as Auto Scaling groups that
need resource-specific tagging configuration.</p>
<p>The Null Label example plans locally without cloud credentials. Its first plan downloads the module:</p>
<div><div class="window_X9dN"><div class="titlebar_DN7h"><span class="dots_R2sg" aria-hidden="true"><i></i><i></i><i></i></span><span class="title_Dael">Pass inherited tags to Null Label</span></div><pre class="screen__b5c noPreWrap_ImkX screenLoading_abuO"><span> </span></pre><div class="controls_eyLV" data-cast-controls="true"><button type="button" class="playButton_kD9r" aria-label="Pause cast"><svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 24 24" aria-hidden="true" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M6 5H8V19H6V5ZM16 5H18V19H16V5Z"></path></svg></button><input aria-label="Cast position" type="range" min="0" max="0" step="0.01" value="0"><span class="time_lEbH">00:00.0<!-- --> / <!-- -->00:00.0</span></div></div><div class="castActions_M13G"><div class="container_zGFV"><div class="group_ncGU" role="group" aria-label="Share this demo"><button type="button" class="primary_hpkh" title="Copy a link to this demo" aria-live="polite"><svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" class="icon_P_nE" aria-hidden="true" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><circle cx="18" cy="5" r="3"></circle><circle cx="6" cy="12" r="3"></circle><circle cx="18" cy="19" r="3"></circle><line x1="8.59" y1="13.51" x2="15.42" y2="17.49"></line><line x1="15.41" y1="6.51" x2="8.59" y2="10.49"></line></svg><span>Share</span></button><button type="button" class="caret_pPxC" aria-expanded="false" aria-label="More share options" title="More share options"><svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" class="icon_P_nE" aria-hidden="true" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><polyline points="6 9 12 15 18 9"></polyline></svg></button></div></div><div class="container_EXko"><button type="button" class="trigger_WxG7" aria-expanded="false" aria-label="Download cast"><svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" class="icon_LbC3" aria-hidden="true" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline points="7 10 12 15 17 10"></polyline><line x1="12" y1="15" x2="12" y2="3"></line></svg><span>Download</span><svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" class="icon_LbC3" aria-hidden="true" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><polyline points="6 9 12 15 18 9"></polyline></svg></button></div></div></div>
<p><a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/examples/tagging-null-label">View the Null Label example</a></p>
<div class="example_jMgJ"><div class="theme-tabs-container tabs-container tabList_oBn1"><ul role="tablist" aria-orientation="horizontal" class="tabs"><li role="tab" tabindex="-1" aria-selected="false" class="tabs__item tabItem_A3p1">Install Atmos</li><li role="tab" tabindex="0" aria-selected="true" class="tabs__item tabItem_A3p1 tabs__item--active">Try the example</li></ul><div class="margin-top--md"><div role="tabpanel" class="tabItem_gg6W" hidden=""><div class="install-widget install-widget--docs"><div class="install-widget__content"><div class="install-widget__select-wrapper"><span class="install-widget__label">Quick Install</span><select class="install-widget__select" aria-label="Installation method"><option value="0" selected="">Quick Install</option><option value="1">macOS</option><option value="2">Windows</option><option value="3">Docker</option></select><svg class="install-widget__chevron" width="12" height="8" viewBox="0 0 12 8" fill="none"><path d="M1 1.5L6 6.5L11 1.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path></svg></div><div class="install-widget__command"><code class="install-widget__code"><span class="install-widget__command-curl">curl -fsSL</span> <span class="install-widget__command-url">https://atmos.tools/install.sh</span> | <span class="install-widget__command-bash">bash</span></code></div><button class="install-widget__copy" type="button" aria-label="Copy installation command" title="Copy to clipboard"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="5" y="5" width="9" height="9" rx="1" stroke="currentColor" stroke-width="1.5"></rect><path d="M3 11V3C3 2.44772 3.44772 2 4 2H11" stroke="currentColor" stroke-width="1.5"></path></svg></button></div></div><div class="links_ZD8T"><a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/install">Installation guide →</a><a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/examples/tagging-null-label">Explore the example →</a></div></div><div role="tabpanel" class="tabItem_gg6W"><p>Copy the example into a new directory and make it your own:</p><div class="language-shell codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-shell codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A"><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos init examples/tagging-null-label</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token builtin class-name" style="color:rgb(255, 203, 139)">cd</span><span class="token plain"> tagging-null-label</span><br></div></code></pre></div></div><div class="language-shell codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-shell codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A"><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos describe component app </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-s</span><span class="token plain"> dev </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--query</span><span class="token plain"> .vars</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos terraform plan app </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-s</span><span class="token plain"> dev</span><br></div></code></pre></div></div><div class="links_ZD8T"><a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/examples/tagging-null-label">Explore the example →</a><a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/init#examples-and-source-directories">Initialization and repository settings</a></div></div></div></div></div>
<p>When applying the resulting map to cloud resources, account for the target provider's tag or label restrictions.
Null Label preserves supplied tags; it does not normalize them for each provider.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/tagging-examples#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>Share tagging patterns or suggest another focused example in
<a href="https://github.com/cloudposse/atmos/discussions" target="_blank" rel="noopener noreferrer" class="">GitHub Discussions</a>.</p>]]></content:encoded>
            <category>Documentation</category>
        </item>
        <item>
            <title><![CDATA[Inspect Terraform Backend Configuration]]></title>
            <link>https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/terraform-backend-inspection</link>
            <guid>https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/terraform-backend-inspection</guid>
            <pubDate>Sun, 25 Oct 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Backend settings can be inherited and overridden across a stack, making it hard to see which configuration each component receives. The Terraform backend inspection commands now show that merged configuration directly.]]></description>
            <content:encoded><![CDATA[<p>Backend settings can be inherited and overridden across a stack, making it hard to see which configuration each component receives. The <a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/terraform/terraform-backend">Terraform backend inspection commands</a> now show that merged configuration directly.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/terraform-backend-inspection#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>The documented <code>atmos terraform backend list</code> and <code>describe</code> commands were placeholders. They could not show a stack's configured backends or the settings inherited by a component.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/terraform-backend-inspection#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>Both commands now inspect merged backend configuration for any backend type. They do not authenticate, provision resources, run Terraform, or check whether remote storage exists. Templates and YAML functions remain unevaluated and appear as stored. Remote stack imports are rejected, and imports that require template evaluation cannot be resolved during inspection.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/terraform-backend-inspection#how-to-use-it" class="hash-link" aria-label="Direct link to How to Use It" title="Direct link to How to Use It" translate="no">​</a></h2>
<p>List the concrete components that have backend configuration in a stack:</p>
<div class="language-shell codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-shell codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A"><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos terraform backend list </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--stack</span><span class="token plain"> dev</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos terraform backend list </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--stack</span><span class="token plain"> dev </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--format</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">json</span><br></div></code></pre></div></div>
<p>The default table is sorted by component name. Abstract components and components without a backend are omitted. JSON and YAML formats return an array of objects with <code>stack</code>, <code>component</code>, <code>backend_type</code>, and <code>backend</code> fields.</p>
<p>Inspect one component:</p>
<div class="language-shell codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-shell codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A"><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos terraform backend describe vpc </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--stack</span><span class="token plain"> dev</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos terraform backend describe vpc </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--stack</span><span class="token plain"> dev </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--format</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">json</span><br></div></code></pre></div></div>
<p>The default output is YAML. JSON output returns a single object with the same fields as a list entry. Missing stacks or components produce an error.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/terraform-backend-inspection#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>See the <a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/terraform/terraform-backend">backend command reference</a> for all options. Report problems in <a href="https://github.com/cloudposse/atmos/issues" target="_blank" rel="noopener noreferrer" class="">Atmos issues</a>.</p>]]></content:encoded>
            <category>Feature</category>
        </item>
        <item>
            <title><![CDATA[Inspect Your Toolchain Aliases]]></title>
            <link>https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/toolchain-aliases</link>
            <guid>https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/toolchain-aliases</guid>
            <pubDate>Sun, 25 Oct 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Tool aliases can come from built-in defaults or your project's configuration, making it difficult to see which target a short name selects. The toolchain aliases command lists the effective mappings in one place.]]></description>
            <content:encoded><![CDATA[<p>Tool aliases can come from built-in defaults or your project's configuration, making it difficult to see which target a short name selects. The <a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/toolchain/aliases">toolchain aliases command</a> lists the effective mappings in one place.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/toolchain-aliases#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>The documented <code>atmos toolchain aliases</code> command was missing from the CLI. Aliases worked when installing or running tools, but checking their targets meant reading configuration files and accounting for built-in defaults yourself.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/toolchain-aliases#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>The command now lists built-in aliases together with aliases from the merged Atmos configuration. Configured aliases take precedence when names overlap. Output is sorted by alias name and shows each target as declared, without resolving it through a tool registry.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/toolchain-aliases#how-to-use-it" class="hash-link" aria-label="Direct link to How to Use It" title="Direct link to How to Use It" translate="no">​</a></h2>
<p>List aliases in a table:</p>
<div class="language-shell codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-shell codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A"><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos toolchain aliases</span><br></div></code></pre></div></div>
<p>Use structured output for scripts:</p>
<div class="language-shell codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-shell codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A"><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos toolchain aliases </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--format</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">json</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos toolchain aliases </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--format</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">yaml</span><br></div></code></pre></div></div>
<p>The command does not install tools or fetch tool registries. Configure mappings under <a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/toolchain/aliases"><code>toolchain.aliases</code></a> in <code>atmos.yaml</code>.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/toolchain-aliases#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>See the <a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/toolchain/aliases">command reference</a> for output options and examples. Report problems in <a href="https://github.com/cloudposse/atmos/issues" target="_blank" rel="noopener noreferrer" class="">Atmos issues</a>.</p>]]></content:encoded>
            <category>Feature</category>
        </item>
        <item>
            <title><![CDATA[Run YAML Exec Expressions Concurrently]]></title>
            <link>https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/parallel-yaml-exec</link>
            <guid>https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/parallel-yaml-exec</guid>
            <pubDate>Sat, 24 Oct 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Several independent configuration lookups can spend most of their time waiting on commands, with each]]></description>
            <content:encoded><![CDATA[<p>Several independent configuration lookups can spend most of their time waiting on commands, with each
lookup waiting for the previous one to finish. You can now set a
<a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/settings/functions/exec">concurrency limit</a> for ordinary
<a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/functions/yaml/exec"><code>!exec</code></a> expressions and let those commands overlap without restructuring your stack.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/parallel-yaml-exec#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>A document with several shell lookups evaluated them serially. Even when the commands were independent,
configuration loading took the sum of their runtimes. Parallelizing them required changing how values were
gathered rather than configuring the evaluation itself.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/parallel-yaml-exec#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>Set one concurrency limit in <code>atmos.yaml</code>. Atmos runs up to that many expressions at once and assigns every
result back to its original location. Serial execution remains the default.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/parallel-yaml-exec#how-to-use-it" class="hash-link" aria-label="Direct link to How to Use It" title="Direct link to How to Use It" translate="no">​</a></h2>
<p>Configure the limit:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token key atrule">settings</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">functions</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">exec</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">max_concurrency</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">4</span></span><br></div></code></pre></div></div>
<p>Keep your stack expressions as they are:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token key atrule">vars</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">network</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token tag" style="color:rgb(127, 219, 202)">!exec</span><span class="token plain"> ./lookup</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">network</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">cluster</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token tag" style="color:rgb(127, 219, 202)">!exec</span><span class="token plain"> ./lookup</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">cluster</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">registry</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token tag" style="color:rgb(127, 219, 202)">!exec</span><span class="token plain"> ./lookup</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">registry</span></span><br></div></code></pre></div></div>
<p>These three commands can overlap. Their completion order does not change which value belongs to which
variable, and JSON results retain their existing decoding behavior.</p>
<p>Use <code>1</code> for serial execution. Values below <code>1</code> are invalid. When enabling concurrency, you own dependencies
between shell commands, including shared files and external state; Atmos does not infer them.
Skipping <code>!exec</code> expressions still prevents their execution.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/parallel-yaml-exec#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>Read the <a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/settings/functions/exec">configuration reference</a> and
<a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/functions/yaml/exec">function reference</a>. Share your use cases in
<a href="https://github.com/cloudposse/atmos/discussions" target="_blank" rel="noopener noreferrer" class="">GitHub Discussions</a>.</p>]]></content:encoded>
            <category>Feature</category>
            <category>DX</category>
        </item>
        <item>
            <title><![CDATA[Retiring Prebuilt Downloads for 32-bit Linux and FreeBSD]]></title>
            <link>https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/release-platform-downloads</link>
            <guid>https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/release-platform-downloads</guid>
            <pubDate>Sat, 24 Oct 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Building and verifying rarely downloaded binaries makes everyone wait longer for Atmos releases. We're retiring prebuilt downloads for Linux 386, Linux 32-bit ARM, and FreeBSD on amd64 and arm64 to reduce that overhead. Users on those platforms should install Atmos with Go, which builds it locally.]]></description>
            <content:encoded><![CDATA[<p>Building and verifying rarely downloaded binaries makes everyone wait longer for Atmos releases. We're retiring prebuilt downloads for Linux 386, Linux 32-bit ARM, and FreeBSD on amd64 and arm64 to reduce that overhead. Users on those platforms should <a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/install#install-with-go">install Atmos with Go</a>, which builds it locally.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/release-platform-downloads#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>Each release builds binaries for multiple operating systems and architectures, then packages and verifies them. Our review of downloads across 12 stable releases published from July 26 through October 20, 2026 found that these four targets accounted for fewer than 0.05% of binary downloads among the current release targets. These are cumulative asset downloads, not a count of active users.</p>
<p>Those targets still add compilation, linking, checksumming, and verification work to every release, and our cache warmups build them too. Removing them reduces the release matrix from ten binaries to six and the Linux package matrix from twelve packages to six. We expect shorter builds and releases; the actual time saved will depend on caching and parallelism.</p>
<p>Other large projects have also reduced their 32-bit distributions:</p>
<ul>
<li class=""><a href="https://nodejs.org/en/blog/migrations/v22-to-v24#platform-support" target="_blank" rel="noopener noreferrer" class="">Node.js 24</a> stopped providing prebuilt Linux ARMv7 binaries.</li>
<li class=""><a href="https://www.electronjs.org/blog/electron-43-0#support-for-32-bit-platforms-ending" target="_blank" rel="noopener noreferrer" class="">Electron's July 2026 announcement</a> identifies v43 as its last series with prebuilt Linux ARM and Windows x86 binaries, with support ending in January 2027.</li>
<li class=""><a href="https://www.debian.org/News/2025/20250809" target="_blank" rel="noopener noreferrer" class="">Debian 13's August 2025 announcement</a> removed the i386 installer and kernel while retaining limited use of i386 packages on amd64 systems.</li>
</ul>
<p>These changes provide context for retiring 32-bit downloads. Our decision to retire FreeBSD downloads is based on their low usage in our own release data.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/release-platform-downloads#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>Starting with the release containing this change, prebuilt downloads will cover six <a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/install#release-platforms">platform combinations</a>:</p>
<table><thead><tr><th>Operating system</th><th>Architectures</th></tr></thead><tbody><tr><td>Linux</td><td>amd64, arm64</td></tr><tr><td>macOS</td><td>amd64, arm64</td></tr><tr><td>Windows</td><td>amd64, arm64</td></tr></tbody></table>
<p>New releases will no longer include Linux 386 or 32-bit ARM binaries and their DEB, RPM, or APK packages, or FreeBSD amd64 and arm64 binaries. Assets from previous releases remain available.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/release-platform-downloads#how-to-use-it" class="hash-link" aria-label="Direct link to How to Use It" title="Direct link to How to Use It" translate="no">​</a></h2>
<p>On the affected platforms, install Go and build the latest stable Atmos release locally:</p>
<div class="language-shell codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-shell codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A"><div class="token-line" style="color:#d6deeb"><span class="token plain">go </span><span class="token function" style="color:rgb(130, 170, 255)">install</span><span class="token plain"> github.com/cloudposse/atmos@latest</span><br></div></code></pre></div></div>
<p>Use a Go toolchain that supports your operating system and architecture and meets the selected Atmos release's requirements. Ensure Go's binary installation directory is on your <code>PATH</code>: this is <code>GOBIN</code> if configured, otherwise the <code>bin</code> directory under <code>GOPATH</code> (usually <code>$HOME/go/bin</code>).</p>
<p>For a specific release, replace <code>@latest</code> with its tag, such as <code>@v1.233.0</code>. Update automation that downloads release binaries to use this build step on the affected platforms. Download-based version switching also requires a published binary for your platform; use Go to install the desired version instead.</p>
<p>The <a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/install#install-with-go">Go installation instructions</a> explain version reporting for locally built binaries. Compiling locally takes time and does not produce the signed release artifacts provided by our prebuilt downloads.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/release-platform-downloads#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>If you rely on one of these downloads, <a href="https://github.com/cloudposse/atmos/issues" target="_blank" rel="noopener noreferrer" class="">open an issue</a> describing your platform and installation workflow so we can understand the impact.</p>]]></content:encoded>
            <category>Deprecation</category>
        </item>
        <item>
            <title><![CDATA[Script Input, File Writes, and OS Controls]]></title>
            <link>https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/starlark-process-input-and-files</link>
            <guid>https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/starlark-process-input-and-files</guid>
            <pubDate>Sat, 24 Oct 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Sending a secret to a subprocess should not require putting it in command-line arguments. Generating a local]]></description>
            <content:encoded><![CDATA[<p>Sending a secret to a subprocess should not require putting it in command-line arguments. Generating a local
configuration file or reading an inherited environment variable should not require launching another program.
Atmos automation scripts now support <a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/functions/automation/exec.run#arguments">standard input</a>,
<a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/functions/automation/fs.write_file">file writes</a>, and <a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/functions/automation/os.getenv">environment lookups</a>
directly, with script-local environment and directory controls.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/starlark-process-input-and-files#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>Scripts could start programs and read files, but could not supply a program's standard input or write a file.
The script's explicit <code>env</code> inputs also differed from the inherited environment available to its subprocesses.
That left scripts passing values as command arguments or relying on helper programs for ordinary input and output.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/starlark-process-input-and-files#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>The process functions and Atmos command wrappers accept <code>stdin</code>, file writes use <code>fs.write_file</code>, and the
predeclared <code>os</code> module exposes the effective environment, current directory, platform, and architecture.
Scripts can change their own execution defaults without changing the host Atmos process. The <code>env</code> dictionary
still contains only explicit step inputs, and process calls without <code>stdin</code> receive EOF.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/starlark-process-input-and-files#how-to-use-it" class="hash-link" aria-label="Direct link to How to Use It" title="Direct link to How to Use It" translate="no">​</a></h2>
<p>Read a token and send it through standard input:</p>
<div class="language-python codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-python codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">token </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> os</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">getenv</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string" style="color:rgb(173, 219, 103)">"TOKEN"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">if</span><span class="token plain"> token </span><span class="token operator" style="color:rgb(127, 219, 202)">==</span><span class="token plain"> </span><span class="token boolean" style="color:rgb(255, 88, 116)">None</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    fail</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string" style="color:rgb(173, 219, 103)">"TOKEN is required"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">exec</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">run</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token string" style="color:rgb(173, 219, 103)">"some-tool"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"--token-stdin"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> stdin </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> token</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> output </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"capture"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span></span><br></div></code></pre></div></div>
<p>Input is sent exactly as supplied, without an added newline. Each retry receives the complete input again.
Atmos excludes the payload from command diagnostics; the subprocess still controls its own output.
The same <code>stdin</code> option is available on <a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/functions/automation/component.exec">component process calls</a> and
all <a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/functions/automation/atmos.run">Atmos command wrappers</a>, including
<a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/functions/automation/atmos.secret"><code>atmos.secret</code></a>. Pass any CLI flag that tells the receiving command to
read stdin separately; the wrapper does not add that flag automatically.</p>
<p>Generate a local configuration file:</p>
<div class="language-python codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-python codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A"><div class="token-line" style="color:#d6deeb"><span class="token plain">fs</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">write_file</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string" style="color:rgb(173, 219, 103)">"config.json"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> json</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">encode</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token string" style="color:rgb(173, 219, 103)">"region"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> os</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">getenv</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string" style="color:rgb(173, 219, 103)">"AWS_REGION"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"us-east-1"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><br></div></code></pre></div></div>
<p>New files default to owner-only read/write permissions. The parent directory must exist, and an existing file
causes an error unless you pass <code>overwrite = True</code>. Overwriting preserves the file's existing permissions.</p>
<p>Inspect and adjust execution defaults:</p>
<div class="language-python codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-python codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">original_directory </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> os</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">getcwd</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">original_environment </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> os</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">environ</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">print</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">os</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">platform</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> os</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">arch</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">os</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">setenv</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string" style="color:rgb(173, 219, 103)">"AWS_REGION"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"us-east-1"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">os</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">chdir</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string" style="color:rgb(173, 219, 103)">"generated"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain">  </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># This directory must already exist.</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">fs</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">write_file</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string" style="color:rgb(173, 219, 103)">"config.json"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> json</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">encode</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token string" style="color:rgb(173, 219, 103)">"region"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> os</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">getenv</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string" style="color:rgb(173, 219, 103)">"AWS_REGION"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">os</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">chdir</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">original_directory</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span></span><br></div></code></pre></div></div>
<p>The <a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/functions/automation/os.environ"><code>os.environ()</code></a> function returns a frozen snapshot; later changes do
not alter it. The <a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/functions/automation/os.platform"><code>os.platform</code></a> and
<a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/functions/automation/os.arch"><code>os.arch</code></a> attributes describe the running executable. The
<a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/functions/automation/os.getcwd"><code>os.getcwd()</code></a> function reads the script's current directory.</p>
<p>Call <a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/functions/automation/os.setenv"><code>os.setenv()</code></a> and <a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/functions/automation/os.chdir"><code>os.chdir()</code></a>
only in the main thread. Parallel tasks inherit those settings and use per-call <code>env=</code> or
<code>working_directory=</code> for their own overrides. Environment changes apply to subsequent process and step
calls, including existing component handles. Directory changes affect relative file operations and default
process and step directories; component calls retain their component directory. Neither operation changes
the host process or another script invocation, and <code>os.setenv</code> leaves the declared <code>env</code> dictionary unchanged.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/starlark-process-input-and-files#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>See the <a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/functions/automation">automation function reference</a> for the complete APIs. Share your scripting
use cases in <a href="https://github.com/cloudposse/atmos/discussions" target="_blank" rel="noopener noreferrer" class="">GitHub Discussions</a>.</p>]]></content:encoded>
            <category>Feature</category>
            <category>DX</category>
        </item>
        <item>
            <title><![CDATA[Secret-store credentials through official Atmos plugins]]></title>
            <link>https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/official-auth-secrets-plugins</link>
            <guid>https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/official-auth-secrets-plugins</guid>
            <pubDate>Fri, 23 Oct 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Tools often need API tokens from a secret store as environment variables. Copying those values into shell profiles duplicates credentials and makes rotation harder. The official auth-secrets plugin lets an Atmos identity read the configured store and select exactly which values a command receives.]]></description>
            <content:encoded><![CDATA[<p>Tools often need API tokens from a secret store as environment variables. Copying those values into shell profiles duplicates credentials and makes rotation harder. The official <code>auth-secrets</code> plugin lets an Atmos identity read the configured store and select exactly which values a command receives.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/official-auth-secrets-plugins#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>Secret storage and command authentication are separate concerns. Teams need to connect them without putting plaintext values in configuration, granting every command every secret, or tying plugin updates to an Atmos release.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/official-auth-secrets-plugins#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>The package provides a secret-store credential provider and an environment identity. Atmos controls the store references, masking, and authentication dependencies. The identity maps selected fields into the command environment, with a five-minute lifetime for process-local reuse.</p>
<p>Official packages use independent manifest versions and public OCI repositories. The built-in <code>cloudposse</code> catalog makes them discoverable, while consumers can opt out or configure another catalog. Installation selects one platform from the release index.</p>
<p>Plugin authors can use <a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/plugin/release">plugin release</a> to build, test, package, publish, and sign a release. Native release planning and catalog reconciliation support independently versioned packages in one repository. One Linux job can cross-build every declared platform concurrently, run Linux tests, and prepare the OCI layout. A two-job workflow checks the inventory, then rebuilds and publishes through a protected release job. Atmos handles package iteration and catalog reconciliation without a package matrix, artifact transfer, or separate release scripts.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/official-auth-secrets-plugins#how-to-use-it" class="hash-link" aria-label="Direct link to How to Use It" title="Direct link to How to Use It" translate="no">​</a></h2>
<p>Declare <code>oci://ghcr.io/cloudposse/atmos/plugins/auth-secrets</code> as a plugin package, configure a <code>secrets/store</code> provider, and map its credential fields through a <code>secrets/env</code> identity. See the <a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/plugins#official-secret-store-authentication">complete configuration example</a>.</p>
<p>Run <code>atmos plugin install</code> and commit the plugin lockfile before using the identity in CI. Each package version is independent of Atmos's version. Publication requires public GHCR provisioning and successful release checks and native SDK CI; source availability alone does not mean a version has been published.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/official-auth-secrets-plugins#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>Read the <a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/tutorials/plugin-development">plugin development guide</a> to build your own package, or review the <a href="https://github.com/cloudposse/atmos/tree/main/plugins" target="_blank" rel="noopener noreferrer" class="">official release infrastructure</a>.</p>]]></content:encoded>
            <category>Feature</category>
            <category>Security</category>
        </item>
        <item>
            <title><![CDATA[Script namespaces, records, and typed configuration]]></title>
            <link>https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/starlark-module-namespaces</link>
            <guid>https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/starlark-module-namespaces</guid>
            <pubDate>Fri, 23 Oct 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Import script libraries as namespaces, create records, load typed YAML/JSON with inline, local-file, or HTTPS schemas and source-line diagnostics, and deep merge configuration records.]]></description>
            <content:encoded><![CDATA[<p>Atmos automation scripts can now import a library as a namespace:</p>
<div class="language-python codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-python codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">kube </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> module</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">load</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string" style="color:rgb(173, 219, 103)">"lib/kube.star"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">kube</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">get</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string" style="color:rgb(173, 219, 103)">"pods"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span></span><br></div></code></pre></div></div>
<p>The library defines its functions directly. There is no export object to maintain
and no need to repeat each function name in an import list.</p>
<p>This release also adds <code>struct()</code> records and typed YAML/JSON configuration with
inline or reusable schemas, source-line diagnostics, and immutable deep merging.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="share-functions-between-scripts">Share functions between scripts<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/starlark-module-namespaces#share-functions-between-scripts" class="hash-link" aria-label="Direct link to Share functions between scripts" title="Direct link to Share functions between scripts" translate="no">​</a></h2>
<p>Create <code>lib/kube.star</code>:</p>
<div class="language-python codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-python codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token keyword" style="color:rgb(127, 219, 202)">def</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">get</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">resource</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token keyword" style="color:rgb(127, 219, 202)">return</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(127, 219, 202)">exec</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">run</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token string" style="color:rgb(173, 219, 103)">"kubectl"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"get"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> resource</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span></span><br></div></code></pre></div></div>
<p><a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/functions/automation/module.load"><code>module.load</code></a> exposes the file's public
functions and constants. Names beginning with <code>_</code> remain private. Relative paths
resolve beside the calling script, including calls inside loaded functions;
inline scripts use their working directory.</p>
<p>The function works inside conditionals and parallel tasks. Successful loads share
a cache with ordinary <a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/functions/automation/load"><code>load()</code></a>, so concurrent callers
initialize a file once. Cyclic imports fail instead of waiting indefinitely, and
canceling a waiting task does not cancel another task's initialization. Failed
initialization can be retried, so top-level side effects should be repeatable.</p>
<p>Loaded globals are frozen. Library functions can create local collections, but
cannot modify shared global lists or dictionaries after initialization.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="create-records-with-named-fields">Create records with named fields<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/starlark-module-namespaces#create-records-with-named-fields" class="hash-link" aria-label="Direct link to Create records with named fields" title="Direct link to Create records with named fields" translate="no">​</a></h2>
<p>The new <a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/functions/automation/struct"><code>struct()</code></a> constructor groups values for
dot access:</p>
<div class="language-python codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-python codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">service </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> struct</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">name</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token string" style="color:rgb(173, 219, 103)">"api"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> port</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token number" style="color:rgb(247, 140, 108)">8080</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">print</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">service</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">output </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> service</span></span><br></div></code></pre></div></div>
<p>Fields cannot be reassigned. Nested collections remain mutable until module
loading or parallel execution freezes them. Data-only records encode as JSON
objects; records containing functions cannot be JSON-encoded.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="load-typed-configuration">Load typed configuration<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/starlark-module-namespaces#load-typed-configuration" class="hash-link" aria-label="Direct link to Load typed configuration" title="Direct link to Load typed configuration" translate="no">​</a></h2>
<p><a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/functions/automation/config.load"><code>config.load</code></a> reads YAML or JSON with inline schemas:</p>
<div class="language-python codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-python codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">cfg </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> config</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">load</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string" style="color:rgb(173, 219, 103)">"app.yaml"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> schema</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token string" style="color:rgb(173, 219, 103)">"database"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token string" style="color:rgb(173, 219, 103)">"host"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(130, 170, 255)">str</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token string" style="color:rgb(173, 219, 103)">"port"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> schema</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">field</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token builtin" style="color:rgb(130, 170, 255)">int</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> default</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token number" style="color:rgb(247, 140, 108)">5432</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(130, 170, 255)">min</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token number" style="color:rgb(247, 140, 108)">1</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(130, 170, 255)">max</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token number" style="color:rgb(247, 140, 108)">65535</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token string" style="color:rgb(173, 219, 103)">"debug"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> schema</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">field</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token builtin" style="color:rgb(130, 170, 255)">bool</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> default</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token boolean" style="color:rgb(255, 88, 116)">False</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">print</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">cfg</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">database</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">port</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span></span><br></div></code></pre></div></div>
<p>Reuse a JSON Schema file or an HTTPS schema:</p>
<div class="language-python codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-python codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">cfg </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> config</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">load</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string" style="color:rgb(173, 219, 103)">"app.yaml"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> schema</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token string" style="color:rgb(173, 219, 103)">"app.schema.json"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">cfg </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> config</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">load</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string" style="color:rgb(173, 219, 103)">"app.yaml"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> schema</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token string" style="color:rgb(173, 219, 103)">"https://example.com/schemas/app.schema.json"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span></span><br></div></code></pre></div></div>
<p>Schemas can be JSON or YAML, from local files or HTTPS URLs; relative <code>$ref</code> documents resolve beside the schema. Inline schemas apply explicit
<code>schema.field</code> defaults, reject unknown fields, and support lists, enums, and optional values. File schemas
follow standard JSON Schema semantics, including annotation-only defaults.</p>
<p><a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/functions/automation/config.validate"><code>config.validate</code></a> checks existing values. Results are immutable copies
with dot and index access. File validation errors include line and column numbers in YAML and JSON, plus the
failing field path, for example:</p>
<div class="language-text codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-text codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A"><div class="token-line" style="color:#d6deeb"><span class="token plain">app.yaml:2:9: database.port: expected int, got string</span><br></div></code></pre></div></div>
<p>Both APIs work inside loaded functions and parallel tasks. HTTPS schemas support relative
references, with cancellation, request timeouts, and bounded downloads. Remote schemas
cannot reference local files.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="combine-configuration">Combine configuration<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/starlark-module-namespaces#combine-configuration" class="hash-link" aria-label="Direct link to Combine configuration" title="Direct link to Combine configuration" translate="no">​</a></h2>
<p>Records support <a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/functions/automation/config.merge">Atmos deep merging</a>:</p>
<div class="language-python codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-python codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">base </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> config</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">load</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string" style="color:rgb(173, 219, 103)">"base.yaml"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> schema</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">app_schema</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">overrides </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> config</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">load</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string" style="color:rgb(173, 219, 103)">"prod.yaml"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> schema</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">override_schema</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">cfg </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> base</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">merge</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">overrides</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">cfg_with_tags </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> base</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">merge</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">overrides</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> list_merge_strategy</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token string" style="color:rgb(173, 219, 103)">"append"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span></span><br></div></code></pre></div></div>
<p>Nested objects merge recursively and right-hand values take precedence. Lists replace by default; <code>append</code>
and Atmos's <code>merge</code> by index are also available. The result is a new frozen record; both inputs remain unchanged. To enforce a schema on
combined data, use <code>config.validate(base.merge(overrides), schema=app_schema)</code>.</p>
<p>These APIs are available in standalone scripts, automation script steps, hooks,
and their loaded helpers. YAML <code>!starlark</code> expressions and policy predicates keep
their existing environments.</p>
<p>See the <a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/functions/automation/module.load">module loader reference</a>,
<a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/functions/automation/struct">struct reference</a>,
<a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/functions/automation/config.load">configuration loading reference</a>, and
<a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/functions/automation/schema">inline schema helpers</a> for the complete behavior.</p>]]></content:encoded>
            <category>Feature</category>
            <category>DX</category>
        </item>
        <item>
            <title><![CDATA[Choose a component executable with --command]]></title>
            <link>https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/component-command-override</link>
            <guid>https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/component-command-override</guid>
            <pubDate>Thu, 22 Oct 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Trying a different Terraform binary or a local wrapper should not require changing shared stack configuration. The component command families now accept a consistent --command flag for a single invocation, with explicit precedence over configured executables.]]></description>
            <content:encoded><![CDATA[<p>Trying a different Terraform binary or a local wrapper should not require changing shared stack configuration. The component command families now accept a consistent <code>--command</code> flag for a single invocation, with explicit precedence over configured executables.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/component-command-override#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>Executable settings can come from CLI configuration, stack inheritance, and component overrides. A command-line selection must remain effective after those settings merge. Different component families also used different flag names for the same purpose.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/component-command-override#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>Use <code>--command</code> to select an executable name or path for the current invocation. The existing component-specific flags remain compatibility aliases. Supplying both spellings or an empty executable produces an error.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/component-command-override#how-to-use-it" class="hash-link" aria-label="Direct link to How to Use It" title="Direct link to How to Use It" translate="no">​</a></h2>
<p>For <a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/terraform/usage">Terraform and OpenTofu</a>:</p>
<div class="language-shell codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-shell codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A"><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos terraform plan app </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-s</span><span class="token plain"> dev </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--command</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">tofu</span><br></div></code></pre></div></div>
<p>The same option applies to <a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/helmfile/usage">Helmfile</a>, <a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/packer/usage">Packer</a>, and <a class="" href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/ansible/playbook">Ansible</a>:</p>
<div class="language-shell codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-shell codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A"><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos helmfile template app </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-s</span><span class="token plain"> dev </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--command</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">/usr/local/bin/helmfile</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos packer inspect image </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-s</span><span class="token plain"> dev </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--command</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">/usr/local/bin/packer</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos ansible playbook app </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-s</span><span class="token plain"> dev </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--command</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">/usr/local/bin/ansible-playbook</span><br></div></code></pre></div></div>
<p>An executable override selects the subprocess-backed component tool. Arguments after <code>--</code> still belong to that tool. SDK-backed component types do not have an executable to override.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-3593.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/component-command-override#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>Share reproducible command-selection problems in <a href="https://github.com/cloudposse/atmos/issues" target="_blank" rel="noopener noreferrer" class="">Atmos issues</a>.</p>]]></content:encoded>
            <category>Feature</category>
            <category>DX</category>
        </item>
    </channel>
</rss>