<?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-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog</link>
        <description>atmos Blog</description>
        <lastBuildDate>Wed, 05 Aug 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[Toolchain registry adds github_archive and github_content support]]></title>
            <link>https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/toolchain-aqua-archive-and-content</link>
            <guid>https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/toolchain-aqua-archive-and-content</guid>
            <pubDate>Wed, 05 Aug 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Atmos's Aqua-compatible toolchain registry now understands two more package types: githubarchive and githubcontent. Tools that ship as a source tarball (like adr-tools and tfenv) or as a single raw file in a repo (like kubens and kubectx) can now be installed through atmos toolchain install without any registry workarounds.]]></description>
            <content:encoded><![CDATA[<p>Atmos's Aqua-compatible toolchain registry now understands two more package types: <code>github_archive</code> and <code>github_content</code>. Tools that ship as a source tarball (like <code>adr-tools</code> and <code>tfenv</code>) or as a single raw file in a repo (like <code>kubens</code> and <code>kubectx</code>) can now be installed through <code>atmos toolchain install</code> without any registry workarounds.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="what-changed">What Changed<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/toolchain-aqua-archive-and-content#what-changed" class="hash-link" aria-label="Direct link to What Changed" title="Direct link to What Changed" translate="no">​</a></h2>
<p>Aqua's registry defines several package types for downloading tools. Atmos previously supported only two:</p>
<ul>
<li class=""><code>github_release</code> — assets attached to a GitHub Release</li>
<li class=""><code>http</code> — arbitrary HTTP(S) URLs</li>
</ul>
<p>Two more are now supported:</p>
<ul>
<li class=""><code>github_archive</code> — the auto-generated source tarball produced by GitHub for any tag, downloaded from <code>github.com/{owner}/{repo}/archive/refs/tags/{version}.tar.gz</code>. Always <code>.tar.gz</code>, regardless of the <code>format</code> field.</li>
<li class=""><code>github_content</code> — a single file from a GitHub repo at a tag, downloaded from <code>raw.githubusercontent.com/{owner}/{repo}/{version}/{path}</code>. The required <code>path</code> field points to the file inside the repo.</li>
</ul>
<p>Both implementations match upstream <code>aquaproj/aqua</code> exactly. For <code>github_archive</code>, the <code>asset</code>, <code>url</code>, <code>format</code>, and <code>format_overrides</code> fields are intentionally ignored (Aqua hardcodes <code>tar.gz</code> and the URL pattern). For <code>github_content</code>, the same fields are ignored — only <code>repo_owner</code>, <code>repo_name</code>, and <code>path</code> are used.</p>
<p>Before this release, any Aqua registry entry using either type failed with <code>unsupported tool type: ...</code>. Those entries now resolve correctly.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/toolchain-aqua-archive-and-content#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>
<h3 class="anchor anchorTargetStickyNavbar_cA1_" id="github_archive">github_archive<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/toolchain-aqua-archive-and-content#github_archive" class="hash-link" aria-label="Direct link to github_archive" title="Direct link to github_archive" translate="no">​</a></h3>
<p>For a tool that ships its binary as a script inside its source tree — such as <code>adr-tools</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">packages</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"> github_archive</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">repo_owner</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> npryce</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">repo_name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> adr</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">tools</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">files</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"> adr</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">src</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> adr</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">tools</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">trimV .Version</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">/src/adr</span></span><br></div></code></pre></div></div>
<p>The <code>{{trimV .Version}}</code> template expands to match GitHub's archive root directory (e.g., <code>adr-tools-3.0.0/</code> for version <code>v3.0.0</code>), so <code>files[].src</code> points to the file inside the extracted archive.</p>
<h3 class="anchor anchorTargetStickyNavbar_cA1_" id="github_content">github_content<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/toolchain-aqua-archive-and-content#github_content" class="hash-link" aria-label="Direct link to github_content" title="Direct link to github_content" translate="no">​</a></h3>
<p>For a tool that ships as a single raw file in a repo — such as <code>kubens</code> from <code>ahmetb/kubectx</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">packages</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"> github_content</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">repo_owner</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> ahmetb</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">repo_name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> kubectx</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"> kubens</span></span><br></div></code></pre></div></div>
<p>The download URL becomes <code>https://raw.githubusercontent.com/ahmetb/kubectx/{version}/kubens</code>. No archive extraction is involved — the file is downloaded directly.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="why-this-matters">Why This Matters<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/toolchain-aqua-archive-and-content#why-this-matters" class="hash-link" aria-label="Direct link to Why This Matters" title="Direct link to Why This Matters" translate="no">​</a></h2>
<p>Aqua's upstream registry has hundreds of entries that use these two types — <code>tfenv</code>, <code>tgswitch</code>, <code>adr-tools</code>, <code>kubectx</code>, <code>kubens</code>, and many one-binary shell-script projects. Until now, those entries were dead in Atmos. Adding these two package types unblocks all of them without registry-level changes: pull the Aqua registry entry as-is and it just works.</p>
<p>The Aqua-compatible build/install types (<code>go_install</code>, <code>go_build_install</code>, <code>cargo</code>) remain unsupported — they require invoking a language toolchain at install time rather than downloading an artifact, which is a different installation model. A follow-up issue tracks that work.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/toolchain-aqua-archive-and-content#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>Atmos is open source on <a href="https://github.com/cloudposse/atmos" target="_blank" rel="noopener noreferrer" class="">GitHub</a>. File issues or open PRs if you hit any tools the registry can't resolve.</p>]]></content:encoded>
            <category>Feature</category>
        </item>
        <item>
            <title><![CDATA[Azure Interactive Browser Authentication]]></title>
            <link>https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/azure-interactive-auth</link>
            <guid>https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/azure-interactive-auth</guid>
            <pubDate>Tue, 04 Aug 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Atmos now supports the azure/interactive provider — the same interactive browser login az login uses (authorization code + PKCE on a localhost redirect). One command, atmos auth login, opens your browser, signs you in, and sets up everything Terraform and the az CLI need.]]></description>
            <content:encoded><![CDATA[<p>Atmos now supports the <code>azure/interactive</code> provider — the same interactive browser login <code>az login</code> uses (authorization code + PKCE on a localhost redirect). One command, <code>atmos auth login</code>, opens your browser, signs you in, and sets up everything Terraform and the <code>az</code> CLI need.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="why-this-matters">Why This Matters<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/azure-interactive-auth#why-this-matters" class="hash-link" aria-label="Direct link to Why This Matters" title="Direct link to Why This Matters" translate="no">​</a></h2>
<p><strong>Device code is getting blocked</strong>: Microsoft-managed Conditional Access policies now block the device code flow in many tenants (error <code>AADSTS530035</code>), so <code>azure/device-code</code> fails there. The interactive browser flow carries full Conditional Access context, so it keeps working.</p>
<p><strong>One command instead of two</strong>: <code>azure/cli</code> requires a pre-existing <code>az login</code> session. With <code>azure/interactive</code>, <code>atmos auth login</code> is the only command you run.</p>
<p><strong>Silent repeat logins</strong>: Atmos tries silent acquisition from the persisted MSAL cache first. Refresh tokens make repeat logins silent — no browser after the first sign-in.</p>
<p><strong>Drop-in for az login</strong>: Atmos writes the Azure CLI-compatible cache files (MSAL token cache and <code>azureProfile.json</code>), so after <code>atmos auth login</code> the <code>az</code> CLI works without ever running <code>az login</code>. Guest/B2B users are handled correctly using the real MSAL home account ID.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/azure-interactive-auth#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>
<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">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">azure-browser</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"> azure/interactive</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">tenant_id</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)">"12345678-1234-1234-1234-123456789012"</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">subscription_id</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)">"87654321-4321-4321-4321-210987654321"</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">location</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> eastus</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">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">azure-dev</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">default</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">kind</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> azure/subscription</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"> azure</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">browser</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">principal</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">subscription_id</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)">"87654321-4321-4321-4321-210987654321"</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">location</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> eastus</span></span><br></div></code></pre></div></div>
<p>Then authenticate:</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 auth login</span><br></div></code></pre></div></div>
<p>Atmos opens your default browser for sign-in (with MFA if configured), acquires Management, Graph, and Key Vault tokens, and caches them for azurerm, azuread, and azapi. Chain identities via <code>azure/subscription</code> exactly like the other Azure providers.</p>
<p>The spec shape is identical to <code>azure/device-code</code>: <code>tenant_id</code> (required), plus optional <code>subscription_id</code>, <code>location</code>, <code>client_id</code> (defaults to the Azure CLI public client), and <code>cloud_environment</code> (<code>public</code>, <code>usgovernment</code>, or <code>china</code>).</p>
<p>The flow requires an interactive terminal and a browser. For headless environments and CI/CD, keep using <code>azure/oidc</code>; where a browser can't be opened (e.g., SSH sessions), <code>azure/device-code</code> remains available.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/azure-interactive-auth#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<ul>
<li class="">Read the <a class="" href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/auth/providers">provider documentation</a> and the <a class="" href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/tutorials/azure-authentication">Azure Authentication tutorial</a></li>
<li class="">Report issues on <a href="https://github.com/cloudposse/atmos/issues" target="_blank" rel="noopener noreferrer" class="">GitHub</a></li>
</ul>]]></content:encoded>
            <category>Feature</category>
        </item>
        <item>
            <title><![CDATA[Populate a Store From Infrastructure You Already Deployed]]></title>
            <link>https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/hooks-on-terraform-output-and-refresh</link>
            <guid>https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/hooks-on-terraform-output-and-refresh</guid>
            <pubDate>Tue, 04 Aug 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Reference architectures live for years. By the time you wire up a store hook, most of what]]></description>
            <content:encoded><![CDATA[<p>Reference architectures live for years. By the time you wire up a store hook, most of what
it should cover was already deployed — some of it before hooks existed, some of it by a
process outside Atmos entirely. Store hooks only ran after <code>apply</code>. To get an existing VPC ID
or subnet list into a store, you had to force a fresh <code>apply</code>, or fall back to a manual write
with a cloud CLI.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/hooks-on-terraform-output-and-refresh#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>A <code>kind: store</code> hook reads a Terraform output and writes it to a configured store, so other
components can read it back later with <code>!store</code> or <code>!store.get</code>. Before this change, the
supported lifecycle events did not include <code>output</code> or <code>refresh</code>. Nothing fired when you just
wanted to <em>read</em> a value from infrastructure that already exists.</p>
<p>That gap matters most for the infrastructure you're least likely to touch again soon: a
production VPC someone applied by hand two years ago, or a reference architecture deployed
before your organization adopted hooks at all. Backfilling a store from that infrastructure
meant either re-running <code>apply</code> against something that didn't need to change, or writing the
value into the store yourself, outside Atmos.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/hooks-on-terraform-output-and-refresh#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 fires lifecycle hooks around <code>atmos terraform output</code> and <code>atmos terraform refresh</code>, the same way it already does for <code>plan</code>, <code>apply</code>, and <code>test</code>. A <code>kind: store</code> hook
(or a <code>type: store</code> step run through the <code>kind: step</code> bridge) can bind to
<code>after.terraform.output</code> instead of, or alongside, <code>after.terraform.apply</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">hooks</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">backfill</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">events</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">after.terraform.output</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"> 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">name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> prod/ssm</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">outputs</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">vpc_id</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> .id</span></span><br></div></code></pre></div></div>
<p>Running <code>atmos terraform output vpc -s prod</code> now reads the current state and writes <code>vpc_id</code>
into the store — no <code>apply</code> required. <code>before</code>/<code>after.terraform.refresh</code> events fire the same
way around <code>atmos terraform refresh</code>, for hooks that care about reconciling state with the
real infrastructure rather than just reading it.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/hooks-on-terraform-output-and-refresh#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>Scope a store hook to <code>after.terraform.output</code> to backfill values from infrastructure that's
already running:</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">hooks</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">outputs</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">events</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">after.terraform.output</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"> 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">name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> prod/ssm</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">outputs</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">vpc_id</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> .id</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">private_subnet_ids</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> .private_subnet_ids</span></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 terraform output vpc </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-s</span><span class="token plain"> prod</span><br></div></code></pre></div></div>
<p>Keep an existing <code>after.terraform.apply</code> hook untouched, or list both events on the same hook
so it fires on either command:</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">hooks</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">outputs</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">events</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">after.terraform.apply</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> after.terraform.output</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"> 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">name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> prod/ssm</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">outputs</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">vpc_id</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> .id</span></span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/hooks-on-terraform-output-and-refresh#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>Try binding a store hook to <code>after.terraform.output</code> against infrastructure you didn't apply
through Atmos. Tell us what's missing — an aggregate event for <code>--affected</code>/<code>--all</code> output
runs, or another lifecycle command entirely. Open an issue or start a discussion at
<a href="https://github.com/cloudposse/atmos" target="_blank" rel="noopener noreferrer" class="">github.com/cloudposse/atmos</a>.</p>]]></content:encoded>
            <category>Feature</category>
        </item>
        <item>
            <title><![CDATA[Read, Write, and Delete Store Values from the CLI and Workflows]]></title>
            <link>https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/store-crud-and-workflow-writes</link>
            <guid>https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/store-crud-and-workflow-writes</guid>
            <pubDate>Mon, 03 Aug 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[A build step often creates a value that a different step needs later. Examples are an image tag, a build number, or a deployment marker. In the past, you had only bad ways to pass this value along. You could write it into Terraform state, where it does not belong. You could run a cloud CLI command by hand. You could also build a custom file-based handoff between steps. Atmos already had a fast way to read any value from a configured store. But Atmos had no supported way to write a value into a store. The only exception was one narrow hook. That hook works only with Terraform output. For every other value, you had to leave Atmos to write it.]]></description>
            <content:encoded><![CDATA[<p>A build step often creates a value that a different step needs later. Examples are an image tag, a build number, or a deployment marker. In the past, you had only bad ways to pass this value along. You could write it into Terraform state, where it does not belong. You could run a cloud CLI command by hand. You could also build a custom file-based handoff between steps. Atmos already had a fast way to read any value from a configured store. But Atmos had no supported way to write a value into a store. The only exception was one narrow hook. That hook works only with Terraform output. For every other value, you had to leave Atmos to write it.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/store-crud-and-workflow-writes#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>Atmos stores support many backends. Examples are AWS SSM, AWS Secrets Manager, HashiCorp Vault, Azure Key Vault, GCP Secret Manager, Redis, Artifactory, 1Password, Keychain, and GitHub Actions. The <code>!store</code> and <code>!store.get</code> YAML functions can read any value from these stores. But Atmos gave you only two ways to write a value into a store. You could declare the value as a formal secret with <code>atmos secret</code>. Or you could use the one existing store hook. That hook only copies a Terraform output into a store after <code>apply</code> runs. Atmos had no supported way to write other values, such as a Docker image tag from a <code>container</code> build step, a build number, or a deployment marker created mid-workflow. To write one of these values, you had to use the AWS CLI, <code>curl</code>, or a custom shell script in the workflow.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/store-crud-and-workflow-writes#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 has a new CLI command group named <code>atmos store</code>. This command group gives you raw CRUD access to any configured store. Atmos also has a new workflow step named <code>type: store</code>. This step writes a value from a workflow, a custom command, or a hook. Neither the CLI nor the step requires you to declare a value first. Both work directly on any backend listed under <code>stores:</code> in <code>atmos.yaml</code>. You can scope a value to a stack and a component. Or you can omit the stack and component to make the value global.</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 store </span><span class="token builtin class-name" style="color:rgb(255, 203, 139)">set</span><span class="token plain"> app-metadata image_tag sha256:abc123 </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--stack</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">prod </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--component</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">ecs-service</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos store get app-metadata image_tag </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--stack</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">prod </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--component</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">ecs-service</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos store list</span><br></div></code></pre></div></div>
<p>The <code>store</code> step closes the loop with the existing read functions. First, a workflow builds an image and pushes it. Next, the workflow writes the resulting tag to a store. Later, a completely separate deploy run reads the tag back with <code>!store</code> or <code>!store.get</code>. This flow needs no shared Terraform state and no custom scripts.</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">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">name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> push</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"> container</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"> push</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">image</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> myapp</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"> .env.GIT_SHA </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" 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 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"> record</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">tag</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"> 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">action</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> write</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">store</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> app</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">metadata</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">key</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> image_tag</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">value</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)">"{{ .steps.push.metadata.digest }}"</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">stack</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> prod</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"> ecs</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">service</span></span><br></div></code></pre></div></div>
<p>The <code>store</code> step is a normal registered step type. Because of this, it also runs as a hook through the existing <code>kind: step</code> bridge. You need no extra configuration to run it after <code>terraform apply</code>.</p>
<p>Atmos allows you to write to a <code>secret: true</code> store on purpose. For example, a step can generate a password and write it straight to a secret backend. Both the CLI and the step support this case. But this write is only a shortcut. It is not a replacement for <code>atmos secret</code>. It skips declaration and scope tracking. When a value must be tracked as a formal secret, use <code>secrets.vars</code> and <code>atmos secret set</code> instead.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/store-crud-and-workflow-writes#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 and read a value scoped to a stack and a 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 store </span><span class="token builtin class-name" style="color:rgb(255, 203, 139)">set</span><span class="token plain"> app-metadata image_tag sha256:abc123 </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--stack</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">prod </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--component</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">ecs-service</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos store get app-metadata image_tag </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--stack</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">prod </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--component</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">ecs-service </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>Delete the value. Then list the configured stores:</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 store delete app-metadata image_tag </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--stack</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">prod </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--component</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">ecs-service</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos store list</span><br></div></code></pre></div></div>
<p>Write a value from a workflow step. Then read the value back in stack configuration for a completely different component:</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"># workflow</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"> record</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">tag</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"> 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">action</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> write</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">store</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> app</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">metadata</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">key</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> image_tag</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">value</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)">"{{ .steps.push.metadata.digest }}"</span></span><br></div></code></pre></div></div>
<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"># stacks/.../ecs-service.yaml</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">image_tag</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)">!store</span><span class="token plain"> app</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">metadata prod ecs</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">service image_tag</span></span><br></div></code></pre></div></div>
<p>Both the command group and the step type are experimental for now. We may change them as we get feedback from users.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/store-crud-and-workflow-writes#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>atmos store</code> and the <code>store</code> step in your own build-to-deploy pipeline. Tell us what is missing. Examples are a matching read step, bulk import and export, or another feature. You can open an issue or start a discussion at <a href="https://github.com/cloudposse/atmos" target="_blank" rel="noopener noreferrer" class="">github.com/cloudposse/atmos</a>.</p>]]></content:encoded>
            <category>Feature</category>
            <category>Experimental</category>
        </item>
        <item>
            <title><![CDATA[Use Tags and Labels with Workflows]]></title>
            <link>https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/workflow-tags-and-labels</link>
            <guid>https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/workflow-tags-and-labels</guid>
            <pubDate>Mon, 03 Aug 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Atmos workflows already supported --stack. They now also support --tags and --labels, forwarding those selectors to every nested type: atmos step.]]></description>
            <content:encoded><![CDATA[<p>Atmos workflows already supported <code>--stack</code>. They now also support <code>--tags</code> and <code>--labels</code>, forwarding those selectors to every nested <code>type: atmos</code> step.</p>
<p>For an introduction to defining and selecting <a class="" href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/tags-and-labels">tags and labels</a>, see the original feature announcement.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/workflow-tags-and-labels#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>Use tags and labels on their 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 workflow deploy </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--tags</span><span class="token plain"> networking </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--labels</span><span class="token plain"> deployment:dev</span><br></div></code></pre></div></div>
<p><code>--stack</code>, <code>--tags</code>, and <code>--labels</code> are all optional selectors. Combine the ones that define the scope you need:</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 workflow deploy </span><span class="token punctuation" style="color:rgb(199, 146, 234)">\</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--stack</span><span class="token plain"> tenant1-ue2-dev </span><span class="token punctuation" style="color:rgb(199, 146, 234)">\</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--tags</span><span class="token plain"> networking </span><span class="token punctuation" style="color:rgb(199, 146, 234)">\</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--labels</span><span class="token plain"> deployment:dev</span><br></div></code></pre></div></div>
<p>Use the same selectors you already use with normal Atmos commands, while keeping the workflow's ordering, dependencies, parallel steps, and matrix steps intact.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/workflow-tags-and-labels#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>Try tags and labels with the workflows you already use for targeted deployments. If a workflow pattern needs a different selection model, open an issue with the command and component scope you want to express.</p>]]></content:encoded>
            <category>Feature</category>
        </item>
        <item>
            <title><![CDATA[Script-Friendly Output for atmos toolchain get]]></title>
            <link>https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/toolchain-get-plain-json-output</link>
            <guid>https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/toolchain-get-plain-json-output</guid>
            <pubDate>Fri, 31 Jul 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Pulling a tool's version into a script usually means scraping decorated terminal output. A checkmark here, a]]></description>
            <content:encoded><![CDATA[<p>Pulling a tool's version into a script usually means scraping decorated terminal output. A checkmark here, a
color code there, maybe a table row — and now the one-liner that used to grab a version string needs a
regex, a <code>head -1</code>, and a <code>2&gt;&amp;1</code> to work around output that was never meant to be parsed.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/toolchain-get-plain-json-output#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>A CI job that needs a tool's configured version — to pass to another action, or write to
<code>GITHUB_OUTPUT</code> — had to reach for something like:</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 assign-left variable" style="color:rgb(214, 222, 235)">version</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token variable" style="color:rgb(214, 222, 235)">$(</span><span class="token variable" style="color:rgb(214, 222, 235)">atmos toolchain get vale-cli/vale </span><span class="token variable operator file-descriptor important" style="color:rgb(127, 219, 202)">2</span><span class="token variable operator" style="color:rgb(127, 219, 202)">&gt;</span><span class="token variable file-descriptor important" style="color:rgb(214, 222, 235)">&amp;1</span><span class="token variable" style="color:rgb(214, 222, 235)"> </span><span class="token variable operator" style="color:rgb(127, 219, 202)">|</span><span class="token variable" style="color:rgb(214, 222, 235)"> </span><span class="token variable function" style="color:rgb(130, 170, 255)">grep</span><span class="token variable" style="color:rgb(214, 222, 235)"> </span><span class="token variable parameter variable" style="color:rgb(214, 222, 235)">-oE</span><span class="token variable" style="color:rgb(214, 222, 235)"> </span><span class="token variable string" style="color:rgb(173, 219, 103)">'[0-9]+\.[0-9]+\.[0-9]+'</span><span class="token variable" style="color:rgb(214, 222, 235)"> </span><span class="token variable operator" style="color:rgb(127, 219, 202)">|</span><span class="token variable" style="color:rgb(214, 222, 235)"> </span><span class="token variable function" style="color:rgb(130, 170, 255)">head</span><span class="token variable" style="color:rgb(214, 222, 235)"> </span><span class="token variable parameter variable" style="color:rgb(214, 222, 235)">-1</span><span class="token variable" style="color:rgb(214, 222, 235)">)</span><span class="token plain"></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)">echo</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"version=</span><span class="token string variable" style="color:rgb(214, 222, 235)">$version</span><span class="token string" style="color:rgb(173, 219, 103)">"</span><span class="token plain"> </span><span class="token operator" style="color:rgb(127, 219, 202)">&gt;&gt;</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_OUTPUT</span><span class="token string" style="color:rgb(173, 219, 103)">"</span><br></div></code></pre></div></div>
<p>That's a lot of shell just to answer "what version is configured?" — a regex to strip a checkmark and
color codes, <code>head -1</code> because the human-readable view can list more than one line, and <code>2&gt;&amp;1</code> because the
output goes to stderr, not stdout.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/toolchain-get-plain-json-output#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p><code>atmos toolchain get</code> now supports a <code>--format</code> flag with two script-friendly output modes alongside the
existing human-readable table: <code>plain</code> prints just the bare version string, and <code>json</code> prints structured
output including whether that version is installed.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/toolchain-get-plain-json-output#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>Grab a version with nothing to parse:</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 get vale-cli/vale </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">plain</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token number" style="color:rgb(247, 140, 108)">2.20</span><span class="token plain">.0</span><br></div></code></pre></div></div>
<p>Which collapses the CI snippet above to:</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 assign-left variable" style="color:rgb(214, 222, 235)">version</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token variable" style="color:rgb(214, 222, 235)">$(</span><span class="token variable" style="color:rgb(214, 222, 235)">atmos toolchain get vale-cli/vale </span><span class="token variable parameter variable" style="color:rgb(214, 222, 235)">--format</span><span class="token variable operator" style="color:rgb(127, 219, 202)">=</span><span class="token variable" style="color:rgb(214, 222, 235)">plain</span><span class="token variable" style="color:rgb(214, 222, 235)">)</span><span class="token plain"></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)">echo</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"version=</span><span class="token string variable" style="color:rgb(214, 222, 235)">$version</span><span class="token string" style="color:rgb(173, 219, 103)">"</span><span class="token plain"> </span><span class="token operator" style="color:rgb(127, 219, 202)">&gt;&gt;</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_OUTPUT</span><span class="token string" style="color:rgb(173, 219, 103)">"</span><br></div></code></pre></div></div>
<p>Ask for more than the version string with <code>--format=json</code>:</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 get terraform </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>
<div class="language-json codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-json 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><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 property" style="color:rgb(128, 203, 196)">"tool"</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)">"hashicorp/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 property" style="color:rgb(128, 203, 196)">"version"</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)">"1.9.8"</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 property" style="color:rgb(128, 203, 196)">"installed"</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)">false</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><br></div></code></pre></div></div>
<p><code>--format=plain</code> only makes sense for a single resolved version, so it's rejected when combined with
<code>--all</code> (which lists every available version) — use <code>--format=json</code> there instead, which returns the full
list with each entry's installed and default status.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/toolchain-get-plain-json-output#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>--format=plain</code> or <code>--format=json</code> the next time you're piping a tool version into a script. If you
run into a <code>toolchain</code> command that still only prints decorated, hard-to-parse output, please
<a href="https://github.com/cloudposse/atmos/issues" target="_blank" rel="noopener noreferrer" class="">open an issue</a> so we can add the same script-friendly modes
there too.</p>]]></content:encoded>
            <category>Feature</category>
        </item>
        <item>
            <title><![CDATA[Apply a Stack and Everything It Depends On]]></title>
            <link>https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/include-dependencies-closure</link>
            <guid>https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/include-dependencies-closure</guid>
            <pubDate>Mon, 27 Jul 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Standing up an environment is rarely one apply. The stack you actually care about sits on top of prerequisites — a network layer in a shared stack, a database a few components down — and something has to run them first, in the right order. In practice that "something" is usually a bash wrapper --include-dependencies and --include-dependents expand any multi-component selection with its dependency closure and execute it in graph order, and the list commands preview exactly what would run.]]></description>
            <content:encoded><![CDATA[<p>Standing up an environment is rarely one <code>apply</code>. The stack you actually care about sits on top of prerequisites — a network layer in a shared stack, a database a few components down — and something has to run them first, in the right order. In practice that "something" is usually a bash wrapper: a hand-maintained list of stacks, a loop of <code>atmos terraform apply</code> calls, and a prayer that the ordering comments are still true. Atmos now does this natively: <code>--include-dependencies</code> and <code>--include-dependents</code> expand any multi-component selection with its dependency closure and execute it in graph order, and the <code>list</code> commands preview exactly what would run.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/include-dependencies-closure#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>Atmos has always known the dependency graph — <code>dependencies.components</code> declares what each component needs, and bulk operations like <code>atmos terraform apply --all</code> already execute in topological order. But the <em>selection</em> never followed the edges. Selecting a stack with <code>-s dev</code>, or a set of components with <code>--tags</code> or <code>--labels</code>, ran only what matched; prerequisites living in another stack (or without the matching tag) were silently out of scope. Deploying "dev and everything dev needs" meant knowing the prerequisite chain yourself and scripting around Atmos — exactly the kind of glue the tool exists to remove.</p>
<p>The reverse direction had the same gap: after changing a shared component, running everything that <em>depends on</em> it was only possible through <code>--affected</code>, not from an arbitrary selection.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/include-dependencies-closure#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>Every multi-component terraform selection — <code>--all</code>, <code>--components</code>, <code>--query</code>, <code>-s</code>, <code>--tags</code>, <code>--labels</code>, and <code>--affected</code> — now accepts two closure flags:</p>
<ul>
<li class="">The <code>--include-dependencies[=N]</code> flag expands the selection with everything it depends on (its prerequisites), N levels deep. The bare flag means unlimited depth.</li>
<li class="">The <code>--include-dependents[=N]</code> flag expands in the reverse direction: everything that depends on the selection.</li>
</ul>
<p>Selectors choose the <em>seed</em>; the closure flags <em>expand</em> it. Expanded components execute even when they don't match the selectors — a prerequisite doesn't need your <code>env=dev</code> label to be required by something that has it. Execution stays in dependency order (reverse order for <code>destroy</code>), and cross-stack edges are followed: <code>apply --all -s dev --include-dependencies</code> will run a prerequisite in <code>core</code> before the components in <code>dev</code>.</p>
<p>The same flags work on <code>atmos list components</code>, <code>atmos list stacks</code>, and <code>atmos list instances</code>, so you can see the exact set a bulk run would execute before running it.</p>
<p>Scoping stays lazy: Atmos first walks a lightweight structural graph to find the closure, then fully evaluates (templates, YAML functions, authentication) only the stacks the closure actually touches. An unrelated account's unreachable backend still can't break your deploy.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/include-dependencies-closure#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>Apply everything labeled for dev, plus all of its prerequisites, in dependency order:</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 apply </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)">--labels</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">env</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">dev --include-dependencies</span><br></div></code></pre></div></div>
<p>Bound the expansion to one dependency level:</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)">--tags</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">app --include-dependencies</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token number" style="color:rgb(247, 140, 108)">1</span><br></div></code></pre></div></div>
<p>Tear down a component and everything that depends on it (dependents are destroyed first):</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 destroy </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--components</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">vpc </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-s</span><span class="token plain"> dev --include-dependents</span><br></div></code></pre></div></div>
<p>Preview the execution set without running anything:</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 list components </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--labels</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">env</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">dev --include-dependencies</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos list stacks </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--labels</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">env</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">dev --include-dependencies</span><br></div></code></pre></div></div>
<p>A few things to know:</p>
<ul>
<li class="">Using <code>--include-dependencies</code> with <code>destroy</code> also destroys <em>shared</em> prerequisites of your selection — components other stacks may still rely on. Atmos warns when you combine them.</li>
<li class="">Because <code>metadata.tags</code> and <code>metadata.labels</code> now drive scoping decisions <em>before</em> evaluation, they are selectors by design: plain strings, simple templates, and local functions like <code>!env</code>, <code>!git.*</code>, and <code>!include</code> are allowed, but values that require authentication or execution (<code>!terraform.state</code>, <code>!store</code>, <code>!exec</code>, <code>atmos.Component</code>, ...) are rejected with an error. This contract is enforced for every component whenever stacks are enumerated — by <code>describe</code>, <code>list</code>, and bulk terraform commands — even when no selector flag is used and the component is outside the current stack filter, so an existing impure value fails fast rather than surfacing later as a confusing scoping bug. The error names the offending component and stack manifest. Move those values into <code>vars</code> or <code>settings</code> instead — or, if you need time to migrate, set <code>describe.settings.eager_evaluation: true</code> in <code>atmos.yaml</code> to restore the previous full-evaluation behavior (see the <a class="" href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/describe">describe configuration</a> reference).</li>
<li class="">If you already combine <code>--affected --include-dependents</code> with <code>--tags</code> or <code>--labels</code>, note the semantics changed: previously the tag/label filter also removed non-matching dependents from the expanded set; now selectors narrow only the <em>seed</em> and closure members are retained regardless. That is the whole point of closure expansion — but it does mean such runs can now include more components than before.</li>
<li class="">The depth value must be attached with <code>=</code> (for example <code>--include-dependencies=2</code>). On the terraform commands a bare <code>--include-dependencies</code> followed by a separate value is also accepted, so take care that a following positional argument isn't consumed as the depth — Atmos rejects non-numeric values loudly rather than guessing.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/include-dependencies-closure#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 closure flags on your own dependency graph and tell us where the semantics surprise you — especially around <code>destroy</code> ordering and depth bounds. Issues and discussions are open at <a href="https://github.com/cloudposse/atmos" target="_blank" rel="noopener noreferrer" class="">github.com/cloudposse/atmos</a>.</p>]]></content:encoded>
            <category>Feature</category>
            <category>DX</category>
        </item>
        <item>
            <title><![CDATA[Stack-Wide Metadata Defaults: Set Labels and Tags Once]]></title>
            <link>https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/global-metadata-defaults</link>
            <guid>https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/global-metadata-defaults</guid>
            <pubDate>Sat, 25 Jul 2026 12:00:00 GMT</pubDate>
            <description><![CDATA[Most components in a stack share the same cost center label or the same compliance-scope tag. vars, env, and settings can all be declared once at the stack level and inherited by every component. metadata couldn't — every component had to repeat the same labels/tags, and a metadata: block placed at the top of a stack file was silently ignored.]]></description>
            <content:encoded><![CDATA[<p>Most components in a stack share the same cost center label or the same compliance-scope tag. <code>vars</code>, <code>env</code>, and <code>settings</code> can all be declared once at the stack level and inherited by every component. <code>metadata</code> couldn't — every component had to repeat the same <code>labels</code>/<code>tags</code>, and a <code>metadata:</code> block placed at the top of a stack file was silently ignored.</p>
<p>Stack manifests can now declare stack-wide metadata defaults that every component inherits, with the component's own <code>metadata:</code> still free to override them.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/global-metadata-defaults#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<ul>
<li class=""><strong>Shared metadata meant duplicated metadata.</strong> If every component in a stack carries the same <code>cost-center</code> label or the same compliance tag, that block had to be copy-pasted into every component definition, and kept in sync by hand as components were added.</li>
<li class=""><strong>A stack-level <code>metadata:</code> block looked like it should work, and didn't.</strong> Unlike <code>vars</code>/<code>env</code>/<code>settings</code>, a <code>metadata:</code> key at the root of a stack manifest was accepted but never applied — it silently did nothing, which is worse than a validation error.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/global-metadata-defaults#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>A stack manifest can now declare a stack-wide <code>metadata:</code> default that's deep-merged into every component's own metadata:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockTitle_JJ7b">stacks/orgs/acme/prod/_defaults.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">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">labels</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">cost-center</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> platform</span></span><br></div></code></pre></div></div>
<p>Only the fields that make sense as shared defaults are allowed here: <code>labels</code>, <code>tags</code>, <code>custom</code>, <code>enabled</code>, <code>locked</code>, and <code>terraform_workspace_pattern</code>. Component-identity fields — <code>component</code>, <code>inherits</code>, <code>type</code>, <code>name</code>, <code>terraform_workspace</code> — stay component-only, and setting one of these at the stack level is now a clear validation error instead of a silent no-op.</p>
<p>Precedence runs lowest to highest: stack-wide default → the component's <code>metadata.inherits</code> base-component chain → the component's own local <code>metadata:</code> block, which always wins:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockTitle_JJ7b">stacks/orgs/acme/prod/network.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">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">vpc</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">labels</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">cost-center</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> network</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">team </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># overrides the stack-wide default for this component</span></span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/global-metadata-defaults#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>Combine a stack-wide default with the <code>!labels</code>/<code>!tags</code> YAML functions (see <a class="" href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/tags-and-labels">Tags and Labels</a>) to feed a shared label set into every component's Terraform variables without repeating it:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockTitle_JJ7b">stacks/orgs/acme/prod/_defaults.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">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">labels</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">Namespace</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> eg</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">Environment</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> prod</span></span><br></div></code></pre></div></div>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockTitle_JJ7b">stacks/orgs/acme/prod/network.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">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">vpc</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">tags</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)">!labels</span><span class="token plain">   </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># var.tags (map) &lt;- stack-wide metadata.labels, unless this component overrides them</span></span><br></div></code></pre></div></div>
<p>The same mechanism also covers <code>enabled</code>/<code>locked</code>/<code>custom</code>/<code>terraform_workspace_pattern</code>, for cases like decommissioning an entire legacy stack without editing every component individually:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockTitle_JJ7b">stacks/orgs/acme/legacy/_defaults.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">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">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)">false</span><span class="token plain"> </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># decommission every component in this stack</span></span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/global-metadata-defaults#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>Stack-wide metadata covers the fields that behave like shared defaults today. If there's another <code>metadata</code> field you'd want to set once for a whole stack, open an issue with your use case.</p>]]></content:encoded>
            <category>Feature</category>
        </item>
        <item>
            <title><![CDATA[Split One Logical Stack Across Focused Manifests]]></title>
            <link>https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/parent-scoped-multi-file-stacks</link>
            <guid>https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/parent-scoped-multi-file-stacks</guid>
            <pubDate>Sat, 25 Jul 2026 12:00:00 GMT</pubDate>
            <description><![CDATA[Large stacks eventually turn into a shared bottleneck. Network, platform, and]]></description>
            <content:encoded><![CDATA[<p>Large stacks eventually turn into a shared bottleneck. Network, platform, and
application owners all need to contribute components, but putting every change
in one manifest makes reviews noisy and parent-level configuration easy to
accidentally share.</p>
<p>Atmos now lets multiple top-level manifests represent one logical stack while
keeping each manifest's components and parent scope independent.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/parent-scoped-multi-file-stacks#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>Teams often organize shared catalog imports and component instances by who owns
them. Before this change, splitting one logical environment across parent
manifests meant commands treated those files as separate stacks, or required a
single large manifest that mixed unrelated scope and ownership.</p>
<p>That made it difficult to divide ownership without also changing how teams
named, discovered, and operated the stack.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/parent-scoped-multi-file-stacks#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>Atmos recognizes parent manifests with the same stack identity as one logical
stack for discovery and component selection. Each manifest still resolves its
own imports, globals, and component configuration, so values from one parent
do not leak into another.</p>
<p>Within that logical stack:</p>
<ul>
<li class="">Distinct components from every parent appear together in stack discovery.</li>
<li class="">Equivalent duplicate components choose a stable, lexical canonical source.</li>
<li class="">Conflicting duplicate components remain errors with the parent manifests
identified in the diagnostic.</li>
<li class="">Inheritance stays self-contained: a base must be defined inline or explicitly
imported by the parent that uses it.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/parent-scoped-multi-file-stacks#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>Give the related parent manifests the same stack identity through <code>name</code>,
<code>name_template</code>, or <code>name_pattern</code>. For example, two manifests can use the same
template-derived environment and stage:</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"># stacks/catalog/shared.yaml</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">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">chatops-base</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">component</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> mock</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">notifications_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><br></div></code></pre></div></div>
<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"># stacks/parents/01-network.yaml</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">environment</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> dev</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">stage</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> shared</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">dns-primary</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">component</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> mock</span></span><br></div></code></pre></div></div>
<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"># stacks/parents/02-platform.yaml</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">import</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"> catalog/shared</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">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">environment</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> dev</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">stage</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> shared</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">chatops</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">component</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> mock</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"> chatops</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">base</span></span><br></div></code></pre></div></div>
<p>With a matching stack name configuration, <code>atmos describe stacks</code> reports one
logical stack, while <code>atmos describe component chatops -s dev-shared</code> retains
the platform parent's scope and resolves its base through the platform
manifest's explicit catalog import. A component defined only by the network
parent is discoverable in the logical stack, but is not an implicit inheritance
dependency of the platform parent.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/parent-scoped-multi-file-stacks#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>Try splitting a large logical stack along your team's ownership boundaries. If
you encounter an import, inheritance, or duplicate-resolution case that is not
clear, please <a href="https://github.com/cloudposse/atmos/issues" target="_blank" rel="noopener noreferrer" class="">open an issue</a> with
a minimal stack example.</p>]]></content:encoded>
            <category>Feature</category>
            <category>Enhancement</category>
        </item>
        <item>
            <title><![CDATA[Terraform state migrations with tfmigrate]]></title>
            <link>https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/terraform-tfmigrate</link>
            <guid>https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/terraform-tfmigrate</guid>
            <pubDate>Fri, 24 Jul 2026 12:00:00 GMT</pubDate>
            <description><![CDATA[Refactoring Terraform code leaves state behind. Rename a resource, or move it between root modules, and every plan shows a destroy-and-recreate for infrastructure that never changed. You can fix this by hand with terraform state mv, but that command only fixes one workspace at a time. It is easy to get wrong, and no one can review it before it runs.]]></description>
            <content:encoded><![CDATA[<p>Refactoring Terraform code leaves state behind. Rename a resource, or move it between root modules, and every plan shows a destroy-and-recreate for infrastructure that never changed. You can fix this by hand with <code>terraform state mv</code>, but that command only fixes one workspace at a time. It is easy to get wrong, and no one can review it before it runs.</p>
<p><a href="https://github.com/minamijoyo/tfmigrate" target="_blank" rel="noopener noreferrer" class=""><code>tfmigrate</code></a> turns these state changes into migration files that you store under version control. Atmos runs these files for you — manually from the CLI, or automatically from Terraform lifecycle hooks — in the same component context as <code>atmos terraform plan</code> and <code>apply</code>.</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 migrate plan s3-bucket </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-s</span><span class="token plain"> plat-ue2-dev</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos terraform migrate apply s3-bucket </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-s</span><span class="token plain"> plat-ue2-dev</span><br></div></code></pre></div></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">atmos terraform migrate</span></div><pre class="screen__b5c noPreWrap_ImkX screenLoading_abuO"><span> </span></pre><div class="controls_eyLV"><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>00:00.0<!-- --> / <!-- -->00:00.0</span></div></div>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="what-changed">What Changed<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/terraform-tfmigrate#what-changed" class="hash-link" aria-label="Direct link to What Changed" title="Direct link to What Changed" translate="no">​</a></h2>
<p>The new <code>atmos terraform migrate</code> command family adds:</p>
<ul>
<li class=""><code>atmos terraform migrate plan</code> to preview a migration.</li>
<li class=""><code>atmos terraform migrate apply</code> to apply a migration.</li>
<li class=""><code>atmos terraform migrate list</code> to inspect per-component hook and history context.</li>
<li class=""><code>kind: tfmigrate</code> hooks for running migrations from Terraform lifecycle events.</li>
<li class="">Zero-config history storage that reuses the component's Terraform backend.</li>
</ul>
<p>Before <code>tfmigrate</code> runs, Atmos performs the normal Terraform component setup.
This includes auth identity resolution, source provisioning, workdir
provisioning, generated backend and varfiles, Terraform init, and workspace
selection.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="dynamic-hooks">Dynamic Hooks<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/terraform-tfmigrate#dynamic-hooks" class="hash-link" aria-label="Direct link to Dynamic Hooks" title="Direct link to Dynamic Hooks" translate="no">​</a></h2>
<p><code>kind: tfmigrate</code> hooks default to <code>mode: dynamic</code>, so automation follows the
Terraform operation:</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">hooks</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">state-migration</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">events</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"> before.terraform.plan</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"> before.terraform.apply</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"> tfmigrate</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">mode</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> dynamic</span></span><br></div></code></pre></div></div>
<p><code>before.terraform.plan</code> runs <code>tfmigrate plan</code>. <code>before.terraform.apply</code> and
<code>before.terraform.deploy</code> run <code>tfmigrate apply</code>. Use static <code>mode: plan</code> or
<code>mode: apply</code> when a hook must always run one action.</p>
<p>Hooks run through Atmos, so they use the same identity as the Terraform
operation. If the Terraform command or component selects an Atmos auth
identity, the migration gets that same authenticated environment.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="recovering-from-skipped-releases">Recovering From Skipped Releases<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/terraform-tfmigrate#recovering-from-skipped-releases" class="hash-link" aria-label="Direct link to Recovering From Skipped Releases" title="Direct link to Recovering From Skipped Releases" translate="no">​</a></h2>
<p>Provider removals are where this bites hardest. When a component release drops
a provider configuration, every workspace that skips the intermediate release
gets stuck. The state still holds resources from the removed provider, and
Terraform refuses to plan:</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">Error: Provider configuration not present</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">To work with random_pet.legacy (orphan) its original provider configuration</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">at provider["registry.opentofu.org/hashicorp/random"].legacy is required,</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">but it has been removed.</span><br></div></code></pre></div></div>
<p>Until now, the only fix was manual, and per workspace: restore a temporary
provider override, apply, then delete the override again. Ship a migration
alongside the release instead. The hook prunes the stale state entries before
Terraform loads provider configurations, so workspaces can jump straight to
the newest release:</p>
<div class="language-hcl codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-hcl 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">migration </span><span class="token string" style="color:rgb(173, 219, 103)">"state"</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"drop_legacy_provider_state"</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 property" style="color:rgb(128, 203, 196)">actions</span><span class="token plain"> </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)">"rm random_pet.legacy"</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><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><br></div></code></pre></div></div>
<p>Note: <code>state rm</code> abandons the remote object. It does not destroy it. This is
usually what you want for provider-cleanup migrations. If you need to destroy
the object, destroy it before you upgrade, or temporarily restore the
provider configuration.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="history-mode">History Mode<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/terraform-tfmigrate#history-mode" class="hash-link" aria-label="Direct link to History Mode" title="Direct link to History Mode" translate="no">​</a></h2>
<p>For idempotent migrations in automation, use <code>tfmigrate</code> history mode:</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 migrate apply s3-bucket </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-s</span><span class="token plain"> plat-ue2-dev</span><br></div></code></pre></div></div>
<p>History mode needs no configuration by default. Atmos looks for a custom
<code>tfmigrate</code> config in four places: the hook's <code>config</code> field, the
<code>--tfmigrate-config</code> / <code>ATMOS_TFMIGRATE_CONFIG</code> flag or environment variable,
the <code>TFMIGRATE_CONFIG</code> environment variable, and a <code>.tfmigrate.hcl</code> file in
the component. If none of these exist, Atmos generates a config on the fly.</p>
<p>The generated config stores migration history in the component's own
Terraform backend. For an S3 or GCS backend, Atmos reuses the same bucket as
the state. It stores history under a key namespaced by stack, component, and
workspace, and it inherits the region, role ARN, and endpoint. For a local
backend, Atmos stores the history file beside the state file.</p>
<p>Atmos records every applied migration and never reruns it. You don't need to
set anything up.</p>
<p>To take control, provide your own config. Drop a <code>.tfmigrate.hcl</code> file in the
component, set the hook's <code>config</code> field, or pass <code>--tfmigrate-config</code> /
<code>ATMOS_TFMIGRATE_CONFIG</code>. Atmos exports stack, component, and
workspace-scoped history variables, and copies the supported Terraform
backend settings. Your custom config can then reuse the same bucket and
identity setup:</p>
<div class="language-hcl codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-hcl 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)">tfmigrate</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 property" style="color:rgb(128, 203, 196)">migration_dir</span><span class="token plain"> </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)">"./tfmigrate"</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 keyword" style="color:rgb(127, 219, 202)">history</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">    storage </span><span class="token string" style="color:rgb(173, 219, 103)">"s3"</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 property" style="color:rgb(128, 203, 196)">bucket</span><span class="token plain">   </span><span class="token punctuation" style="color:rgb(199, 146, 234)">=</span><span class="token plain"> env.ATMOS_TFMIGRATE_HISTORY_BUCKET</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 property" style="color:rgb(128, 203, 196)">key</span><span class="token plain">      </span><span class="token punctuation" style="color:rgb(199, 146, 234)">=</span><span class="token plain"> env.ATMOS_TFMIGRATE_HISTORY_KEY</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 property" style="color:rgb(128, 203, 196)">region</span><span class="token plain">   </span><span class="token punctuation" style="color:rgb(199, 146, 234)">=</span><span class="token plain"> env.ATMOS_TFMIGRATE_HISTORY_REGION</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 property" style="color:rgb(128, 203, 196)">role_arn</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">=</span><span class="token plain"> env.ATMOS_TFMIGRATE_HISTORY_ROLE_ARN</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><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><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><br></div></code></pre></div></div>
<p>The default history key is:</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">tfmigrate/&lt;stack&gt;/&lt;component&gt;/&lt;workspace&gt;/history.json</span><br></div></code></pre></div></div>
<p>That keeps multiple Atmos component instances from colliding when they share a
Terraform backend bucket.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="important-limitation">Important Limitation<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/terraform-tfmigrate#important-limitation" class="hash-link" aria-label="Direct link to Important Limitation" title="Direct link to Important Limitation" translate="no">​</a></h2>
<p>Single-file <code>tfmigrate apply path.hcl</code> is not idempotent by itself. A rerun
can fail if a state address already moved or was removed. Prefer history mode
instead. When the component's backend is S3 or GCS, the generated default
gives you durable storage automatically. With a purely local backend, make
sure the local history file survives between runs — for example, have your CI
workflow persist it.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="learn-more">Learn More<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/terraform-tfmigrate#learn-more" class="hash-link" aria-label="Direct link to Learn More" title="Direct link to Learn More" translate="no">​</a></h2>
<ul>
<li class=""><a class="" href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/terraform/migrate"><code>atmos terraform migrate</code></a></li>
<li class=""><a class="" href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/stacks/hooks">Hooks</a></li>
<li class=""><a class="" href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/components/terraform">Terraform Component Configuration</a></li>
</ul>]]></content:encoded>
            <category>Feature</category>
            <category>DX</category>
        </item>
        <item>
            <title><![CDATA[Native Pull Requests for Vendored Component Updates]]></title>
            <link>https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/component-updater-pull-requests</link>
            <guid>https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/component-updater-pull-requests</guid>
            <pubDate>Tue, 21 Jul 2026 12:00:00 GMT</pubDate>
            <description><![CDATA[Keeping vendored components current across dozens of repositories doesn't scale as a manual habit.]]></description>
            <content:encoded><![CDATA[<p>Keeping vendored components current across dozens of repositories doesn't scale as a manual habit.
Someone has to notice a new upstream release, edit the right <code>version:</code> field without breaking a
comment or a template, then commit, push, and open a pull request. That has to happen for every
component, on some kind of schedule, forever. Most teams either let it slip until something forces
an update, or bolt on a third-party GitHub Action just to automate the commit-and-PR part.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/component-updater-pull-requests#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>atmos vendor update</code> command already finds and writes newer versions locally. Turning that
into a reviewable pull request meant scripting Git branch/commit/push logic and a GitHub API client
yourself, or reaching for an external action with its own permissions model, its own config format,
and its own release cadence to track.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/component-updater-pull-requests#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>The <code>--pull-request</code> flag does the whole cycle natively: discover available updates, write them
with the same format-preserving editor <code>vendor update</code> already uses, create or reuse a branch,
commit, push, and open or update a pull request — through a provider-neutral Git registry (GitHub
today; GitLab and Bitbucket can register without any command changes).</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 vendor update --pull-request</span><br></div></code></pre></div></div>
<p>Nothing happens unless there's actually an update: no updates means no branch, no commit, no push,
no PR. Atmos fetches the base branch but never writes to it. It reuses an existing feature branch
for the same scope and pushes it fast-forward only — repeated runs update the same PR instead of
piling up duplicates.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/component-updater-pull-requests#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>Scope updates to a named group instead of updating everything at once:</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">vendor</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">update</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">groups</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">include</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 string" style="color:rgb(173, 219, 103)">"terraform/vpc"</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)">"terraform/eks/*"</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">exclude</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 string" style="color:rgb(173, 219, 103)">"terraform/eks/legacy"</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">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">pull_request</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">branch_prefix</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> atmos/component</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">updater</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">title</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)">"chore(components): update {{ .scope.name }}"</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">labels</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">component</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">update</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span></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 vendor update </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--group</span><span class="token plain"> platform --pull-request</span><br></div></code></pre></div></div>
<p>For a scheduled run, the official container image is all a workflow needs — no third-party action
performs the update, commit, push, or PR creation:</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">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 key atrule">schedule</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"> </span><span class="token key atrule">cron</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)">"17 3 * * 1"</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"></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">permissions</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">contents</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> write</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">pull-requests</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> write</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">jobs</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">update</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">runs-on</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> ubuntu</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">latest</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">image</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> ghcr.io/cloudposse/atmos</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"> vars.ATMOS_VERSION </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">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">uses</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> actions/checkout@v6</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">run</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> atmos vendor update </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">pull</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">request</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 class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> </span><span class="token key atrule">GITHUB_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.GITHUB_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 class="token punctuation" style="color:rgb(199, 146, 234)">}</span></span><br></div></code></pre></div></div>
<p>Set <code>execution.mode: worktree</code> when you'd rather the whole discover-branch-commit-push cycle ran in
an isolated checkout instead of the workflow's own working tree — useful if other steps in the same
job depend on an unmodified checkout while the update runs. In GitHub Actions, every run also
appends a summary showing scope, counts, and the resulting PR link, independent of whether an
update was found.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="triggering-downstream-workflows">Triggering Downstream Workflows<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/component-updater-pull-requests#triggering-downstream-workflows" class="hash-link" aria-label="Direct link to Triggering Downstream Workflows" title="Direct link to Triggering Downstream Workflows" translate="no">​</a></h2>
<p>The example above uses the default <code>GITHUB_TOKEN</code>. This token is fine for opening the PR, but
GitHub deliberately excludes its own default Actions token from re-triggering <code>on: pull_request</code>/
<code>on: push</code> workflows. As a result, a plan/validate workflow that's supposed to run against the new
PR won't fire.</p>
<p>Pair the Component Updater with the
<a class="" href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/auth#github-sts-atmos-pro"><code>github/sts</code></a> auth integration to get a token that
does trigger downstream Actions — a just-in-time GitHub App installation token, minted through
<a class="" href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/atmos-pro-github-sts">Atmos Pro STS</a> and exported as <code>ATMOS_PRO_GITHUB_TOKEN</code>. The
<code>--pull-request</code> flag already prefers this token over <code>GITHUB_TOKEN</code>:</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 auth </span><span class="token builtin class-name" style="color:rgb(255, 203, 139)">exec</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--identity</span><span class="token plain"> github-sts -- atmos vendor update --pull-request</span><br></div></code></pre></div></div>
<p>No other flags or config changes are required. <code>atmos auth exec</code> mints and exports the token for
the wrapped command's environment. The Component Updater's GitHub client picks it up automatically.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/component-updater-pull-requests#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>Questions about scopes, groups, or CI publishing are welcome in the
<a href="https://github.com/cloudposse/atmos" target="_blank" rel="noopener noreferrer" class="">Atmos GitHub repository</a> and the community Slack.</p>]]></content:encoded>
            <category>Feature</category>
        </item>
        <item>
            <title><![CDATA[Verify Vendored Files Never Silently Drift]]></title>
            <link>https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/vendor-lock-verify</link>
            <guid>https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/vendor-lock-verify</guid>
            <pubDate>Tue, 21 Jul 2026 12:00:00 GMT</pubDate>
            <description><![CDATA[Vendoring pulls external code into your own repository so it's reviewable, diffable, and not]]></description>
            <content:encoded><![CDATA[<p>Vendoring pulls external code into your own repository so it's reviewable, diffable, and not
subject to an upstream registry going away. But once those files land on disk, nothing has watched
them since. A teammate edits a vendored file directly to work around a bug. A pull can interrupt
partway through. CI reuses a runner's disk across jobs. Every one of these leaves your checkout
silently out of sync with what Atmos actually vendored. The first sign of trouble is usually a
broken <code>terraform plan</code> weeks later — not the moment the drift happened.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/vendor-lock-verify#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>atmos vendor pull</code> command always re-fetches everything, every time, whether or not anything
actually changed. That makes it slow to lean on as a drift check, so most teams just don't run it that
way — they trust the checkout and find out otherwise the hard way. There was also no way to answer
"does what's on disk still match what was vendored" without a network round trip, and no way to
choose how loudly a stale checkout should complain before Atmos quietly re-fetches it.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/vendor-lock-verify#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>Every <code>atmos vendor pull</code> now records a <code>vendor.lock.yaml</code> receipt for each vendored source: its
declared origin, a resolved identity, and a checksum for every file it wrote. That receipt is what
<code>atmos vendor verify</code> checks against, with zero network access:</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 vendor verify</span><br></div></code></pre></div></div>
<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">COMPONENT  PATH                              REASON</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">vpc        components/terraform/vpc/main.tf  checksum mismatch</span><br></div></code></pre></div></div>
<p>It exits non-zero the moment anything doesn't match — a missing file or a modified one — so it
drops straight into a CI gate. Add <code>--component &lt;name&gt;</code> to scope the check, or <code>--format json</code> for
machine-readable output.</p>
<p>You also get to choose how a drifted checkout behaves on the next <code>atmos vendor pull</code>, instead of
always silently re-fetching:</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">vendor</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">lock</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">enforcement</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> warn </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># silent | warn | strict</span></span><br></div></code></pre></div></div>
<ul>
<li class="">The <code>silent</code> mode re-fetches with no reporting — the behavior every <code>vendor pull</code> had before this
existed.</li>
<li class="">The <code>warn</code> mode (the default) re-fetches and prints one line naming what drifted and why.</li>
<li class="">The <code>strict</code> mode refuses to run at all until you pass <code>--refresh-lock</code>, so an unreviewed local
edit can never get silently overwritten — or silently kept — without someone noticing.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/vendor-lock-verify#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>Gate CI on drift the same way you'd gate on any other check:</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 vendor verify </span><span class="token operator" style="color:rgb(127, 219, 202)">||</span><span class="token plain"> </span><span class="token builtin class-name" style="color:rgb(255, 203, 139)">exit</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">1</span><br></div></code></pre></div></div>
<p>Override enforcement for a single invocation without touching <code>atmos.yaml</code>:</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 vendor pull --lock-enforcement</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">strict</span><br></div></code></pre></div></div>
<p>And when a source genuinely needs to move — not just recover from drift — <code>version:</code> can now be a
semver range instead of only an exact pin:</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">sources</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">component</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> vpc</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">source</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> github.com/cloudposse/terraform</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">aws</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">vpc.git</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">version</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)">"^1.0.0"</span></span><br></div></code></pre></div></div>
<p>The first <code>atmos vendor pull</code> resolves that range to a concrete tag and locks it there — every
later pull reuses the locked version with no network call at all, until an explicit
<code>atmos vendor update</code> or <code>--refresh-lock</code> re-resolves it. An exact pin like <code>version: v1.5.0</code>
behaves exactly as it always has: the manifest itself remains the single source of truth for what
gets fetched.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/vendor-lock-verify#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>Questions about lock enforcement, <code>vendor verify</code>, or version ranges are welcome in the
<a href="https://github.com/cloudposse/atmos" target="_blank" rel="noopener noreferrer" class="">Atmos GitHub repository</a> and the community Slack.</p>]]></content:encoded>
            <category>Feature</category>
        </item>
        <item>
            <title><![CDATA[Remote Build Caching for Container Builds]]></title>
            <link>https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/container-buildx-cache-and-driver</link>
            <guid>https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/container-buildx-cache-and-driver</guid>
            <pubDate>Mon, 20 Jul 2026 12:00:00 GMT</pubDate>
            <description><![CDATA[Container image builds get slower as a Dockerfile grows, and CI runners rarely keep a warm]]></description>
            <content:encoded><![CDATA[<p>Container image builds get slower as a Dockerfile grows, and CI runners rarely keep a warm
local cache between runs. Teams work around this with a handful of <code>docker/setup-buildx-action</code>
and <code>docker/build-push-action</code> steps that provision a builder and wire up a remote cache — glue
that lives outside the rest of the pipeline and has to be reproduced in every workflow that builds
an image.</p>
<p>The native <code>container</code> build step can now provision that builder and cache directly, so a build's
caching strategy lives next to the rest of its configuration instead of in separate Actions.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/container-buildx-cache-and-driver#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>A <code>docker buildx build</code> that starts cold rebuilds every layer, even when nothing meaningful
changed. Reusing a remote cache and a purpose-built builder solves this, but doing it by hand
means composing several pieces: creating a builder with the right driver, pointing it at a
registry-backed cache, and keeping all of that in sync with the rest of the build step.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/container-buildx-cache-and-driver#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p><code>action: build</code> now accepts <code>driver</code> and <code>cache</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"> build</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"> container</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"> build</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"> docker</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">engine</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> buildx</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">context</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">dockerfile</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> Dockerfile</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">tags</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"> registry.example.com/app</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain">latest</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">driver</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> docker</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">container   </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># shorthand — just the driver</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">cache</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">from</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"> registry</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">ref</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> registry.example.com/app</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain">buildcache</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">to</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"> registry</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">ref</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> registry.example.com/app</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain">buildcache</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">mode</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> max</span></span><br></div></code></pre></div></div>
<p>Atmos creates the named builder if it doesn't already exist and reuses it on later runs, so the
builder's own cache persists across builds on the same host instead of starting cold every time.
<code>driver</code> also accepts a full form when you need driver-specific options, such as pointing Buildx
at a mirrored BuildKit image to avoid Docker Hub rate limits:</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">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">driver</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"> atmos</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"> docker</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">container</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">opts</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"> mirror.gcr.io/moby/buildkit</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain">buildx</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">stable</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token number" style="color:rgb(247, 140, 108)">1</span></span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/container-buildx-cache-and-driver#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 <code>driver</code> and <code>cache</code> under an existing <code>action: build</code> step wherever you use
<code>engine: buildx</code>. If you build with <code>bake</code> instead, keep <code>cache-from</code>/<code>cache-to</code> in the bake file
itself — Bake already supports them natively — and use <code>driver</code> for builder selection either way.</p>
<p>See the <a class="" href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/workflows/steps/type/container#driver"><code>container</code> step documentation</a> for the full
field reference, including the three ways to avoid Docker Hub rate limits.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/container-buildx-cache-and-driver#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>driver</code> and <code>cache</code> in a build step and share feedback through
<a href="https://github.com/cloudposse/atmos/issues" target="_blank" rel="noopener noreferrer" class="">GitHub issues</a>.</p>]]></content:encoded>
            <category>Feature</category>
        </item>
        <item>
            <title><![CDATA[Validate Only What Changed]]></title>
            <link>https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/affected-validation</link>
            <guid>https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/affected-validation</guid>
            <pubDate>Sat, 18 Jul 2026 12:00:00 GMT</pubDate>
            <description><![CDATA[Large repositories often have validation rules that are useful but expensive or]]></description>
            <content:encoded><![CDATA[<p>Large repositories often have validation rules that are useful but expensive or
noisy to run across every file on every pull request. That makes it tempting to
skip validation exactly when a focused signal would be most helpful.</p>
<p>Atmos can now validate the files affected by a change, so pull requests get
actionable feedback without rechecking unrelated project inputs.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/affected-validation#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>Configuration schema checks, stack validation, formatting rules, and workflow
linting protect different parts of a project. Running every check over an entire
repository can obscure the result that matters to the change under review.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/affected-validation#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>Add <code>--affected</code> to the project-wide validator or to an individual validator.
Atmos compares the current worktree with the Git merge-base, including local
uncommitted and untracked files. In GitHub Actions, it reads the pull request
base SHA automatically.</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 validate </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--affected</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--format</span><span class="token plain"> rich</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos validate config </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--affected</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--base</span><span class="token plain"> origin/main</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos config validate </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--affected</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--base</span><span class="token plain"> origin/main</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos validate stacks </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--affected</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--base</span><span class="token plain"> origin/main</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos stack validate </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--affected</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--base</span><span class="token plain"> origin/main</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos validate editorconfig </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--affected</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--base</span><span class="token plain"> origin/main</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos validate ci </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--affected</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--base</span><span class="token plain"> origin/main</span><br></div></code></pre></div></div>
<p>Schema and EditorConfig checks validate changed inputs directly. Changes to a
schema or rule configuration expand validation to the relevant full set. Stack
validation runs whenever stack or Atmos configuration inputs change, preserving
import and duplicate-component checks. Workflow validation sends only changed
workflows to actionlint unless its configuration changes.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/affected-validation#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>Use the new <code>Validation (affected)</code> GitHub Actions job as a model for a project
workflow. Check out enough Git history for the merge-base, then run the command
with rich output:</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">uses</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> actions/checkout@v6</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">fetch-depth</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)">0</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">run</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> atmos validate </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">affected </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">format rich</span></span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/affected-validation#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>Try affected validation in your pull request workflow and share feedback through
<a href="https://github.com/cloudposse/atmos/issues" target="_blank" rel="noopener noreferrer" class="">GitHub issues</a>.</p>]]></content:encoded>
            <category>Feature</category>
            <category>DX</category>
        </item>
        <item>
            <title><![CDATA[Initialize an Atmos project from a proven starting point]]></title>
            <link>https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/init-real-starter-project</link>
            <guid>https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/init-real-starter-project</guid>
            <pubDate>Fri, 17 Jul 2026 12:00:00 GMT</pubDate>
            <description><![CDATA[Initializing a project should establish a useful local starting point, not leave a developer with]]></description>
            <content:encoded><![CDATA[<p>Initializing a project should establish a useful local starting point, not leave a developer with
an empty directory and a list of conventions to reconstruct. Modern development platforms provide
an initialization workflow: developers select a known-good example or template, create the project
locally, and make the next action obvious. Atmos provides that workflow for infrastructure projects.</p>
<p>The <code>atmos init</code> command initializes an Atmos project from a template chosen for the job at hand:
a minimal cloud-agnostic project, an AWS application SDLC project, or a cloud landing zone. Each
template creates the configuration, structure, and operational path appropriate to that project
rather than asking every team to assemble it from scratch.</p>
<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">atmos init a working project</span></div><pre class="screen__b5c noPreWrap_ImkX screenLoading_abuO"><span> </span></pre><div class="controls_eyLV"><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>00:00.0<!-- --> / <!-- -->00:00.0</span></div></div>
<p><a class="" href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/examples/init">View the full init example</a></p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="initialize-the-project-you-need">Initialize the Project You Need<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/init-real-starter-project#initialize-the-project-you-need" class="hash-link" aria-label="Direct link to Initialize the Project You Need" title="Direct link to Initialize the Project You Need" translate="no">​</a></h2>
<p>The <code>basic</code> template gives a new project a small, cloud-agnostic foundation with a real <code>greeting</code>
Terraform component. It creates a local file, so a developer can validate and deploy the generated
project without a cloud account, credentials, or an emulator. The point is to prove that the
initialized project works before anyone starts extending it.</p>
<p>For teams beginning an application project, the <code>aws/app</code> catalog template establishes a complete
AWS application SDLC repository with dev, staging, and production stacks, native CI, and an
emulator-proven application component. For a platform foundation, <code>aws/landing-zone</code> initializes
dev, staging, and production environments with a conventional AWS baseline for audit, KMS, SSM,
monitoring, and IAM. The catalog also includes GCP and Azure landing-zone starting points.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="a-consistent-initialization-contract">A Consistent Initialization Contract<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/init-real-starter-project#a-consistent-initialization-contract" class="hash-link" aria-label="Direct link to A Consistent Initialization Contract" title="Direct link to A Consistent Initialization Contract" translate="no">​</a></h2>
<p>An interactive invocation lets a developer choose the project template and answer only the
questions that shape it. Required answers, patterns, option lists, and boolean values are enforced
consistently whether they come from prompts, defaults, persisted values, or <code>--set</code>. The same
initialization can therefore be repeated from automation without bypassing the template’s contract.</p>
<p>Built-in templates travel with the Atmos binary. Catalog templates resolve to the source associated
with that build, so a team initializes from a known template version rather than an accidental
snapshot of a repository.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="build-your-organizations-golden-paths">Build Your Organization's Golden Paths<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/init-real-starter-project#build-your-organizations-golden-paths" class="hash-link" aria-label="Direct link to Build Your Organization's Golden Paths" title="Direct link to Build Your Organization's Golden Paths" translate="no">​</a></h2>
<p>The <code>init</code> catalog distributes proven starting points with Atmos. For organization-owned golden
paths that your platform team distributes through a catalog or Git repository, see <a class="" href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/scaffold-conditional-generation-and-hooks">the scaffolds announcement</a>.</p>
<p>See the <a class="" href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/init">Init Command Documentation</a> for the full template list.</p>]]></content:encoded>
            <category>Enhancement</category>
            <category>DX</category>
        </item>
        <item>
            <title><![CDATA[Generate Verifiable Terraform Provenance SBOMs]]></title>
            <link>https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/sbom-provenance</link>
            <guid>https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/sbom-provenance</guid>
            <pubDate>Fri, 17 Jul 2026 12:00:00 GMT</pubDate>
            <description><![CDATA[Compliance reviews often start with a deceptively simple question: what exactly is in this infrastructure release? Answering it by hand means reconciling vendored sources, provider locks, module downloads, and registry artifacts—without accidentally mistaking missing evidence for an empty dependency set. Atmos now makes that evidence visible in one SBOM while keeping coverage boundaries explicit. It also integrates with native CI to upload the SBOM as a GitHub Actions workflow artifact when enabled.]]></description>
            <content:encoded><![CDATA[<p>Compliance reviews often start with a deceptively simple question: what exactly is in this infrastructure release? Answering it by hand means reconciling vendored sources, provider locks, module downloads, and registry artifacts—without accidentally mistaking missing evidence for an empty dependency set. Atmos now makes that evidence visible in one SBOM while keeping coverage boundaries explicit. It also integrates with native CI to upload the SBOM as a GitHub Actions workflow artifact when enabled.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/sbom-provenance#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>An SBOM that quietly excludes a dependency category can create more risk than no SBOM at all. The person deciding whether an artifact is ready for compliance review needs to see gaps like these:</p>
<ul>
<li class="">A provider version without its checksum</li>
<li class="">A module selected from a mutable ref</li>
<li class="">An unavailable module graph</li>
</ul>
<p>Terraform's provider lock file, vendored source receipts, and OCI artifact digests already contain much of the evidence that infrastructure teams need. Until now, that evidence lived in separate places, and no tool could render it as a single standards-based document.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/sbom-provenance#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>Generate a provenance/build-input SBOM for Terraform-managed infrastructure:</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 sbom generate </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--format</span><span class="token plain"> cyclonedx-json </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--output</span><span class="token plain"> infra.sbom.json</span><br></div></code></pre></div></div>
<p>The first release inventories four evidence domains:</p>
<ul>
<li class="">Atmos-managed sources recorded in <code>vendor.lock.yaml</code>, including <code>vendor.yaml</code>, <code>component.yaml</code>, and mixins</li>
<li class="">OCI source artifacts pinned by their selected manifest digest</li>
<li class="">Terraform providers from <code>.terraform.lock.hcl</code>, including recorded archive checksums</li>
<li class="">Terraform modules from <code>terraform modules -json</code>, resolved to a commit, OCI digest, or content hash when possible</li>
</ul>
<p>The command emits CycloneDX JSON or SPDX JSON from the same graph. The two documents describe the same components and relationships.</p>
<h3 class="anchor anchorTargetStickyNavbar_cA1_" id="compliance-without-false-confidence">Compliance Without False Confidence<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/sbom-provenance#compliance-without-false-confidence" class="hash-link" aria-label="Direct link to Compliance Without False Confidence" title="Direct link to Compliance Without False Confidence" translate="no">​</a></h3>
<p>An SBOM is only useful when its coverage is clear. The default <code>provenance</code> mode includes coverage diagnostics for each adapter and emits the evidence that is available. It deliberately does not claim that the document represents every dependency or deployed workload in the environment.</p>
<p>For a Terraform-scoped NTIA-baseline check, use <code>--mode ntia</code> and identify the subject:</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 sbom generate </span><span class="token punctuation" style="color:rgb(199, 146, 234)">\</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--mode</span><span class="token plain"> ntia </span><span class="token punctuation" style="color:rgb(199, 146, 234)">\</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  --subject-name infra-live </span><span class="token punctuation" style="color:rgb(199, 146, 234)">\</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  --subject-version </span><span class="token string" style="color:rgb(173, 219, 103)">"</span><span class="token string variable" style="color:rgb(214, 222, 235)">$(</span><span class="token string variable function" style="color:rgb(130, 170, 255)">git</span><span class="token string variable" style="color:rgb(214, 222, 235)"> rev-parse </span><span class="token string variable parameter variable" style="color:rgb(214, 222, 235)">--short</span><span class="token string variable" style="color:rgb(214, 222, 235)"> HEAD</span><span class="token string variable" style="color:rgb(214, 222, 235)">)</span><span class="token string" style="color:rgb(173, 219, 103)">"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">\</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  --subject-supplier </span><span class="token string" style="color:rgb(173, 219, 103)">"Example, Inc."</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">\</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--format</span><span class="token plain"> spdx-json </span><span class="token punctuation" style="color:rgb(199, 146, 234)">\</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--output</span><span class="token plain"> infra-live.spdx.json</span><br></div></code></pre></div></div>
<p>NTIA mode fails when required provenance is incomplete, such as:</p>
<ul>
<li class="">Missing subject information</li>
<li class="">A provider lock without a SHA-256 archive checksum</li>
<li class="">A module without immutable resolution evidence</li>
<li class="">An unavailable module-graph interface</li>
</ul>
<p>A failed compliance-mode invocation is more useful than a document that silently leaves evidence out.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/sbom-provenance#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>Start with the default provenance mode to inspect the evidence and coverage for initialized Terraform components:</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 sbom generate </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--format</span><span class="token plain"> cyclonedx-json </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--output</span><span class="token plain"> infra.sbom.json</span><br></div></code></pre></div></div>
<p>Add <code>--include-files</code> when the exact <code>vendor.lock.yaml</code> file inventory belongs in the document:</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 sbom generate --include-files </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--output</span><span class="token plain"> infra.sbom.json</span><br></div></code></pre></div></div>
<p>The command uses the Terraform executable configured by <code>components.terraform.command</code> in each component directory. If it is unset, Atmos uses <code>terraform</code>. Module inventory currently requires Terraform 1.10 or later because it relies on the stable <code>terraform modules -json</code> interface.</p>
<p>If your project configures <code>tofu</code>, Atmos honors that choice. Atmos does not parse Terraform's internal module-installation files as a fallback. Until OpenTofu exposes an equivalent stable structured interface, Atmos marks module coverage unavailable, and NTIA mode refuses the scope.</p>
<h3 class="anchor anchorTargetStickyNavbar_cA1_" id="whats-next">What's Next<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/sbom-provenance#whats-next" class="hash-link" aria-label="Direct link to What's Next" title="Direct link to What's Next" translate="no">​</a></h3>
<p>This is the foundation for broader dependency coverage — it's not yet feature complete. The next adapters extend coverage across the other component types Atmos already supports:</p>
<ul>
<li class="">Helm and Helmfile locks</li>
<li class="">Kubernetes manifests</li>
<li class="">Typed deployed-container image discovery</li>
<li class="">OCI SBOM attestations or scanner integration for image contents</li>
<li class="">OpenTofu module graphs</li>
</ul>
<p>The shared graph and coverage contract mean those additions extend both CycloneDX and SPDX consistently.</p>
<p>Read the full <a class="" href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/sbom/usage">SBOM command reference</a> and the <a href="https://github.com/cloudposse/atmos/blob/main/docs/prd/sbom-provenance.md" target="_blank" rel="noopener noreferrer" class="">provenance design</a>.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/sbom-provenance#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>The initial release is experimental. Questions about the evidence model, new adapters, or compliance workflows are welcome in the <a href="https://github.com/cloudposse/atmos" target="_blank" rel="noopener noreferrer" class="">Atmos GitHub repository</a> and the community Slack.</p>]]></content:encoded>
            <category>Feature</category>
            <category>Experimental</category>
        </item>
        <item>
            <title><![CDATA[Scaffolds turn your golden paths into a platform product]]></title>
            <link>https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/scaffold-conditional-generation-and-hooks</link>
            <guid>https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/scaffold-conditional-generation-and-hooks</guid>
            <pubDate>Fri, 17 Jul 2026 12:00:00 GMT</pubDate>
            <description><![CDATA[Platform teams build golden paths so application teams can begin with the right architecture,]]></description>
            <content:encoded><![CDATA[<p>Platform teams build golden paths so application teams can begin with the right architecture,
guardrails, and operational conventions. A GitHub template repository is an excellent way to
distribute that starting tree, but its job ends at the copy. It cannot ask project-specific
questions, apply a policy to CI-supplied answers, tailor the file set, or evolve the template
without every team manually reconciling a fork.</p>
<p>Atmos scaffolds turn a golden path into an executable contract. Use a local template, register one
in <code>atmos.yaml</code>, or point to a Git repository—including a GitHub template repository—and let the
same template guide developers, automate CI, and evolve with the platform.</p>
<p>Creation is only day one. Golden paths accumulate improvements after projects have adopted them:
updated CI conventions, guardrails, shared configuration, and boilerplate. Atmos scaffolds include
an optimistic three-way merge process so a project can take those upstream improvements without
blindly replacing the custom work that happened after initialization.</p>
<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">atmos scaffold golden path</span></div><pre class="screen__b5c noPreWrap_ImkX screenLoading_abuO"><span> </span></pre><div class="controls_eyLV"><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>00:00.0<!-- --> / <!-- -->00:00.0</span></div></div>
<p><a class="" href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/examples/scaffolding">View the full scaffolding example</a></p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="from-repository-copy-to-golden-path">From Repository Copy to Golden Path<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/scaffold-conditional-generation-and-hooks#from-repository-copy-to-golden-path" class="hash-link" aria-label="Direct link to From Repository Copy to Golden Path" title="Direct link to From Repository Copy to Golden Path" translate="no">​</a></h2>
<p>The usual alternative is either a generic template that every team must customize by hand or a
matrix of near-duplicate templates for every language, environment, compliance rule, and deployment
option. The first creates drift. The second makes the platform team responsible for maintaining an
ever-growing catalog of almost-the-same repositories.</p>
<p>A scaffold keeps one template and makes it adapt to the project being created. The platform team
owns the contract; the consuming team supplies only the choices that belong to its project.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="what-the-contract-enforces">What the Contract Enforces<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/scaffold-conditional-generation-and-hooks#what-the-contract-enforces" class="hash-link" aria-label="Direct link to What the Contract Enforces" title="Direct link to What the Contract Enforces" translate="no">​</a></h2>
<ul>
<li class=""><strong>Validated inputs.</strong> Required fields, patterns, select and multiselect options, and boolean
values are validated for interactive answers, defaults, presets, persisted values, and <code>--set</code>
flags. Platform policy does not disappear when a template runs in CI.</li>
<li class=""><strong>Conditional prompts and files.</strong> A field or file can use <code>when:</code> and the answers collected so
far. A template can ask for a vendored component version only when vendoring is enabled, then
generate the corresponding manifest only in that case.</li>
<li class=""><strong>Lifecycle hooks.</strong> Templates can run declared work before or after generation—formatting,
validation, or setup—with the same condition engine used by Atmos workflows and CI hooks. Teams
can use <code>--skip-hooks</code> as an explicit per-invocation escape hatch.</li>
<li class=""><strong>Day-two updates.</strong> The <code>atmos scaffold generate --update</code> command re-runs a template against
an existing project and performs an optimistic three-way merge. It is a strong fit for shared
boilerplate that changes infrequently across many projects: non-overlapping improvements can be
carried forward, while real conflicts stay visible instead of silently overwriting local work.
The <code>--merge-strategy</code> option selects manual, ours, or theirs conflict handling.</li>
</ul>
<p>Both <code>when:</code> forms use the condition language shared by Atmos workflows and CI hooks. The <code>answers</code>
variable exposes the values collected so far, allowing a golden path to express its decisions once
rather than encode them in a pile of repository variants.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="keep-github-templates-add-a-platform-contract">Keep GitHub Templates, Add a Platform Contract<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/scaffold-conditional-generation-and-hooks#keep-github-templates-add-a-platform-contract" class="hash-link" aria-label="Direct link to Keep GitHub Templates, Add a Platform Contract" title="Direct link to Keep GitHub Templates, Add a Platform Contract" translate="no">​</a></h2>
<p>GitHub template repositories remain a useful ownership and discovery mechanism. Atmos adds the
behavior they intentionally do not provide: typed choices, conditional generation, hooks, and a
safe path for bringing template improvements back to an existing project. A remote source can be
pinned to a branch, tag, or commit with <code>--ref</code>, so platform teams can make a deliberate release
available instead of distributing an accidental snapshot.</p>
<p>See the <a class="" href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/scaffold/generate">Scaffold Command Documentation</a> for the field, hook,
remote-source, and update reference.</p>]]></content:encoded>
            <category>Feature</category>
            <category>DX</category>
        </item>
        <item>
            <title><![CDATA[Toolchain proxies install only the commands you use]]></title>
            <link>https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/toolchain-proxies</link>
            <guid>https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/toolchain-proxies</guid>
            <pubDate>Fri, 17 Jul 2026 12:00:00 GMT</pubDate>
            <description><![CDATA[Installing every tool a repository might eventually need makes project setup slow and wasteful.]]></description>
            <content:encoded><![CDATA[<p>Installing every tool a repository might eventually need makes project setup slow and wasteful.
Atmos toolchain proxies provide on-demand, just-in-time installation instead: invoking a configured
command resolves its pinned version and installs that binary only when it is first needed. The first
invocation pays the download-and-prepare cost; later invocations reuse the installed release.</p>
<p>Proxies also make subcommands first-class executable names. A command-named link points back to
Atmos; when it is invoked, Atmos reads the executed name, finds its proxy configuration, and runs
the configured tool with its prefix arguments and the caller’s arguments. A multicall tool such as
uutils/coreutils can therefore expose <code>coreutils ls</code> as the normal <code>ls</code> command—without shell
aliases, copied shims, or a different invocation in every repository.</p>
<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">atmos toolchain proxies</span></div><pre class="screen__b5c noPreWrap_ImkX screenLoading_abuO"><span> </span></pre><div class="controls_eyLV"><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>00:00.0<!-- --> / <!-- -->00:00.0</span></div></div>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="install-on-demand-keep-versions-pinned">Install on Demand, Keep Versions Pinned<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/toolchain-proxies#install-on-demand-keep-versions-pinned" class="hash-link" aria-label="Direct link to Install on Demand, Keep Versions Pinned" title="Direct link to Install on Demand, Keep Versions Pinned" translate="no">​</a></h2>
<p>An alias resolves the package name, and a proxy maps the familiar command to the package and any
prefix arguments it needs:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockTitle_JJ7b">atmos.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">toolchain</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">aliases</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">coreutils</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> uutils/coreutils</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">proxies</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">ls</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">tool</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> coreutils</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">args</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">ls</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span></span><br></div></code></pre></div></div>
<div class="language-text codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockTitle_JJ7b">.tool-versions</div><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">coreutils 0.9.0</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-started">Get Started<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/toolchain-proxies#get-started" class="hash-link" aria-label="Direct link to Get Started" title="Direct link to Get Started" translate="no">​</a></h2>
<p>Activate every configured proxy in the current Bash or Zsh session with one command:</p>
<div class="language-sh codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-sh 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)">eval</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)">$(</span><span class="token string variable" style="color:rgb(214, 222, 235)">atmos toolchain </span><span class="token string variable function" style="color:rgb(130, 170, 255)">env</span><span class="token string variable" style="color:rgb(214, 222, 235)">)</span><span class="token string" style="color:rgb(173, 219, 103)">"</span><br></div></code></pre></div></div>
<p>The normal <code>ls</code> command now invokes the <code>ls</code> proxy, which resolves to the pinned <code>coreutils ls</code>
implementation. On its first invocation, the proxy installs that version if it is not already
available, then runs it with the supplied arguments. Later invocations reuse the installed binary.</p>
<p>For an intentionally eager setup—for example, a CI image or an offline preparation step—install
every pinned tool in <code>.tool-versions</code> before activating the environment:</p>
<div class="language-sh codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-sh 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 </span><span class="token function" style="color:rgb(130, 170, 255)">install</span><span class="token plain"></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)">eval</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)">$(</span><span class="token string variable" style="color:rgb(214, 222, 235)">atmos toolchain </span><span class="token string variable function" style="color:rgb(130, 170, 255)">env</span><span class="token string variable" style="color:rgb(214, 222, 235)">)</span><span class="token string" style="color:rgb(173, 219, 103)">"</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="promote-a-subcommand-to-a-command">Promote a Subcommand to a Command<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/toolchain-proxies#promote-a-subcommand-to-a-command" class="hash-link" aria-label="Direct link to Promote a Subcommand to a Command" title="Direct link to Promote a Subcommand to a Command" translate="no">​</a></h2>
<p>The same on-demand mechanism is useful when a package exposes many operations through one binary.
The <code>args</code> list supplies the subcommand or default flags, while the proxy name becomes the command
that developers and automation invoke. This turns a useful part of a larger tool into a normal,
version-pinned command without a wrapper script.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="useful-beyond-an-interactive-shell">Useful Beyond an Interactive Shell<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/toolchain-proxies#useful-beyond-an-interactive-shell" class="hash-link" aria-label="Direct link to Useful Beyond an Interactive Shell" title="Direct link to Useful Beyond an Interactive Shell" translate="no">​</a></h2>
<p>Atmos prepares the proxy environment for built-in command runners, workflows, hooks, components,
and custom commands. A project can therefore use the familiar command name in its automation while
retaining the tool version and source in version control. Developers can opt into the same proxy
directory in their terminal without modifying the system command globally.</p>
<p>The boundary is deliberate: a proxy is available only to Atmos child processes or to a shell that
has explicitly activated the toolchain environment. It never replaces the system <code>ls</code> command for
the rest of the machine.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="portable-by-design">Portable by Design<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/toolchain-proxies#portable-by-design" class="hash-link" aria-label="Direct link to Portable by Design" title="Direct link to Portable by Design" translate="no">​</a></h2>
<p>Atmos creates symbolic links on Unix-like systems and executable hard links on Windows, avoiding a
Windows symlink-privilege requirement. Proxy activation also carries the configuration context
across directory changes, so the selected toolchain remains associated with the project that
declared it.</p>
<p>See <a class="" href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/toolchain/proxies">Toolchain Proxies</a> for the configuration reference,
platform details, and troubleshooting guidance.</p>]]></content:encoded>
            <category>Feature</category>
            <category>DX</category>
        </item>
        <item>
            <title><![CDATA[Azure Blob Storage Support for !terraform.state Function]]></title>
            <link>https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/azure-blob-terraform-state-support</link>
            <guid>https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/azure-blob-terraform-state-support</guid>
            <pubDate>Thu, 16 Jul 2026 12:00:00 GMT</pubDate>
            <description><![CDATA[Atmos now supports Azure Blob Storage backends in the !terraform.state YAML function. Read Terraform outputs directly from Azure-backed state files without initializing Terraform—bringing the same blazing-fast performance to Azure that S3 users already enjoy.]]></description>
            <content:encoded><![CDATA[<p>Atmos now supports Azure Blob Storage backends in the <code>!terraform.state</code> YAML function. Read Terraform outputs directly from Azure-backed state files without initializing Terraform—bringing the same blazing-fast performance to Azure that S3 users already enjoy.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="whats-new">What's New<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/azure-blob-terraform-state-support#whats-new" class="hash-link" aria-label="Direct link to What's New" title="Direct link to What's New" translate="no">​</a></h2>
<p>The <code>!terraform.state</code> YAML function now supports <strong>Azure Blob Storage (azurerm)</strong> backends, joining existing support for S3 and local backends. This means you can retrieve Terraform outputs from Azure-backed state files at lightning speed—without the overhead of Terraform initialization.</p>
<h3 class="anchor anchorTargetStickyNavbar_cA1_" id="why-this-matters">Why This Matters<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/azure-blob-terraform-state-support#why-this-matters" class="hash-link" aria-label="Direct link to Why This Matters" title="Direct link to Why This Matters" translate="no">​</a></h3>
<p>Before this feature, if you were using Azure Blob Storage as your Terraform backend, you had two options for reading remote state:</p>
<ol>
<li class=""><strong><code>!terraform.output</code></strong> - Slow but reliable. Requires full Terraform initialization, provider downloads, and varfile generation.</li>
<li class=""><strong><code>!store</code></strong> - Fast but requires extra setup. You had to manually configure external secret stores.</li>
</ol>
<p>Now you can use <strong><code>!terraform.state</code></strong> with Azure backends—getting <strong>10-100x faster performance</strong> compared to <code>!terraform.output</code> by reading directly from blob storage.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-it-works">How It Works<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/azure-blob-terraform-state-support#how-it-works" class="hash-link" aria-label="Direct link to How It Works" title="Direct link to How It Works" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_cA1_" id="backend-configuration">Backend Configuration<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/azure-blob-terraform-state-support#backend-configuration" class="hash-link" aria-label="Direct link to Backend Configuration" title="Direct link to Backend Configuration" translate="no">​</a></h3>
<p>Configure your Terraform component with an <code>azurerm</code> backend:</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">vpc</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">backend_type</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> azurerm</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">backend</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">azurerm</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">storage_account_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)">"mystorageaccount"</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_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)">"tfstate"</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">key</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)">"vpc.terraform.tfstate"</span></span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_cA1_" id="reading-state">Reading State<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/azure-blob-terraform-state-support#reading-state" class="hash-link" aria-label="Direct link to Reading State" title="Direct link to Reading State" translate="no">​</a></h3>
<p>Use the <code>!terraform.state</code> function to read outputs:</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">eks-cluster</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"># Get vpc_id output from vpc component in current stack</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">vpc_id</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)">!terraform.state</span><span class="token plain"> vpc vpc_id</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"># Get private subnet IDs</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">subnet_ids</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)">!terraform.state</span><span class="token plain"> vpc private_subnet_ids</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"># Get first subnet using YQ expression</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">subnet_id</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)">!terraform.state</span><span class="token plain"> vpc .private_subnet_ids</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token number" style="color:rgb(247, 140, 108)">0</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span></span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_cA1_" id="cross-stack-references">Cross-Stack References<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/azure-blob-terraform-state-support#cross-stack-references" class="hash-link" aria-label="Direct link to Cross-Stack References" title="Direct link to Cross-Stack References" translate="no">​</a></h3>
<p>Reference components from different stacks:</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">tgw</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"># Get VPC ID from production stack</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">vpc_id</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)">!terraform.state</span><span class="token plain"> vpc plat</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">ue2</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">prod vpc_id</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"># Use template for dynamic stack names</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">vpc_id</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)">!terraform.state</span><span class="token plain"> vpc </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"> printf "net</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">%s</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">%s" .vars.environment .vars.stage </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"> vpc_id</span></span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="authentication">Authentication<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/azure-blob-terraform-state-support#authentication" class="hash-link" aria-label="Direct link to Authentication" title="Direct link to Authentication" translate="no">​</a></h2>
<p>The Azure Blob Storage integration uses <strong>Azure DefaultAzureCredential</strong>, which supports multiple authentication methods automatically:</p>
<ol>
<li class=""><strong>Environment variables</strong> - <code>AZURE_TENANT_ID</code>, <code>AZURE_CLIENT_ID</code>, <code>AZURE_CLIENT_SECRET</code></li>
<li class=""><strong>Managed Identity</strong> - When running in Azure (AKS, VMs, Functions)</li>
<li class=""><strong>Azure CLI credentials</strong> - <code>az login</code></li>
<li class=""><strong>Visual Studio Code credentials</strong> - Authenticated VS Code sessions</li>
</ol>
<p>No additional configuration needed—just authenticate using your preferred method.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="workspace-handling">Workspace Handling<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/azure-blob-terraform-state-support#workspace-handling" class="hash-link" aria-label="Direct link to Workspace Handling" title="Direct link to Workspace Handling" translate="no">​</a></h2>
<p>Azure Blob Storage uses a specific naming convention for workspaces:</p>
<ul>
<li class=""><strong>Default workspace</strong>: Uses the key as-is (e.g., <code>terraform.tfstate</code>)</li>
<li class=""><strong>Non-default workspaces</strong>: Appends workspace as suffix (e.g., <code>terraform.tfstateenv:dev</code>)</li>
</ul>
<p>Atmos handles this automatically—you don't need to worry about the naming convention.</p>
<h3 class="anchor anchorTargetStickyNavbar_cA1_" id="example">Example<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/azure-blob-terraform-state-support#example" class="hash-link" aria-label="Direct link to Example" title="Direct link to Example" translate="no">​</a></h3>
<p>If you have:</p>
<ul>
<li class="">Key: <code>apimanagement.terraform.tfstate</code></li>
<li class="">Workspace: <code>dev-wus3-apimanagement-be</code></li>
</ul>
<p>Atmos will look for: <code>apimanagement.terraform.tfstateenv:dev-wus3-apimanagement-be</code></p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="performance-benefits">Performance Benefits<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/azure-blob-terraform-state-support#performance-benefits" class="hash-link" aria-label="Direct link to Performance Benefits" title="Direct link to Performance Benefits" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_cA1_" id="before-using-terraformoutput">Before: Using <code>!terraform.output</code><a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/azure-blob-terraform-state-support#before-using-terraformoutput" class="hash-link" aria-label="Direct link to before-using-terraformoutput" title="Direct link to before-using-terraformoutput" translate="no">​</a></h3>
<div class="language-bash codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-bash 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">$ </span><span class="token function" style="color:rgb(130, 170, 255)">time</span><span class="token plain"> atmos terraform plan eks-cluster </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-s</span><span class="token plain"> plat-ue2-dev</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Must initialize Terraform for each dependency</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">Initializing vpc component</span><span class="token punctuation" style="color:rgb(199, 146, 234)">..</span><span class="token plain">.</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">Downloading providers</span><span class="token punctuation" style="color:rgb(199, 146, 234)">..</span><span class="token plain">.</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">Generating backend config</span><span class="token punctuation" style="color:rgb(199, 146, 234)">..</span><span class="token plain">.</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">Generating varfiles</span><span class="token punctuation" style="color:rgb(199, 146, 234)">..</span><span class="token plain">.</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">Reading outputs</span><span class="token punctuation" style="color:rgb(199, 146, 234)">..</span><span class="token plain">.</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">real    2m34.521s</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_cA1_" id="after-using-terraformstate">After: Using <code>!terraform.state</code><a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/azure-blob-terraform-state-support#after-using-terraformstate" class="hash-link" aria-label="Direct link to after-using-terraformstate" title="Direct link to after-using-terraformstate" translate="no">​</a></h3>
<div class="language-bash codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-bash 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">$ </span><span class="token function" style="color:rgb(130, 170, 255)">time</span><span class="token plain"> atmos terraform plan eks-cluster </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-s</span><span class="token plain"> plat-ue2-dev</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Direct blob storage access</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">Reading state from Azure Blob Storage</span><span class="token punctuation" style="color:rgb(199, 146, 234)">..</span><span class="token plain">.</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">real    0m3.142s</span><br></div></code></pre></div></div>
<p><strong>~50x faster</strong> in this example—and the speedup grows with infrastructure complexity.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="advanced-features">Advanced Features<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/azure-blob-terraform-state-support#advanced-features" class="hash-link" aria-label="Direct link to Advanced Features" title="Direct link to Advanced Features" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_cA1_" id="yq-expressions">YQ Expressions<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/azure-blob-terraform-state-support#yq-expressions" class="hash-link" aria-label="Direct link to YQ Expressions" title="Direct link to YQ Expressions" translate="no">​</a></h3>
<p>Use YQ expressions for complex data extraction:</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 comment" style="color:rgb(99, 119, 119);font-style:italic"># Get nested map values</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_endpoint</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)">!terraform.state</span><span class="token plain"> database .config_map.endpoint</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"># String concatenation</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">jdbc_url</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)">!terraform.state</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'postgres .master_hostname | "jdbc:postgresql://" + . + ":5432/events"'</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"># Default values for unprovisioned components</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">username</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)">!terraform.state</span><span class="token plain"> config .username // "default</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">user"</span></span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_cA1_" id="caching">Caching<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/azure-blob-terraform-state-support#caching" class="hash-link" aria-label="Direct link to Caching" title="Direct link to Caching" translate="no">​</a></h3>
<p>Results are cached in memory per CLI execution:</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 comment" style="color:rgb(99, 119, 119);font-style:italic"># All three calls use the same cached result</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">sg_id_1</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)">!terraform.state</span><span class="token plain"> vpc security_group_id</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">sg_id_2</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)">!terraform.state</span><span class="token plain"> vpc security_group_id</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">sg_id_3</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)">!terraform.state</span><span class="token plain"> vpc </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"> .stack </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"> security_group_id</span></span><br></div></code></pre></div></div>
<p>The first call reads from Azure; subsequent calls return cached data instantly.</p>
<h3 class="anchor anchorTargetStickyNavbar_cA1_" id="error-handling">Error Handling<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/azure-blob-terraform-state-support#error-handling" class="hash-link" aria-label="Direct link to Error Handling" title="Direct link to Error Handling" translate="no">​</a></h3>
<ul>
<li class=""><strong>Blob not found (404)</strong>: Returns <code>null</code> (component not provisioned yet)</li>
<li class=""><strong>Permission denied (403)</strong>: Returns clear error message</li>
<li class=""><strong>Network errors</strong>: Automatically retries up to 2 times with exponential backoff</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="technical-details">Technical Details<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/azure-blob-terraform-state-support#technical-details" class="hash-link" aria-label="Direct link to Technical Details" title="Direct link to Technical Details" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_cA1_" id="implementation-highlights">Implementation Highlights<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/azure-blob-terraform-state-support#implementation-highlights" class="hash-link" aria-label="Direct link to Implementation Highlights" title="Direct link to Implementation Highlights" translate="no">​</a></h3>
<ul>
<li class=""><strong>Azure SDK for Go</strong> - Uses official <code>github.com/Azure/azure-sdk-for-go/sdk/storage/azblob</code> package</li>
<li class=""><strong>Client caching</strong> - Azure Blob clients are cached per storage account/container</li>
<li class=""><strong>Retry logic</strong> - Automatic retry with exponential backoff for transient failures</li>
<li class=""><strong>Nil safety</strong> - Robust error handling prevents panics</li>
<li class=""><strong>Test coverage</strong> - Comprehensive unit tests with mocked Azure SDK</li>
<li class=""><strong>Cross-platform</strong> - Works on Linux, macOS, and Windows</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_cA1_" id="backend-configuration-options">Backend Configuration Options<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/azure-blob-terraform-state-support#backend-configuration-options" class="hash-link" aria-label="Direct link to Backend Configuration Options" title="Direct link to Backend Configuration Options" translate="no">​</a></h3>
<p>All standard Azure backend options are supported:</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">backend</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">azurerm</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">storage_account_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)">"mystorageaccount"</span><span class="token plain">  </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Required</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_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)">"tfstate"</span><span class="token plain">                  </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Required</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">key</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)">"terraform.tfstate"</span><span class="token plain">                   </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Optional (default: terraform.tfstate)</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"># Authentication happens via DefaultAzureCredential</span></span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="migration-guide">Migration Guide<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/azure-blob-terraform-state-support#migration-guide" class="hash-link" aria-label="Direct link to Migration Guide" title="Direct link to Migration Guide" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_cA1_" id="from-terraformoutput-to-terraformstate">From <code>!terraform.output</code> to <code>!terraform.state</code><a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/azure-blob-terraform-state-support#from-terraformoutput-to-terraformstate" class="hash-link" aria-label="Direct link to from-terraformoutput-to-terraformstate" title="Direct link to from-terraformoutput-to-terraformstate" translate="no">​</a></h3>
<p>The syntax is identical—just replace <code>!terraform.output</code> with <code>!terraform.state</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 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">vpc_id</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)">!terraform.output</span><span class="token plain"> vpc vpc_id</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">vpc_id</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)">!terraform.state</span><span class="token plain"> vpc vpc_id</span></span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_cA1_" id="from-store-to-terraformstate">From <code>!store</code> to <code>!terraform.state</code><a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/azure-blob-terraform-state-support#from-store-to-terraformstate" class="hash-link" aria-label="Direct link to from-store-to-terraformstate" title="Direct link to from-store-to-terraformstate" translate="no">​</a></h3>
<p>Simplify your configuration by removing store setup:</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: Required store configuration</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">vpc_id</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)">!store</span><span class="token plain"> azurekeyvault plat</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">ue2</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">dev vpc vpc_id</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: Direct state access</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">vpc_id</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)">!terraform.state</span><span class="token plain"> vpc vpc_id</span></span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="examples">Examples<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/azure-blob-terraform-state-support#examples" class="hash-link" aria-label="Direct link to Examples" title="Direct link to Examples" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_cA1_" id="basic-usage">Basic Usage<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/azure-blob-terraform-state-support#basic-usage" class="hash-link" aria-label="Direct link to Basic Usage" title="Direct link to Basic Usage" translate="no">​</a></h3>
<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">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"># String output</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">security_group_id</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)">!terraform.state</span><span class="token plain"> security</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">group id</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"># List output</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">subnet_ids</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)">!terraform.state</span><span class="token plain"> vpc private_subnet_ids</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"># Map output</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">config</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)">!terraform.state</span><span class="token plain"> config config_map</span></span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_cA1_" id="cross-region-references">Cross-Region References<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/azure-blob-terraform-state-support#cross-region-references" class="hash-link" aria-label="Direct link to Cross-Region References" title="Direct link to Cross-Region References" translate="no">​</a></h3>
<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">replication</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"># Reference component from different region</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">primary_db</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)">!terraform.state</span><span class="token plain"> database </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"> printf "%s</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">use1</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">%s" .vars.tenant .vars.stage </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"> endpoint</span></span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_cA1_" id="disaster-recovery-scenarios">Disaster Recovery Scenarios<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/azure-blob-terraform-state-support#disaster-recovery-scenarios" class="hash-link" aria-label="Direct link to Disaster Recovery Scenarios" title="Direct link to Disaster Recovery Scenarios" translate="no">​</a></h3>
<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">failover</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"># Primary region</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">primary_vpc</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)">!terraform.state</span><span class="token plain"> vpc plat</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">ue2</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">prod vpc_id</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"># DR region with default fallback</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">dr_vpc</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)">!terraform.state</span><span class="token plain"> vpc plat</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">uw2</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">prod .vpc_id // "vpc</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">mock</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">dr"</span></span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="considerations">Considerations<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/azure-blob-terraform-state-support#considerations" class="hash-link" aria-label="Direct link to Considerations" title="Direct link to Considerations" translate="no">​</a></h2>
<ul>
<li class=""><strong>Secrets exposure</strong>: Using <code>!terraform.state</code> with secrets will expose them in <code>atmos describe</code> output</li>
<li class=""><strong>Permission scoping</strong>: Ensure your Azure credentials have access to all referenced storage accounts</li>
<li class=""><strong>Cross-region access</strong>: Consider latency when reading state across regions</li>
<li class=""><strong>Cold starts</strong>: Components not yet provisioned return <code>null</code> (use YQ default values to handle this)</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="try-it-now">Try It Now<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/azure-blob-terraform-state-support#try-it-now" class="hash-link" aria-label="Direct link to Try It Now" title="Direct link to Try It Now" translate="no">​</a></h2>
<p>Upgrade to the latest Atmos release and start using Azure Blob Storage backends:</p>
<div class="language-bash codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-bash codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A"><div class="token-line" style="color:#d6deeb"><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Check your version</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos version</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Describe a component using Azure backend</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos describe component vpc </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-s</span><span class="token plain"> plat-ue2-dev</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Use !terraform.state in your stack configs</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># (See examples above)</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="documentation">Documentation<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/azure-blob-terraform-state-support#documentation" class="hash-link" aria-label="Direct link to Documentation" title="Direct link to Documentation" translate="no">​</a></h2>
<ul>
<li class=""><strong><a class="" href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/functions/yaml/terraform.state">!terraform.state Function Reference</a></strong> - Complete usage documentation</li>
<li class=""><strong><a class="" href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/components/terraform/backends">Terraform Backends</a></strong> - Backend configuration guide</li>
<li class=""><strong><a class="" href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/stacks/remote-state">Remote State</a></strong> - Data sharing patterns</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/azure-blob-terraform-state-support#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>We're building Atmos in the open and welcome your feedback:</p>
<ul>
<li class="">💬 <strong>Discuss</strong> - Share thoughts in <a href="https://github.com/orgs/cloudposse/discussions" target="_blank" rel="noopener noreferrer" class="">GitHub Discussions</a>.</li>
<li class="">🐛 <strong>Report Issues</strong> - Found a bug? <a href="https://github.com/cloudposse/atmos/issues" target="_blank" rel="noopener noreferrer" class="">Open an issue</a>.</li>
<li class="">🚀 <strong>Contribute</strong> - Want to add features? Review our <a href="https://atmos.tools/community/contributing" target="_blank" rel="noopener noreferrer" class="">contribution guide</a>.</li>
</ul>
<hr>
<p><strong>Next up</strong>: Google Cloud Storage (GCS) backend support for <code>!terraform.state</code>. Stay tuned!</p>]]></content:encoded>
            <category>Feature</category>
        </item>
        <item>
            <title><![CDATA[Validate GitHub Actions Workflows with Atmos]]></title>
            <link>https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/ci-workflow-validation</link>
            <guid>https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/ci-workflow-validation</guid>
            <pubDate>Thu, 16 Jul 2026 12:00:00 GMT</pubDate>
            <description><![CDATA[A workflow can be valid YAML and still fail only after GitHub Actions tries to run it: a]]></description>
            <content:encoded><![CDATA[<p>A workflow can be valid YAML and still fail only after GitHub Actions tries to run it: a
misspelled trigger filter, an invalid expression, or an action reference that does not make
sense in context. Those failures are slow to discover and usually arrive after a push.</p>
<p>Atmos now includes GitHub Actions workflow validation as an experimental native-CI command. Run
it from your workstation or in the workflow that it checks:</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 ci validate</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Equivalent validation-oriented alias</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos validate ci</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="validate-before-the-push">Validate Before the Push<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/ci-workflow-validation#validate-before-the-push" class="hash-link" aria-label="Direct link to Validate Before the Push" title="Direct link to Validate Before the Push" translate="no">​</a></h2>
<p>With no arguments, <code>atmos ci validate</code> recursively checks every <code>.yml</code> and
<code>.yaml</code> file in the current working directory's <code>.github/workflows</code>. It uses
the built-in <a href="https://github.com/rhysd/actionlint" target="_blank" rel="noopener noreferrer" class="">actionlint</a> integration, so the linting
capability ships with Atmos rather than requiring a separately installed binary.</p>
<p>A successful run gives a compact confirmation:</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">✓ Validated 3 GitHub Actions workflow file(s) in .github/workflows.</span><br></div></code></pre></div></div>
<p>Findings include the workflow path, line, column, and actionlint rule. They fail the command,
which makes validation suitable for both a pre-push check and a CI gate.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="check-a-fixture-or-another-directory">Check a Fixture or Another Directory<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/ci-workflow-validation#check-a-fixture-or-another-directory" class="hash-link" aria-label="Direct link to Check a Fixture or Another Directory" title="Direct link to Check a Fixture or Another Directory" translate="no">​</a></h2>
<p>Sometimes the workflows you want to validate do not live in the current directory's default
location — for example, when testing generated workflows or fixtures. Use
<code>--workflow-path</code> to point at that directory. Atmos recursively finds workflow YAML
beneath it:</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 ci validate --workflow-path tests/fixtures/scenarios/invalid-github-actions-workflows/.github/workflows</span><br></div></code></pre></div></div>
<p>That repository fixture intentionally uses <code>branch</code> instead of <code>branches</code>
in a <code>push</code> trigger. The command reports the line and exits with status 1, making it a
quick end-to-end smoke test of the feature. You can also select specific files directly:</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 ci validate .github/workflows/plan.yml .github/workflows/apply.yml</span><br></div></code></pre></div></div>
<p><code>--workflow-path</code> and explicit workflow-file arguments are intentionally separate
selectors and cannot be combined. This keeps the validation scope unambiguous.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="put-it-in-github-actions">Put It in GitHub Actions<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/ci-workflow-validation#put-it-in-github-actions" class="hash-link" aria-label="Direct link to Put It in GitHub Actions" title="Direct link to Put It in GitHub Actions" translate="no">​</a></h2>
<p>Add a validation step after checkout:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockTitle_JJ7b">.github/workflows/validate.yml</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">name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> Validate workflows</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">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 key atrule">pull_request</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" 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">jobs</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">validate</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">runs-on</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> ubuntu</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">latest</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">uses</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> actions/checkout@v6</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">uses</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> cloudposse/github</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">action</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">setup</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">atmos@v2</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">run</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> atmos ci validate</span></span><br></div></code></pre></div></div>
<p>When native CI is enabled, Atmos turns findings into line-anchored GitHub Actions annotations:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockTitle_JJ7b">atmos.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">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><br></div></code></pre></div></div>
<p>Annotations are enabled by default once <code>ci.enabled</code> is true; set
<code>ci.annotations.enabled: false</code> to suppress them. Outside GitHub Actions, the same
command has no provider side effects and simply renders its diagnostics.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="sarif-is-explicit">SARIF Is Explicit<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/ci-workflow-validation#sarif-is-explicit" class="hash-link" aria-label="Direct link to SARIF Is Explicit" title="Direct link to SARIF Is Explicit" translate="no">​</a></h2>
<p>For a separate Code Scanning upload or an artifact, request SARIF explicitly:</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 ci validate </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">sarif </span><span class="token operator" style="color:rgb(127, 219, 202)">&gt;</span><span class="token plain"> actionlint.sarif</span><br></div></code></pre></div></div>
<p>Atmos does not upload SARIF automatically. That avoids duplicate pull-request feedback and keeps
<code>security-events: write</code> unnecessary unless your workflow deliberately adds a SARIF
upload step.</p>
<p>The validator respects <code>.github/actionlint.yaml</code> and
<code>.github/actionlint.yml</code>. Its optional ShellCheck and Pyflakes integrations are
disabled for now, so the command stays deterministic and does not depend on tools installed on
the runner.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="learn-more">Learn More<a href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/ci-workflow-validation#learn-more" class="hash-link" aria-label="Direct link to Learn More" title="Direct link to Learn More" translate="no">​</a></h2>
<ul>
<li class=""><a class="" href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/ci/validate">atmos ci validate</a> — usage, flags, and output formats</li>
<li class=""><a class="" href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/ci">Native CI</a> — native CI behavior and configuration</li>
<li class=""><a class="" href="https://pr-2875.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/ci">CI configuration</a> — enable annotations and other CI features</li>
</ul>]]></content:encoded>
            <category>Feature</category>
        </item>
    </channel>
</rss>