<?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://atmos.tools/changelog</link>
        <description>atmos Blog</description>
        <lastBuildDate>Mon, 20 Jul 2026 12: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[Remote Build Caching for Container Builds]]></title>
            <link>https://atmos.tools/changelog/container-buildx-cache-and-driver</link>
            <guid>https://atmos.tools/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_K69Q" id="the-problem">The Problem<a href="https://atmos.tools/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_K69Q" id="the-fix">The Fix<a href="https://atmos.tools/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_K69Q" id="how-to-use-it">How to Use It<a href="https://atmos.tools/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://atmos.tools/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_K69Q" id="get-involved">Get Involved<a href="https://atmos.tools/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://atmos.tools/changelog/affected-validation</link>
            <guid>https://atmos.tools/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_K69Q" id="the-problem">The Problem<a href="https://atmos.tools/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_K69Q" id="the-fix">The Fix<a href="https://atmos.tools/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_K69Q" id="how-to-use-it">How to Use It<a href="https://atmos.tools/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_K69Q" id="get-involved">Get Involved<a href="https://atmos.tools/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://atmos.tools/changelog/init-real-starter-project</link>
            <guid>https://atmos.tools/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://atmos.tools/examples/init">View the full init example</a></p>
<h2 class="anchor anchorTargetStickyNavbar_K69Q" id="initialize-the-project-you-need">Initialize the Project You Need<a href="https://atmos.tools/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_K69Q" id="a-consistent-initialization-contract">A Consistent Initialization Contract<a href="https://atmos.tools/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_K69Q" id="build-your-organizations-golden-paths">Build Your Organization's Golden Paths<a href="https://atmos.tools/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://atmos.tools/changelog/scaffold-conditional-generation-and-hooks">the scaffolds announcement</a>.</p>
<p>See the <a class="" href="https://atmos.tools/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[Scaffolds turn your golden paths into a platform product]]></title>
            <link>https://atmos.tools/changelog/scaffold-conditional-generation-and-hooks</link>
            <guid>https://atmos.tools/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://atmos.tools/examples/scaffolding">View the full scaffolding example</a></p>
<h2 class="anchor anchorTargetStickyNavbar_K69Q" id="from-repository-copy-to-golden-path">From Repository Copy to Golden Path<a href="https://atmos.tools/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_K69Q" id="what-the-contract-enforces">What the Contract Enforces<a href="https://atmos.tools/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_K69Q" id="keep-github-templates-add-a-platform-contract">Keep GitHub Templates, Add a Platform Contract<a href="https://atmos.tools/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://atmos.tools/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://atmos.tools/changelog/toolchain-proxies</link>
            <guid>https://atmos.tools/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_K69Q" id="install-on-demand-keep-versions-pinned">Install on Demand, Keep Versions Pinned<a href="https://atmos.tools/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_K69Q" id="get-started">Get Started<a href="https://atmos.tools/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_K69Q" id="promote-a-subcommand-to-a-command">Promote a Subcommand to a Command<a href="https://atmos.tools/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_K69Q" id="useful-beyond-an-interactive-shell">Useful Beyond an Interactive Shell<a href="https://atmos.tools/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_K69Q" id="portable-by-design">Portable by Design<a href="https://atmos.tools/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://atmos.tools/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://atmos.tools/changelog/azure-blob-terraform-state-support</link>
            <guid>https://atmos.tools/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_K69Q" id="whats-new">What's New<a href="https://atmos.tools/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_K69Q" id="why-this-matters">Why This Matters<a href="https://atmos.tools/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_K69Q" id="how-it-works">How It Works<a href="https://atmos.tools/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_K69Q" id="backend-configuration">Backend Configuration<a href="https://atmos.tools/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_K69Q" id="reading-state">Reading State<a href="https://atmos.tools/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_K69Q" id="cross-stack-references">Cross-Stack References<a href="https://atmos.tools/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_K69Q" id="authentication">Authentication<a href="https://atmos.tools/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_K69Q" id="workspace-handling">Workspace Handling<a href="https://atmos.tools/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_K69Q" id="example">Example<a href="https://atmos.tools/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_K69Q" id="performance-benefits">Performance Benefits<a href="https://atmos.tools/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_K69Q" id="before-using-terraformoutput">Before: Using <code>!terraform.output</code><a href="https://atmos.tools/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_K69Q" id="after-using-terraformstate">After: Using <code>!terraform.state</code><a href="https://atmos.tools/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_K69Q" id="advanced-features">Advanced Features<a href="https://atmos.tools/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_K69Q" id="yq-expressions">YQ Expressions<a href="https://atmos.tools/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_K69Q" id="caching">Caching<a href="https://atmos.tools/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_K69Q" id="error-handling">Error Handling<a href="https://atmos.tools/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_K69Q" id="technical-details">Technical Details<a href="https://atmos.tools/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_K69Q" id="implementation-highlights">Implementation Highlights<a href="https://atmos.tools/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_K69Q" id="backend-configuration-options">Backend Configuration Options<a href="https://atmos.tools/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_K69Q" id="migration-guide">Migration Guide<a href="https://atmos.tools/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_K69Q" id="from-terraformoutput-to-terraformstate">From <code>!terraform.output</code> to <code>!terraform.state</code><a href="https://atmos.tools/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_K69Q" id="from-store-to-terraformstate">From <code>!store</code> to <code>!terraform.state</code><a href="https://atmos.tools/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_K69Q" id="examples">Examples<a href="https://atmos.tools/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_K69Q" id="basic-usage">Basic Usage<a href="https://atmos.tools/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_K69Q" id="cross-region-references">Cross-Region References<a href="https://atmos.tools/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_K69Q" id="disaster-recovery-scenarios">Disaster Recovery Scenarios<a href="https://atmos.tools/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_K69Q" id="considerations">Considerations<a href="https://atmos.tools/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_K69Q" id="try-it-now">Try It Now<a href="https://atmos.tools/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_K69Q" id="documentation">Documentation<a href="https://atmos.tools/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://atmos.tools/functions/yaml/terraform.state">!terraform.state Function Reference</a></strong> - Complete usage documentation</li>
<li class=""><strong><a class="" href="https://atmos.tools/components/terraform/backends">Terraform Backends</a></strong> - Backend configuration guide</li>
<li class=""><strong><a class="" href="https://atmos.tools/stacks/remote-state">Remote State</a></strong> - Data sharing patterns</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_K69Q" id="get-involved">Get Involved<a href="https://atmos.tools/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://atmos.tools/changelog/ci-workflow-validation</link>
            <guid>https://atmos.tools/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_K69Q" id="validate-before-the-push">Validate Before the Push<a href="https://atmos.tools/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_K69Q" id="check-a-fixture-or-another-directory">Check a Fixture or Another Directory<a href="https://atmos.tools/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_K69Q" id="put-it-in-github-actions">Put It in GitHub Actions<a href="https://atmos.tools/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_K69Q" id="sarif-is-explicit">SARIF Is Explicit<a href="https://atmos.tools/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_K69Q" id="learn-more">Learn More<a href="https://atmos.tools/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://atmos.tools/cli/commands/ci/validate">atmos ci validate</a> — usage, flags, and output formats</li>
<li class=""><a class="" href="https://atmos.tools/ci">Native CI</a> — native CI behavior and configuration</li>
<li class=""><a class="" href="https://atmos.tools/cli/configuration/ci">CI configuration</a> — enable annotations and other CI features</li>
</ul>]]></content:encoded>
            <category>Feature</category>
        </item>
        <item>
            <title><![CDATA[YQ Default Values Now Work Reliably in YAML Functions]]></title>
            <link>https://atmos.tools/changelog/yq-defaults-yaml-functions</link>
            <guid>https://atmos.tools/changelog/yq-defaults-yaml-functions</guid>
            <pubDate>Thu, 16 Jul 2026 12:00:00 GMT</pubDate>
            <description><![CDATA[We've fixed an issue where YQ default values (using the // fallback operator) in !terraform.state and !terraform.output YAML functions were not being evaluated when components weren't provisioned or outputs didn't exist.]]></description>
            <content:encoded><![CDATA[<p>We've fixed an issue where YQ default values (using the <code>//</code> fallback operator) in <code>!terraform.state</code> and <code>!terraform.output</code> YAML functions were not being evaluated when components weren't provisioned or outputs didn't exist.</p>
<h2 class="anchor anchorTargetStickyNavbar_K69Q" id="what-changed">What Changed<a href="https://atmos.tools/changelog/yq-defaults-yaml-functions#what-changed" class="hash-link" aria-label="Direct link to What Changed" title="Direct link to What Changed" translate="no">​</a></h2>
<p>YQ expressions with default values now work correctly in all scenarios:</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"># This now works reliably when vpc component isn't provisioned</span><span class="token plain"></span></span><br></div><div class="token-line 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">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 </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"> .vpc_id // "default</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">subnets</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"> .subnets // </span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token string" style="color:rgb(173, 219, 103)">"subnet-1"</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)">"subnet-2"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span></span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_K69Q" id="the-problem">The Problem<a href="https://atmos.tools/changelog/yq-defaults-yaml-functions#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>Previously, when a terraform component wasn't provisioned or an output didn't exist, the YAML function wrappers would return <code>nil</code> or exit before the YQ pipeline could evaluate default expressions. This caused sporadic failures where users expected the YQ <code>//</code> operator to provide fallback values.</p>
<p>The issue manifested as:</p>
<ul>
<li class="">Stack configurations failing when referencing unprovisioned components</li>
<li class="">Inconsistent behavior depending on component state</li>
<li class="">No way to gracefully handle missing outputs with defaults</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_K69Q" id="the-solution">The Solution<a href="https://atmos.tools/changelog/yq-defaults-yaml-functions#the-solution" class="hash-link" aria-label="Direct link to The Solution" title="Direct link to The Solution" translate="no">​</a></h2>
<p>We refactored the YAML function processing to:</p>
<ol>
<li class="">
<p><strong>Properly classify errors</strong>: Distinguish between recoverable errors (component not provisioned, output missing) and non-recoverable API errors (S3 timeouts, network failures)</p>
</li>
<li class="">
<p><strong>Evaluate YQ defaults for recoverable errors</strong>: When a component isn't provisioned but the expression includes a default (<code>//</code>), evaluate the YQ expression against an empty map to extract the default value</p>
</li>
<li class="">
<p><strong>Propagate API errors</strong>: Infrastructure failures like S3 timeouts correctly propagate as errors rather than silently using defaults</p>
</li>
</ol>
<h2 class="anchor anchorTargetStickyNavbar_K69Q" id="examples">Examples<a href="https://atmos.tools/changelog/yq-defaults-yaml-functions#examples" class="hash-link" aria-label="Direct link to Examples" title="Direct link to Examples" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_K69Q" id="string-defaults">String Defaults<a href="https://atmos.tools/changelog/yq-defaults-yaml-functions#string-defaults" class="hash-link" aria-label="Direct link to String Defaults" title="Direct link to String Defaults" 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">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">bucket_name</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"> s3 </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"> .bucket_name // "default</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">bucket"</span></span><br></div></code></pre></div></div>
<p>If the <code>s3</code> component isn't provisioned, <code>bucket_name</code> will be <code>"default-bucket"</code>.</p>
<h3 class="anchor anchorTargetStickyNavbar_K69Q" id="list-defaults">List Defaults<a href="https://atmos.tools/changelog/yq-defaults-yaml-functions#list-defaults" class="hash-link" aria-label="Direct link to List Defaults" title="Direct link to List Defaults" 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">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">subnets</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"> .private_subnets // </span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token string" style="color:rgb(173, 219, 103)">"subnet-a"</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)">"subnet-b"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span></span><br></div></code></pre></div></div>
<p>If the <code>vpc</code> component isn't provisioned, <code>subnets</code> will be <code>["subnet-a", "subnet-b"]</code>.</p>
<h3 class="anchor anchorTargetStickyNavbar_K69Q" id="map-defaults">Map Defaults<a href="https://atmos.tools/changelog/yq-defaults-yaml-functions#map-defaults" class="hash-link" aria-label="Direct link to Map Defaults" title="Direct link to Map Defaults" 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">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)">!terraform.output</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'common {{ .stack }} .tags // {"env": "dev", "team": "platform"}'</span></span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_K69Q" id="no-default-error-on-missing">No Default (Error on Missing)<a href="https://atmos.tools/changelog/yq-defaults-yaml-functions#no-default-error-on-missing" class="hash-link" aria-label="Direct link to No Default (Error on Missing)" title="Direct link to No Default (Error on Missing)" 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">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"># This will error if vpc component isn't provisioned (expected behavior)</span><span class="token plain"></span></span><br></div><div class="token-line 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 </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"> .vpc_id</span></span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_K69Q" id="error-handling-behavior">Error Handling Behavior<a href="https://atmos.tools/changelog/yq-defaults-yaml-functions#error-handling-behavior" class="hash-link" aria-label="Direct link to Error Handling Behavior" title="Direct link to Error Handling Behavior" translate="no">​</a></h2>
<table><thead><tr><th>Scenario</th><th>Has Default (<code>//</code>)</th><th>Result</th></tr></thead><tbody><tr><td>Component not provisioned</td><td>Yes</td><td>Uses default value</td></tr><tr><td>Component not provisioned</td><td>No</td><td>Returns error</td></tr><tr><td>Output missing</td><td>Yes</td><td>Uses default value</td></tr><tr><td>Output missing</td><td>No</td><td>Returns <code>nil</code></td></tr><tr><td>API error (S3 timeout)</td><td>Yes/No</td><td>Returns error</td></tr></tbody></table>
<h2 class="anchor anchorTargetStickyNavbar_K69Q" id="migration">Migration<a href="https://atmos.tools/changelog/yq-defaults-yaml-functions#migration" class="hash-link" aria-label="Direct link to Migration" title="Direct link to Migration" translate="no">​</a></h2>
<p>No migration is required. Existing configurations that use YQ defaults will now work as expected. Configurations without defaults maintain their existing behavior.</p>
<h2 class="anchor anchorTargetStickyNavbar_K69Q" id="related-links">Related Links<a href="https://atmos.tools/changelog/yq-defaults-yaml-functions#related-links" class="hash-link" aria-label="Direct link to Related Links" title="Direct link to Related Links" translate="no">​</a></h2>
<ul>
<li class=""><a href="https://github.com/cloudposse/atmos/pull/1836" target="_blank" rel="noopener noreferrer" class="">PR #1836: Fix YQ defaults for terraform.state/output YAML functions</a></li>
<li class=""><a class="" href="https://atmos.tools/functions/yaml">YAML Functions Documentation</a></li>
<li class=""><a class="" href="https://atmos.tools/functions/yaml/terraform.output">Terraform Output Function</a></li>
<li class=""><a class="" href="https://atmos.tools/functions/yaml/terraform.state">Terraform State Function</a></li>
</ul>]]></content:encoded>
            <category>Bug Fix</category>
        </item>
        <item>
            <title><![CDATA[atmos.yaml Gets a JSON Schema That Can't Go Stale]]></title>
            <link>https://atmos.tools/changelog/atmos-yaml-schema</link>
            <guid>https://atmos.tools/changelog/atmos-yaml-schema</guid>
            <pubDate>Thu, 16 Jul 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Editing atmos.yaml has always been a matter of trust. Misspell a key, indent a section one level too deep, or put a string where a map belongs, and nothing tells you — unknown keys are silently ignored, and you discover the mistake only when Atmos doesn't behave the way you expected. Stack manifests solved this with a published JSON Schema and editor auto-completion, but the CLI configuration itself — a surface that has grown far larger than stack manifests — had no schema at all. Now it does: a schema generated from the very code that reads the configuration, validated by default, published with every release, and wired into your editor with one comment line.]]></description>
            <content:encoded><![CDATA[<p>Editing <code>atmos.yaml</code> has always been a matter of trust. Misspell a key, indent a section one level too deep, or put a string where a map belongs, and nothing tells you — unknown keys are silently ignored, and you discover the mistake only when Atmos doesn't behave the way you expected. Stack manifests solved this with a published JSON Schema and editor auto-completion, but the CLI configuration itself — a surface that has grown far larger than stack manifests — had no schema at all. Now it does: a schema generated from the very code that reads the configuration, validated by default, published with every release, and wired into your editor with one comment line.</p>
<h2 class="anchor anchorTargetStickyNavbar_K69Q" id="the-problem">The Problem<a href="https://atmos.tools/changelog/atmos-yaml-schema#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>Your <code>atmos.yaml</code> is the control plane for everything Atmos does — stacks, components, commands, auth, toolchains, integrations. It's also the file where mistakes hide best:</p>
<ul>
<li class="">A typo like <code>worfklows:</code> is ignored without a warning, and the real setting silently keeps its default.</li>
<li class="">Nothing in your editor tells you what keys exist, what type they expect, or what they mean.</li>
<li class="">Configuration is spread across <code>atmos.yaml</code>, <code>atmos.d/</code> fragments, and <a class="" href="https://atmos.tools/cli/configuration/profiles">profiles</a> — partial files that no hand-written schema handled.</li>
<li class="">Hand-maintained schemas rot. Every release adds configuration options, and a schema updated by memory falls behind the moment someone forgets.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_K69Q" id="the-fix">The Fix<a href="https://atmos.tools/changelog/atmos-yaml-schema#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 ships a complete JSON Schema for <code>atmos.yaml</code> — and it's generated from the configuration code itself, on every change, enforced by CI. If a release adds a configuration option, the schema already models it. There is no separate document to remember to update, so it cannot drift from what Atmos actually reads.</p>
<p>The schema understands how real Atmos configurations are written:</p>
<ul>
<li class=""><strong>YAML functions are first-class.</strong> Where a section expects a map, the schema also accepts <code>!include shared.yaml</code>, <code>!env</code>, <code>!exec</code>, and every other function <code>atmos.yaml</code> supports — so dynamic configs validate cleanly.</li>
<li class=""><strong>Fragments validate standalone.</strong> No field is required, so <code>atmos.d/</code> files and profile fragments — which each carry only a slice of the configuration — pass on their own.</li>
<li class=""><strong>Descriptions come from the source.</strong> Hover documentation in your editor is sourced from the same documentation the code carries.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_K69Q" id="how-to-use-it">How to Use It<a href="https://atmos.tools/changelog/atmos-yaml-schema#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>Validation now happens out of the box. With no configuration at all, <code>atmos validate schema</code> checks <code>atmos.yaml</code>, <code>atmos.d/</code> fragments, and project-local profiles:</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 schema</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">✓ Validated atmos.yaml</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">✓ Validated atmos.d/logs.yaml</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">✓ Validated profiles/dev/settings.yaml</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">✓ All schemas validated successfully</span><br></div></code></pre></div></div>
<p>To validate just the CLI configuration, <code>atmos config validate</code> is a shorthand alias for <code>atmos validate schema config</code>, and exits non-zero on violations — handy for CI and pre-commit hooks. Symmetrically, <code>atmos stack validate</code> now aliases <code>atmos validate stacks</code>. Validation is also fast in large repositories: file matching no longer walks the whole tree for plain file names, so results stream immediately.</p>
<p>Print the schema for the exact Atmos version you're running with the new <a class="" href="https://atmos.tools/cli/commands/config/config-schema"><code>atmos config schema</code></a> command — a sibling of <code>atmos stack schema</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 config schema                     </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># print to stdout</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos config schema atmos-config.json   </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># write to a file</span><br></div></code></pre></div></div>
<p>For editor auto-completion and inline validation, add one comment to the top of <code>atmos.yaml</code>:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># yaml-language-server: $schema=https://atmos.tools/schemas/atmos/atmos-config/1.0/atmos-config.json</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain"></span><span class="token key atrule">base_path</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)">"./"</span></span><br></div></code></pre></div></div>
<p>The schema reaches every surface where you touch <code>atmos.yaml</code>: the experimental Atmos LSP server (<code>atmos lsp start</code>) now reports schema violations as inline diagnostics with line positions, and AI assistants connected through the Atmos MCP server get a new <code>atmos_validate_schema</code> tool alongside <code>atmos_validate_stacks</code>.</p>
<p>The floating URL above always tracks the latest release. Every release also publishes an immutable, version-pinned snapshot at <code>https://atmos.tools/schemas/atmos/atmos-config/&lt;atmos-version&gt;/atmos-config.json</code>, and a <code>schemas.config</code> entry in <code>atmos.yaml</code> lets you pin validation to a reviewed schema version or point it at your own:</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">schemas</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">config</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">schema</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)">"https://atmos.tools/schemas/atmos/atmos-config/1.219.0/atmos-config.json"</span></span><br></div></code></pre></div></div>
<p>See <a class="" href="https://atmos.tools/cli/configuration/schemas">CLI Configuration Schemas</a> for the full reference.</p>
<h2 class="anchor anchorTargetStickyNavbar_K69Q" id="get-involved">Get Involved<a href="https://atmos.tools/changelog/atmos-yaml-schema#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 validate schema</code> on your project and add the modeline to your <code>atmos.yaml</code>. If the schema rejects a configuration that Atmos accepts — or your editor's completions are missing something — <a href="https://github.com/cloudposse/atmos/issues" target="_blank" rel="noopener noreferrer" class="">open an issue</a>; the generator makes those fixes one small change away. Join us in the <a href="https://cloudposse.com/slack/" target="_blank" rel="noopener noreferrer" class="">Cloud Posse community</a> to share feedback.</p>]]></content:encoded>
            <category>Feature</category>
            <category>DX</category>
        </item>
        <item>
            <title><![CDATA[Faster, Safer Parallel Toolchain Installs]]></title>
            <link>https://atmos.tools/changelog/parallel-toolchain-installs</link>
            <guid>https://atmos.tools/changelog/parallel-toolchain-installs</guid>
            <pubDate>Wed, 15 Jul 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Atmos toolchain installs can now run independent packages in parallel. Batch installs use four workers by default, while preserving the compact terminal UI: every active package keeps its own spinner, download size, verification state, and final result line.]]></description>
            <content:encoded><![CDATA[<p>Atmos toolchain installs can now run independent packages in parallel. Batch installs use four workers by default, while preserving the compact terminal UI: every active package keeps its own spinner, download size, verification state, and final result line.</p>
<h2 class="anchor anchorTargetStickyNavbar_K69Q" id="faster-installs-without-shared-state-races">Faster installs without shared-state races<a href="https://atmos.tools/changelog/parallel-toolchain-installs#faster-installs-without-shared-state-races" class="hash-link" aria-label="Direct link to Faster installs without shared-state races" title="Direct link to Faster installs without shared-state races" translate="no">​</a></h2>
<p>Tool downloads, extraction, version markers, <code>toolchain.lock.yaml</code>, and <code>.tool-versions</code> are all coordinated with granular advisory locks. Independent tools continue in parallel, but operations that mutate the same cache asset, installation directory, or configuration file wait safely instead of corrupting one another. The locks work across separate Atmos processes as well as parallel workers in one process.</p>
<p>The progress display now keeps download totals visible on the right edge of the terminal and changes the active state to <strong>Verifying</strong> once the asset is available. Non-interactive output and the existing completed-result summary remain unchanged.</p>
<h2 class="anchor anchorTargetStickyNavbar_K69Q" id="configure-concurrency">Configure concurrency<a href="https://atmos.tools/changelog/parallel-toolchain-installs#configure-concurrency" class="hash-link" aria-label="Direct link to Configure concurrency" title="Direct link to Configure concurrency" translate="no">​</a></h2>
<p>Set the maximum number of simultaneous installs in <code>atmos.yaml</code>:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token key atrule">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">max_concurrency</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">4</span></span><br></div></code></pre></div></div>
<p>Or override it for a single command:</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 </span><span class="token function" style="color:rgb(130, 170, 255)">install</span><span class="token plain"> --max-concurrency </span><span class="token number" style="color:rgb(247, 140, 108)">8</span><br></div></code></pre></div></div>
<p>Atmos rejects values lower than one. The command-line flag takes precedence over configuration.</p>
<h2 class="anchor anchorTargetStickyNavbar_K69Q" id="reliable-signature-verification">Reliable signature verification<a href="https://atmos.tools/changelog/parallel-toolchain-installs#reliable-signature-verification" class="hash-link" aria-label="Direct link to Reliable signature verification" title="Direct link to Reliable signature verification" translate="no">​</a></h2>
<p>Atmos also isolates its bootstrap verifier from concurrent use and retries only transient, pre-verdict verifier failures. Legacy releases that publish detached Cosign certificates and signatures are verified with the compatible Cosign v2 path; newer bundle-based verification continues to use the current verifier. Verification remains required—retries never treat an invalid signature or identity mismatch as success.</p>
<p>See the <a class="" href="https://atmos.tools/cli/commands/toolchain/usage">toolchain documentation</a> for installation and configuration details.</p>]]></content:encoded>
            <category>Feature</category>
            <category>Experimental</category>
        </item>
        <item>
            <title><![CDATA[Component Mocks for Terraform YAML Lookups]]></title>
            <link>https://atmos.tools/changelog/terraform-component-mocks</link>
            <guid>https://atmos.tools/changelog/terraform-component-mocks</guid>
            <pubDate>Wed, 15 Jul 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Cross-component Terraform lookups are useful precisely when an application component needs the outputs of something like a VPC, cluster, or database. They can also make a local plan or configuration review depend on deployed infrastructure, backend access, and cloud credentials that are irrelevant to the change at hand.]]></description>
            <content:encoded><![CDATA[<p>Cross-component Terraform lookups are useful precisely when an application component needs the outputs of something like a VPC, cluster, or database. They can also make a local plan or configuration review depend on deployed infrastructure, backend access, and cloud credentials that are irrelevant to the change at hand.</p>
<p>Atmos now supports <strong>component mocks</strong>: literal, component-owned Terraform outputs that you enable explicitly with <code>--use-mocks</code>.</p>
<h2 class="anchor anchorTargetStickyNavbar_K69Q" id="the-problem-a-small-dependency-can-make-a-plan-non-local">The problem: a small dependency can make a plan non-local<a href="https://atmos.tools/changelog/terraform-component-mocks#the-problem-a-small-dependency-can-make-a-plan-non-local" class="hash-link" aria-label="Direct link to The problem: a small dependency can make a plan non-local" title="Direct link to The problem: a small dependency can make a plan non-local" translate="no">​</a></h2>
<p>Consider an <code>app</code> component that takes its VPC ID from a <code>vpc</code> component:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockTitle_JJ7b">stacks/dev.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">app</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">vars</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">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>
<p>Normally, Atmos resolves that lookup from the VPC's real Terraform state. That is the right default for regular operations, but it can be inconvenient when you are developing the application configuration before the VPC exists, reviewing a change offline, or deliberately avoiding access to a remote backend.</p>
<p>The old choices were usually to provision the dependency first, change the consumer temporarily, or build an ad hoc fixture outside the component that owns the output. None of those makes the intended fake surface obvious.</p>
<h2 class="anchor anchorTargetStickyNavbar_K69Q" id="the-fix-declare-the-fake-surface-next-to-the-producer">The fix: declare the fake surface next to the producer<a href="https://atmos.tools/changelog/terraform-component-mocks#the-fix-declare-the-fake-surface-next-to-the-producer" class="hash-link" aria-label="Direct link to The fix: declare the fake surface next to the producer" title="Direct link to The fix: declare the fake surface next to the producer" translate="no">​</a></h2>
<p>Declare the outputs a Terraform component can stand in for under <code>mocks</code>:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockTitle_JJ7b">stacks/dev.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">mocks</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"> vpc</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">local</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">private_subnet_ids</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">subnet</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">a</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> subnet</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">b</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">network</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">          </span><span class="token key atrule">cidr</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> 10.0.0.0/16</span></span><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">app</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">vars</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">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">        </span><span class="token key atrule">private_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.output</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 class="token plain">'</span></span><br></div></code></pre></div></div>
<p>Then choose the mock path at invocation time:</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 describe component app </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-s</span><span class="token plain"> dev --use-mocks</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos terraform plan app </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-s</span><span class="token plain"> dev --use-mocks</span><br></div></code></pre></div></div>
<p>Both <code>!terraform.state</code> and <code>!terraform.output</code> resolve from <code>vpc.mocks</code>. The familiar output and YQ-expression syntax stays the same; only the source of the value changes.</p>
<p>This is intentionally a narrow model. There are no mock profiles, provider simulations, resource emulation, or consumer-side override DSLs. A component declares the broad fake output surface once, and the command makes an explicit decision to use it.</p>
<p>The <a class="" href="https://atmos.tools/quick-start/advanced/">advanced quick start</a> uses this pattern for its first, state-free plan: its regional KMS, storage, and messaging components declare provider-shaped outputs, while its normal deploy continues to use real state.</p>
<h2 class="anchor anchorTargetStickyNavbar_K69Q" id="what-mock-mode-bypasses">What mock mode bypasses<a href="https://atmos.tools/changelog/terraform-component-mocks#what-mock-mode-bypasses" class="hash-link" aria-label="Direct link to What mock mode bypasses" title="Direct link to What mock mode bypasses" translate="no">​</a></h2>
<p>When a Terraform lookup is mocked, Atmos loads the referenced component's merged <code>mocks</code> map and evaluates the requested expression against it. It does <strong>not</strong> initialize Terraform, resolve the referenced component's credentials, read a backend, or populate the real-state lookup cache.</p>
<p>That makes mock mode useful for local plans and <code>describe component</code> output that should be independent of the remote dependency. It also means <code>--use-mocks</code> never silently falls back to real state: a missing mock map or output is an actionable error, not a surprise backend read.</p>
<p>Mock values themselves are literal. Atmos does not evaluate templates or YAML functions inside <code>mocks</code>, so a mock cannot accidentally call the real dependency it was meant to replace.</p>
<h2 class="anchor anchorTargetStickyNavbar_K69Q" id="guardrails-keep-normal-operations-normal">Guardrails keep normal operations normal<a href="https://atmos.tools/changelog/terraform-component-mocks#guardrails-keep-normal-operations-normal" class="hash-link" aria-label="Direct link to Guardrails keep normal operations normal" title="Direct link to Guardrails keep normal operations normal" translate="no">​</a></h2>
<p>Mocks are opt-in. Without <code>--use-mocks</code>, existing <code>!terraform.state</code> and <code>!terraform.output</code> behavior is unchanged.</p>
<p>The flag is supported by:</p>
<ul>
<li class=""><code>atmos terraform plan</code></li>
<li class=""><code>atmos describe component</code></li>
</ul>
<p>Mutating Terraform commands—including <code>apply</code>, <code>deploy</code>, and <code>destroy</code>—and Terraform passthrough commands reject it before stack resolution. <code>--use-mocks</code> also requires YAML function processing to remain enabled.</p>
<p>Because <code>mocks</code> follows normal component inheritance and deep-merge behavior, a base component can provide shared fixtures while a concrete component replaces only the outputs that differ.</p>
<h2 class="anchor anchorTargetStickyNavbar_K69Q" id="try-it">Try it<a href="https://atmos.tools/changelog/terraform-component-mocks#try-it" class="hash-link" aria-label="Direct link to Try it" title="Direct link to Try it" translate="no">​</a></h2>
<p>The repository includes a provider-free example with a producer, a consumer, the normal real-state flow, and the mocked flow:</p>
<div class="language-shell codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-shell codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A"><div class="token-line" style="color:#d6deeb"><span class="token builtin class-name" style="color:rgb(255, 203, 139)">cd</span><span class="token plain"> examples/terraform-component-mocks</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"># Resolve app's VPC ID from the vpc mock, without creating state.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos terraform plan app </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-s</span><span class="token plain"> dev --use-mocks</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"># Inspect the final component configuration with the same mock resolution.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos describe component app </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-s</span><span class="token plain"> dev --use-mocks</span><br></div></code></pre></div></div>
<p>For the normal path, create the producer's state and omit the flag:</p>
<div class="language-shell codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-shell codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A"><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos terraform apply vpc </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-s</span><span class="token plain"> dev</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos terraform plan app </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-s</span><span class="token plain"> dev</span><br></div></code></pre></div></div>
<p>Read more about <a class="" href="https://atmos.tools/functions/yaml/terraform.state"><code>!terraform.state</code></a> and <a class="" href="https://atmos.tools/functions/yaml/terraform.output"><code>!terraform.output</code></a>, or use the example as the smallest starting point for adding mocks to your own stack.</p>]]></content:encoded>
            <category>Feature</category>
            <category>DX</category>
        </item>
        <item>
            <title><![CDATA[Fixing Gatekeeper SIGKILLs on Downloaded Toolchain Verifiers]]></title>
            <link>https://atmos.tools/changelog/macos-toolchain-verifier-trust</link>
            <guid>https://atmos.tools/changelog/macos-toolchain-verifier-trust</guid>
            <pubDate>Tue, 14 Jul 2026 12:00:00 GMT</pubDate>
            <description><![CDATA[On macOS, Atmos would sometimes install a verifier CLI (like cosign, used to check signatures on]]></description>
            <content:encoded><![CDATA[<p>On macOS, Atmos would sometimes install a verifier CLI (like <code>cosign</code>, used to check signatures on
downloaded toolchain binaries) through <code>verifier_install: auto</code>, checksum-verify it successfully — and
then have the OS kill it the instant Atmos tried to run it. Gatekeeper and AMFI re-validate a downloaded
binary's code-signing trust on every execution, not just the first Finder launch, so a checksum match
alone wasn't enough to let a freshly downloaded, ad-hoc-signed release asset actually run.</p>
<h2 class="anchor anchorTargetStickyNavbar_K69Q" id="the-fix">The Fix<a href="https://atmos.tools/changelog/macos-toolchain-verifier-trust#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>After Atmos installs and checksum-verifies a verifier binary, it now strips the macOS quarantine
extended attributes (<code>com.apple.quarantine</code>, <code>com.apple.provenance</code>) and ad-hoc re-signs the binary —
the same trick Homebrew uses for downloaded formula binaries. This only ever runs on binaries Atmos
itself just downloaded into its own bootstrap path; a verifier already found on <code>PATH</code> is user-managed
and already OS-trusted, so it's left untouched. On Linux and Windows, this is a no-op — only macOS
re-validates trust on every exec.</p>
<h2 class="anchor anchorTargetStickyNavbar_K69Q" id="how-to-use-it">How to Use It<a href="https://atmos.tools/changelog/macos-toolchain-verifier-trust#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>This is on by default (<code>verifier_trust: auto</code>) — most users won't need to touch it. To opt out entirely:</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">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">verification</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">verifier_trust</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> disabled</span></span><br></div></code></pre></div></div>
<p>See the <a class="" href="https://atmos.tools/cli/configuration/toolchain/verification">toolchain verification docs</a> for the full settings
reference.</p>
<h2 class="anchor anchorTargetStickyNavbar_K69Q" id="get-involved">Get Involved<a href="https://atmos.tools/changelog/macos-toolchain-verifier-trust#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>Questions or feedback? Open an issue on <a href="https://github.com/cloudposse/atmos" target="_blank" rel="noopener noreferrer" class="">GitHub</a> or join the
conversation in our community Slack.</p>]]></content:encoded>
            <category>Bug Fix</category>
        </item>
        <item>
            <title><![CDATA[Manage MCP Servers Without Hand-Editing YAML]]></title>
            <link>https://atmos.tools/changelog/mcp-server-management-commands</link>
            <guid>https://atmos.tools/changelog/mcp-server-management-commands</guid>
            <pubDate>Tue, 14 Jul 2026 12:00:00 GMT</pubDate>
            <description><![CDATA[Getting Atmos connected to an MCP server, or letting your AI assistant call Atmos's own tools, used to]]></description>
            <content:encoded><![CDATA[<p>Getting Atmos connected to an MCP server, or letting your AI assistant call Atmos's own tools, used to
mean opening <code>atmos.yaml</code> and hand-writing a <code>mcp.servers</code> entry — then, separately, remembering which
<code>atmos mcp</code> command actually pushes it into Claude Code, Cursor, or VS Code. If all you wanted was
"let my AI assistant use Atmos," there was no single command that got you there.</p>
<h2 class="anchor anchorTargetStickyNavbar_K69Q" id="the-fix">The Fix<a href="https://atmos.tools/changelog/mcp-server-management-commands#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 mcp add</code> and <code>atmos mcp remove</code> manage <code>mcp.servers</code> in <code>atmos.yaml</code> directly — no YAML editing
required. Two built-in presets skip the boilerplate entirely: <code>self</code> wires up Atmos's own MCP server, and
<code>atmos-pro</code> wires up the Atmos Pro MCP server. Run <code>atmos mcp add</code> with no arguments at all and it defaults
to <code>atmos mcp add self</code>, so the entire "let my AI assistant use Atmos" flow is one command.</p>
<p>On the other side, <code>atmos mcp uninstall</code> is the mirror image of the existing <code>atmos mcp install</code> — it
removes servers from an AI client's config without touching <code>atmos.yaml</code>. <code>add</code>/<code>remove</code> manage the
declarative source of truth; <code>install</code>/<code>uninstall</code> push and pull it to your client. They compose, but
never step on each other.</p>
<p><code>atmos mcp list</code> and <code>atmos mcp status</code> also now mention these commands directly instead of just saying
"no servers configured," and nudge you to run <code>atmos mcp add atmos-pro</code> if Atmos Pro is already configured
but its MCP server hasn't been added yet.</p>
<h2 class="anchor anchorTargetStickyNavbar_K69Q" id="how-to-use-it">How to Use It<a href="https://atmos.tools/changelog/mcp-server-management-commands#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-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"># Let your AI assistant use Atmos's own tools -- writes mcp.servers.atmos,</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"># prompts to enable mcp.enabled if it's off, and installs into detected clients.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos mcp </span><span class="token function" style="color:rgb(130, 170, 255)">add</span><span class="token plain"> self </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--install</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"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Add the Atmos Pro MCP server.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos mcp </span><span class="token function" style="color:rgb(130, 170, 255)">add</span><span class="token plain"> atmos-pro</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"># Add an external server -- name and transport are inferred.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos mcp </span><span class="token function" style="color:rgb(130, 170, 255)">add</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"uvx awslabs.aws-documentation-mcp-server@latest"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos mcp </span><span class="token function" style="color:rgb(130, 170, 255)">add</span><span class="token plain"> https://mcp.example.com/mcp </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--header</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"Authorization: Bearer </span><span class="token string variable" style="color:rgb(214, 222, 235)">${TOKEN}</span><span class="token string" style="color:rgb(173, 219, 103)">"</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"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Remove a server, and uninstall it from wherever it was pushed.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos mcp remove aws-docs</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos mcp uninstall aws-docs</span><br></div></code></pre></div></div>
<p>See the <a class="" href="https://atmos.tools/mcp">MCP documentation</a> for the full command reference and built-in preset details.</p>
<h2 class="anchor anchorTargetStickyNavbar_K69Q" id="get-involved">Get Involved<a href="https://atmos.tools/changelog/mcp-server-management-commands#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>Questions or feedback? Open an issue on <a href="https://github.com/cloudposse/atmos" target="_blank" rel="noopener noreferrer" class="">GitHub</a> or join the
conversation in our community Slack.</p>]]></content:encoded>
            <category>Feature</category>
        </item>
        <item>
            <title><![CDATA[MCP Servers No Longer Need a Second Flag to Do Anything]]></title>
            <link>https://atmos.tools/changelog/mcp-tools-always-available</link>
            <guid>https://atmos.tools/changelog/mcp-tools-always-available</guid>
            <pubDate>Tue, 14 Jul 2026 12:00:00 GMT</pubDate>
            <description><![CDATA[You set mcp.enabled `failed to initialize AI components:]]></description>
            <content:encoded><![CDATA[<p>You set <code>mcp.enabled: true</code>, ran <code>atmos mcp start</code>, and got: <code>failed to initialize AI components: tools are disabled</code>. MCP was on. Why did anything else need to be "enabled" for a command whose
entire job is exposing tools?</p>
<h2 class="anchor anchorTargetStickyNavbar_K69Q" id="the-problem">The Problem<a href="https://atmos.tools/changelog/mcp-tools-always-available#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p><code>ai.tools.enabled</code> was designed for <code>atmos ai chat</code>/<code>ask</code>/<code>exec</code> — Atmos's own assistant deciding
whether it's allowed to call tools during a conversation. <code>atmos mcp start</code> reused that same flag
as a hard gate, even though the MCP server has nothing to do with Atmos's own chat loop: its only
job is exposing Atmos tools to <em>external</em> clients like Claude Desktop or Cursor. <code>mcp.enabled: true</code>
was already the explicit, purpose-built opt-in for that — requiring a second, differently-named
flag on top of it just to get a non-empty server was pure friction, not safety.</p>
<h2 class="anchor anchorTargetStickyNavbar_K69Q" id="the-fix">The Fix<a href="https://atmos.tools/changelog/mcp-tools-always-available#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 mcp start</code> no longer checks <code>ai.tools.enabled</code> at all. Once <code>mcp.enabled: true</code>, tools
register unconditionally — <code>ai.tools.enabled</code> now only governs <code>atmos ai chat</code>/<code>ask</code>/<code>exec</code>'s own
tool-use loop, which is what it was always meant for.</p>
<p>While in there, we also renamed three related settings for consistency. They're already nested
under <code>tools:</code>, so the <code>_tools</code> suffix was redundant:</p>
<table><thead><tr><th>Old</th><th>New</th></tr></thead><tbody><tr><td><code>tools.allowed_tools</code></td><td><code>tools.allowed</code></td></tr><tr><td><code>tools.restricted_tools</code></td><td><code>tools.restricted</code></td></tr><tr><td><code>tools.blocked_tools</code></td><td><code>tools.blocked</code></td></tr></tbody></table>
<p><code>tools.allowed</code> also picked up a second job. Previously it only skipped the confirmation prompt —
every tool was still registered and callable, just some needed a "yes" first. Now, when non-empty,
it also controls which tools <em>exist</em> at all: unlisted tools aren't registered, aren't visible in
<code>tools/list</code>, and aren't offered to the AI. An empty or unset list still means "everything is
registered, subject to normal confirmation rules" — unchanged.</p>
<h2 class="anchor anchorTargetStickyNavbar_K69Q" id="how-to-use-it">How to Use It<a href="https://atmos.tools/changelog/mcp-tools-always-available#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><div class="file"><div class="file-header"><div class="file-title"><svg stroke="currentColor" fill="currentColor" stroke-width="0" role="img" viewBox="0 0 24 24" class="file-type-icon file-type-icon--yaml" aria-hidden="true" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="m0 .97 4.111 6.453v4.09h2.638v-4.09L11.053.969H8.214L5.58 5.125 2.965.969Zm12.093.024-4.47 10.544h2.114l.97-2.345h4.775l.804 2.345h2.26L14.255.994Zm1.133 2.225 1.463 3.87h-3.096zm3.06 9.475v10.29H24v-2.199h-5.454v-8.091zm-12.175.002v10.335h2.217v-7.129l2.32 4.792h1.746l2.4-4.96v7.295h2.127V12.696h-2.904L9.44 17.37l-2.455-4.674Z"></path></svg><span>atmos.yaml</span></div></div><div class="viewport"><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">mcp</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">enabled</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token boolean important" style="color:rgb(255, 88, 116)">true</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain" 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">ai</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">enabled</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token boolean important" style="color:rgb(255, 88, 116)">true</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">tools</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"># Optional -- omit entirely for a fully-populated MCP server.</span><span class="token plain"></span></span><br></div><div class="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"># When set, ONLY these are registered, and they skip confirmation:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">allowed</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"> atmos_describe_*</span></span><br></div><div class="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"> atmos_list_*</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">blocked</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"> execute_bash_command</span></span><br></div></code></pre></div></div></div></div></div>
<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">atmos mcp start</span><br></div></code></pre></div></div>
<p>No <code>ai.tools.enabled</code> required.</p>
<h2 class="anchor anchorTargetStickyNavbar_K69Q" id="breaking-change">Breaking Change<a href="https://atmos.tools/changelog/mcp-tools-always-available#breaking-change" class="hash-link" aria-label="Direct link to Breaking Change" title="Direct link to Breaking Change" translate="no">​</a></h2>
<p><code>tools.allowed_tools</code>, <code>tools.restricted_tools</code>, and <code>tools.blocked_tools</code> are no longer read —
there's no fallback or deprecation warning, just the new names. If your <code>atmos.yaml</code> sets any of
these under <code>ai.tools</code>, rename them before upgrading. If you were relying on <code>allowed_tools</code> to
skip confirmation for a subset of tools <em>while still allowing everything else to run with a
prompt</em>, note the semantics changed: an unlisted tool is no longer registered at all. Move it to
an empty <code>allowed</code> (or drop the list) and lean on <code>restricted</code>/<code>blocked</code> instead.</p>
<p>See <a class="" href="https://atmos.tools/cli/configuration/ai/tools">AI Tools Configuration</a> for the full reference.</p>]]></content:encoded>
            <category>Enhancement</category>
            <category>Breaking Change</category>
        </item>
        <item>
            <title><![CDATA[Tags and Labels: a First-Class Way to Categorize and Select Anything in Atmos]]></title>
            <link>https://atmos.tools/changelog/tags-and-labels</link>
            <guid>https://atmos.tools/changelog/tags-and-labels</guid>
            <pubDate>Tue, 14 Jul 2026 12:00:00 GMT</pubDate>
            <description><![CDATA[Your stack hierarchy picks one way to organize your infrastructure — org, account, region, component type — and it can only pick one. vpc in stacks/orgs/acme/prod/network.yaml tells you where it lives in that tree; it doesn't tell you it's tier-1, or that platform owns it, or that it's in scope for SOX. Those characteristics don't belong to one branch of the tree — they apply across many stacks and many components at once, and a single component is usually several of them simultaneously. Your AWS accounts and auth identities have the same problem: prod-admin doesn't tell you it's the production one, or the elevated one, until you already know that.]]></description>
            <content:encoded><![CDATA[<p>Your stack hierarchy picks one way to organize your infrastructure — org, account, region, component type — and it can only pick one. <code>vpc</code> in <code>stacks/orgs/acme/prod/network.yaml</code> tells you where it lives in that tree; it doesn't tell you it's tier-1, or that platform owns it, or that it's in scope for SOX. Those characteristics don't belong to one branch of the tree — they apply across many stacks and many components at once, and a single component is usually several of them simultaneously. Your AWS accounts and auth identities have the same problem: <code>prod-admin</code> doesn't tell you it's the production one, or the elevated one, until you already know that.</p>
<p>Tags and labels give components that organizational context directly — components get both; auth identities and providers get tags — so you can select and act on infrastructure by what it is instead of by where you filed it.</p>
<h2 class="anchor anchorTargetStickyNavbar_K69Q" id="the-problem">The Problem<a href="https://atmos.tools/changelog/tags-and-labels#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>A hierarchy can only organize infrastructure one way, but you need to operate on it along lines that hierarchy doesn't capture:</p>
<ul>
<li class=""><strong>A component's path describes its place in the tree, not what it is.</strong> It tells you the org, account, and region; it says nothing about tier, ownership, or compliance scope — and those apply across stacks and component types, not within one branch.</li>
<li class=""><strong>That context ended up living outside the system instead of on the resource.</strong> A <code>--query</code> expression like <code>.settings.tier == "network"</code> encoded "tier-1" for one command; a hand-maintained <code>--components</code> list encoded it for another. Neither traveled with the component, and both went stale the moment something changed.</li>
<li class=""><strong>The same gap showed up wherever Atmos manages many things.</strong> Components across every type (Terraform, Kubernetes, Helm, containers), plus auth identities and providers, all needed a way to carry their own organizational context instead of relying on someone remembering it.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_K69Q" id="the-fix">The Fix<a href="https://atmos.tools/changelog/tags-and-labels#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 carries that organizational context as metadata, in two shapes:</p>
<ul>
<li class=""><strong>Tags</strong> — a simple list of words, for basic categorical membership. Filtering matches <em>any</em> of the given tags.</li>
<li class=""><strong>Labels</strong> — a set of key-value pairs, for richer metadata. Filtering requires <em>all</em> of the given key=value pairs, the same semantics as a Kubernetes label selector.</li>
</ul>
<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">tags</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">production</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> networking</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> tier</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 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><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">          </span><span class="token key atrule">compliance</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> sox</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">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">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">sso-prod</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"> aws/iam</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">identity</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">center</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">start_url</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> https</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain">//my</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">org.awsapps.com/start</span></span><br></div><div class="token-line 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 punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token plain">production</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"> sso</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">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">prod-admin</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"> aws/permission</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">set</span></span><br></div><div class="token-line 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"> sso</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">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">name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> AdministratorAccess</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">account</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 key atrule">name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> production</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 punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token plain">admin</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> production</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> elevated</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">access</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span></span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_K69Q" id="how-to-use-it">How to Use It<a href="https://atmos.tools/changelog/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><strong>Listing and filtering components:</strong></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)">--tags</span><span class="token plain"> production,tier-1</span><br></div><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 plain"> cost-center</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">platform,compliance</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">sox</span><br></div></code></pre></div></div>
<p><strong>Bulk operations</strong> — <code>--tags</code>/<code>--labels</code> compose with <code>--all</code>/<code>--affected</code> everywhere Atmos already supports bulk selection, across every component type:</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)">--affected</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--tags</span><span class="token plain"> production</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos kubernetes 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 plain"> cost-center</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">platform</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos helm apply </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)">--tags</span><span class="token plain"> production</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos container up </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 plain"> production</span><br></div></code></pre></div></div>
<p>Because this lives in the shared component registry (<code>pkg/component</code>), any component type — built-in or custom — that adopts the standard bulk-execution pattern gets <code>--tags</code>/<code>--labels</code> filtering automatically, with no per-type code.</p>
<p><strong>The same filtering works for auth</strong>, since providers and identities are tagged the same way:</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 list </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--tags</span><span class="token plain"> production</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos auth login </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--tags</span><span class="token plain"> admin,production   </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># auto-selects if exactly one match, else prompts</span><span class="token plain"></span><br></div><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)">logout</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--tags</span><span class="token plain"> production        </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># logs out every matching provider</span><br></div></code></pre></div></div>
<p><strong>Bridging into your modules</strong> — four new YAML functions read a component's own <code>metadata.tags</code>/<code>metadata.labels</code> without the usual <code>!template</code>/<code>toJson</code> boilerplate: <code>!tags</code> and <code>!labels</code> return the values directly, and <code>!labels.keys</code>/<code>!labels.values</code> return just the label map's keys or values. The most common use is feeding <code>metadata.labels</code> into the <code>var.tags</code> a <code>terraform-null-label</code>-style module expects (Terraform and AWS call a map "tags"; Atmos calls it a "label" — same data, different name):</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">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><div class="token-line 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;- metadata.labels</span></span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_K69Q" id="get-involved">Get Involved<a href="https://atmos.tools/changelog/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>Tags and labels are supported today on components across Terraform, Kubernetes, Helm, and container components; auth identities and providers support tags. Auto-discovering tags/labels from cloud provider metadata (for example, mapping AWS SSO PermissionSet tags into Atmos labels automatically) is a natural next step — if that's something you need, open an issue and let us know your use case.</p>]]></content:encoded>
            <category>Feature</category>
        </item>
        <item>
            <title><![CDATA[Toolchain now installs aws-cli, Node, and other multi-file tools correctly]]></title>
            <link>https://atmos.tools/changelog/toolchain-multi-file-tools</link>
            <guid>https://atmos.tools/changelog/toolchain-multi-file-tools</guid>
            <pubDate>Tue, 14 Jul 2026 12:00:00 GMT</pubDate>
            <description><![CDATA[You pinned aws/aws-cli in your toolchain, ran atmos toolchain install, and saw a]]></description>
            <content:encoded><![CDATA[<p>You pinned <code>aws/aws-cli</code> in your toolchain, ran <code>atmos toolchain install</code>, and saw a
green checkmark — then <code>aws --version</code> died with <code>Failed to load Python shared library</code>. Or you pinned <code>nodejs/node</code> and the install never finished at all,
warning about "unknown type" and a file it couldn't find. The tools were right
there in the registry, <code>aqua</code> installed them fine, but Atmos couldn't.</p>
<p>That's fixed. Multi-file tools now install completely and actually run.</p>
<h2 class="anchor anchorTargetStickyNavbar_K69Q" id="the-problem">The Problem<a href="https://atmos.tools/changelog/toolchain-multi-file-tools#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>Atmos installed tools by copying just the entrypoints named in the registry's
<code>files:</code> list out of the downloaded archive — and throwing the rest away. That
works for a single self-contained binary like <code>jq</code> or <code>terraform</code>. It breaks for
"onedir" bundles that ship a binary <em>plus</em> the files it needs at runtime:</p>
<ul>
<li class=""><strong><code>aws/aws-cli</code></strong> bundles its own Python runtime. Atmos kept <code>aws</code> and
<code>aws_completer</code> and dropped the ~8,600 supporting files, including
<code>libpython</code>. The install reported success, but the binary was dead on arrival
(<a href="https://github.com/cloudposse/atmos/issues/2743" target="_blank" rel="noopener noreferrer" class="">#2743</a>).</li>
<li class=""><strong><code>nodejs/node</code></strong> exposes <code>npm</code>, <code>npx</code>, and <code>corepack</code> as symlinks into a
sibling <code>lib/</code> tree, and publishes under a <code>v</code>-prefixed path. Atmos skipped the
symlinks as an "unknown type" and looked for <code>node-24.18.0-...</code> instead of
<code>node-v24.18.0-...</code>, so the install failed outright
(<a href="https://github.com/cloudposse/atmos/issues/2744" target="_blank" rel="noopener noreferrer" class="">#2744</a>).</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_K69Q" id="the-fix">The Fix<a href="https://atmos.tools/changelog/toolchain-multi-file-tools#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 mirrors how the upstream <code>aqua</code> CLI installs these packages:</p>
<ul>
<li class=""><strong>Preserves the whole archive</strong> for multi-file tools under a <code>.pkg</code> directory
— so every executable stays next to the runtime files it needs — and records
each entrypoint's real path in a small sidecar manifest, without creating any
symlinks of its own (a design choice used consistently across Atmos).</li>
<li class=""><strong>Keeps the archive's own symlink entrypoints</strong> (like <code>npm</code> → <code>../lib/node_modules/...</code>)
instead of dropping them.</li>
<li class=""><strong>Resolves versions consistently</strong>, so a pinned <code>24.18.0</code> correctly finds the
<code>v24.18.0</code> archive that actually downloads.</li>
<li class=""><strong>Fails honestly</strong>: a broken or incomplete extraction no longer reports success
or leaves an orphaned binary behind.</li>
</ul>
<p>Single-binary tools are completely unaffected — they keep the exact same flat
layout as before.</p>
<h2 class="anchor anchorTargetStickyNavbar_K69Q" id="how-to-use-it">How to Use It<a href="https://atmos.tools/changelog/toolchain-multi-file-tools#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>Nothing new to learn. Pin the tools and install:</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 </span><span class="token function" style="color:rgb(130, 170, 255)">install</span><span class="token plain"> aws/aws-cli@2.35.15</span><br></div><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"> nodejs/node@24.18.0</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">$ aws </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--version</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">aws-cli/2.35.15 Python/3.14.5 Linux/</span><span class="token punctuation" style="color:rgb(199, 146, 234)">..</span><span class="token plain">. exe/x86_64</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">$ </span><span class="token function" style="color:rgb(130, 170, 255)">node</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--version</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">v24.18.0</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">$ </span><span class="token function" style="color:rgb(130, 170, 255)">npm</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--version</span><span class="token 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)">11.16</span><span class="token plain">.0</span><br></div></code></pre></div></div>
<p>See <a class="" href="https://atmos.tools/cli/commands/toolchain/install#how-tools-are-installed-on-disk">How tools are installed on disk</a>
for details on the layout.</p>
<h2 class="anchor anchorTargetStickyNavbar_K69Q" id="get-involved">Get Involved<a href="https://atmos.tools/changelog/toolchain-multi-file-tools#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>Toolchain is an <a href="https://atmos.tools/experimental" target="_blank" rel="noopener noreferrer" class="">experimental feature</a> and we're
actively hardening it. If a tool doesn't install cleanly, please
<a href="https://github.com/cloudposse/atmos/issues" target="_blank" rel="noopener noreferrer" class="">open an issue</a> with the <code>owner/repo</code>
and version — those reports are exactly what drove this fix.</p>]]></content:encoded>
            <category>Bug Fix</category>
            <category>Enhancement</category>
        </item>
        <item>
            <title><![CDATA[Archive Step Type: Pack Zip/Tar Archives Without Shelling Out]]></title>
            <link>https://atmos.tools/changelog/archive-step-type</link>
            <guid>https://atmos.tools/changelog/archive-step-type</guid>
            <pubDate>Mon, 13 Jul 2026 12:00:00 GMT</pubDate>
            <description><![CDATA[Packaging a directory into a deployable archive — most commonly zipping a Lambda]]></description>
            <content:encoded><![CDATA[<p>Packaging a directory into a deployable archive — most commonly zipping a Lambda
function's source into <code>handler.zip</code> before <code>terraform plan</code>/<code>apply</code> — has always
meant reaching for a shell-based hook that wraps the <code>zip</code>/<code>tar</code> binary. That works
until you actually depend on it: the flags aren't even the same between BSD <code>tar</code>
(macOS) and GNU <code>tar</code> (most Linux CI images), errors surface as opaque shell exit
codes instead of anything typed, and — the part that's easy to miss — the archive you
get back isn't reproducible. Build the exact same source twice and you get two
different files. A new <code>archive</code> step type fixes all three: implemented on the Go
standard library only, it behaves identically everywhere Atmos runs, validates its
config before touching the filesystem, and can now produce byte-identical output for
identical input.</p>
<h2 class="anchor anchorTargetStickyNavbar_K69Q" id="the-problem">The Problem<a href="https://atmos.tools/changelog/archive-step-type#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>This surfaced while migrating a Terragrunt Lambda example (Lambda + DynamoDB + IAM
role) to Atmos. The source unit used a <code>before_hook "package"</code> wrapping
<code>scripts/package.sh</code>, which itself wrapped the <code>zip</code> binary, before every
<code>plan</code>/<code>apply</code>/<code>destroy</code>. Translating that directly meant an equivalent shell-based
hook:</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">package</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"> command</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">command</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> bash</span></span><br></div><div class="token-line 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 string" style="color:rgb(173, 219, 103)">"-c"</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)">"cd src &amp;&amp; zip -r ../handler.zip . -x '*.test.js'"</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">before.terraform.plan</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> before.terraform.apply</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> before.terraform.destroy</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span></span><br></div></code></pre></div></div>
<p>Three problems with this, once you look past "it worked when I tested it":</p>
<ul>
<li class=""><strong>The invocation isn't even portable between macOS and Linux</strong>, let alone Windows.
<code>zip -x</code> and <code>tar --exclude</code> take different glob syntax; BSD <code>tar</code> (what macOS
ships) and GNU <code>tar</code> (most Linux CI images) disagree on flags like <code>--exclude</code> vs.
<code>-X excludefile</code>. Two engineers on the same team can get different results running
the "same" hook.</li>
<li class=""><strong>Failures are opaque.</strong> A typo in a glob, a missing source directory — all of it
surfaces as a shell exit code with no structure Atmos can validate ahead of time.</li>
<li class=""><strong>The output isn't reproducible.</strong> Zip and tar both bake in each file's real
modification time and permission bits. A fresh <code>git clone</code> sets every file's mtime
to checkout time, and umask varies across machines and CI images — so identical
source content produces a <em>different archive</em> on every rebuild. This is the same
failure mode Terraform's own <code>archive_file</code> provider has been
<a href="https://github.com/hashicorp/terraform-provider-archive/issues/34" target="_blank" rel="noopener noreferrer" class="">reported for</a>
over the years: two runs, same input, different checksum. Anything downstream that
keys off the archive's hash — Lambda only redeploying when the zip's checksum
changes, a build cache, a provenance check — sees a "change" that isn't one.</li>
</ul>
<p>A <code>data "archive_file"</code> Terraform data source was tried first for the packaging step
itself. It works fine when a config references the data source's own output attribute
directly (<code>output_path</code>, <code>output_base64sha256</code>) — Terraform's graph orders that
correctly. It broke here because the migrated module computed the zip path
independently in a <code>locals</code> block, mirroring the original Terragrunt script's own
variable, instead of referencing the data source's attribute — so there was no
dependency edge forcing <code>archive_file</code> to run first. That's not a one-off: it's a
<a href="https://github.com/hashicorp/terraform/issues/30042" target="_blank" rel="noopener noreferrer" class="">documented class of bug</a>,
closed once the reporter switched to referencing the output attribute directly — the
same fix this migration's module hadn't made. A <code>before.terraform.*</code> hook sidesteps
the whole class of problem
structurally — it runs and completes before Terraform's graph is even evaluated, so
there's no reference to get wrong.</p>
<h2 class="anchor anchorTargetStickyNavbar_K69Q" id="the-fix">The Fix<a href="https://atmos.tools/changelog/archive-step-type#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>The new <code>archive</code> step type packages a directory or file into a <code>zip</code>, <code>tar</code>, or
<code>tgz</code> archive using only Go's standard library — <code>archive/zip</code>, <code>archive/tar</code>,
<code>compress/gzip</code>. No shelling out, so the same config produces the same archive
structure everywhere Atmos runs:</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"> package</span></span><br></div><div class="token-line 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"> 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">source</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> src/</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">destination</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> handler.zip</span></span><br></div><div class="token-line 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><br></div><div class="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 string" style="color:rgb(173, 219, 103)">"**/*.test.js"</span><span class="token plain"></span></span><br></div><div class="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 string" style="color:rgb(173, 219, 103)">"**/node_modules/**"</span></span><br></div></code></pre></div></div>
<p>It has no dedicated hook kind — like every step type added since
<a class="" href="https://atmos.tools/changelog/hooks-step-types"><code>kind: step</code></a> shipped, it reaches hooks through the same
bridge, so it works as a lifecycle hook with zero extra plumbing:</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">package</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"> step</span></span><br></div><div class="token-line 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"> 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">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">before.terraform.plan</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> before.terraform.apply</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> before.terraform.destroy</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">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">source</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> src/</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">destination</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> handler.zip</span></span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_K69Q" id="how-to-use-it">How to Use It<a href="https://atmos.tools/changelog/archive-step-type#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>
<ul>
<li class=""><code>source</code> / <code>destination</code> — required. What to archive, and where to write it.</li>
<li class=""><code>format</code> — <code>zip</code>, <code>tar</code>, <code>tgz</code>, <code>tar.bz2</code>, or <code>tar.xz</code>. Inferred from
<code>destination</code>'s extension when omitted (writing <code>tar.bz2</code>/<code>tar.xz</code> isn't
implemented yet — see below).</li>
<li class=""><code>subpath</code> — nests <code>source</code>'s content under a path inside the archive, e.g.
<code>subpath: opt/nodejs</code> for a Lambda Layer.</li>
<li class=""><code>include</code> / <code>exclude</code> — glob filters, evaluated exclude-then-include.</li>
<li class=""><code>action</code> — <code>replace</code> (default) always rebuilds the archive fresh from <code>source</code>.
<code>update</code> adds/refreshes entries in an existing archive without touching the rest —
supported for <code>zip</code> and uncompressed <code>tar</code> only, since <code>tgz</code>/<code>tar.bz2</code>/<code>tar.xz</code>
compress the whole stream as one unit and can't be edited surgically. Selecting
<code>update</code> on one of those formats fails with a clear error instead of silently
falling back to a full rebuild.</li>
</ul>
<p><code>create</code> and <code>extract</code> are reserved in the schema for a future release, so it won't
need a breaking change to add them later.</p>
<h2 class="anchor anchorTargetStickyNavbar_K69Q" id="reproducible-output">Reproducible Output<a href="https://atmos.tools/changelog/archive-step-type#reproducible-output" class="hash-link" aria-label="Direct link to Reproducible Output" title="Direct link to Reproducible Output" translate="no">​</a></h2>
<p>A native step type fixes the shelling-out problems, but not the reproducibility one
by itself — by default, entries still carry the source files' real mtime and
permission bits (same as omitting the field, or setting it to <code>filesystem</code>
explicitly). Set <code>mtime: epoch</code> or <code>mtime: git</code> to fix that too:</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"> package</span></span><br></div><div class="token-line 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"> 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">source</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> src/</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">destination</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> handler.zip</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">mtime</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> epoch</span></span><br></div></code></pre></div></div>
<p><code>mtime</code> names the mechanism, not an outcome: it's the modification-time metadata
stamped into each <em>archive entry</em> — not the source files on disk, and not the
archive file's own OS-level mtime.</p>
<ul>
<li class=""><code>filesystem</code> — the default. Every entry carries the source file's real mtime and
permission bits.</li>
<li class=""><code>epoch</code> — every entry gets the same timestamp: the most recent Git commit that
touched anything under <code>source</code>. One timestamp, whole archive. Named after the
<a href="https://reproducible-builds.org/docs/source-date-epoch/" target="_blank" rel="noopener noreferrer" class=""><code>SOURCE_DATE_EPOCH</code></a>
reproducible-builds convention, which this mirrors conceptually — one shared
reference timestamp for the whole build — even though the value here comes from
Git history rather than an environment variable.</li>
<li class=""><code>git</code> — each entry gets its own timestamp, from its most recent commit. Files
with no Git history (build output, <code>node_modules/</code>) fall back to the same value
<code>epoch</code> would use.</li>
</ul>
<p><code>epoch</code> and <code>git</code> both also normalize permission bits (<code>0644</code>, or <code>0755</code> if the
source is executable), since inconsistent umask-derived permissions produce different
archive bytes just as reliably as inconsistent timestamps do. Timestamps come from
Git commit history via <code>go-git</code> — no shelling out to <code>git log</code>, and no dependency on
<code>SOURCE_DATE_EPOCH</code> being threaded through every tool in the chain. Outside a Git
repository, both modes fall back to a fixed reference date rather than failing the
step. It's opt-in: existing workflows that don't set <code>mtime</code> see no change in
behavior.</p>
<p><strong><code>action: replace</code> + <code>mtime</code> is idempotent — <code>action: update</code> is not.</strong> With
<code>replace</code>, the same <code>source</code> produces the same bytes on every rerun, because
<code>replace</code> always rebuilds from scratch. <code>update</code> doesn't get that guarantee even with
<code>mtime</code> set: its existing entries keep whatever mtime/mode a prior write already gave
them, and only the entries a given <code>update</code> call adds or refreshes get normalized —
so the final bytes depend on the archive's history, not just <code>source</code>'s current
content. If you need the idempotent guarantee, use <code>replace</code>.</p>
<h2 class="anchor anchorTargetStickyNavbar_K69Q" id="get-involved">Get Involved<a href="https://atmos.tools/changelog/archive-step-type#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>See the <a class="" href="https://atmos.tools/workflows/steps/type/archive">archive step reference</a> for the full field
list, and the <a class="" href="https://atmos.tools/stacks/hooks#kind-step-run-a-step-type">hooks reference</a> for using it
as a lifecycle hook. Questions or ideas? Join us in the
<a href="https://cloudposse.com/slack" target="_blank" rel="noopener noreferrer" class="">Cloud Posse community Slack</a>.</p>]]></content:encoded>
            <category>Feature</category>
        </item>
        <item>
            <title><![CDATA[oci:// Sources Now Work with JIT Auto-Provisioning]]></title>
            <link>https://atmos.tools/changelog/oci-source-jit-provisioning</link>
            <guid>https://atmos.tools/changelog/oci-source-jit-provisioning</guid>
            <pubDate>Mon, 13 Jul 2026 12:00:00 GMT</pubDate>
            <description><![CDATA[A component with an oci true failed the moment you ran any Terraform operation against it. JIT auto-provisioning (the before.terraform.init hook) failed with go-getter's download not supported for scheme 'oci', even though atmos vendor pull handled the exact same source fine. Registries distributing modules in OpenTofu's native OCI module-package format couldn't be pulled by either path at all.]]></description>
            <content:encoded><![CDATA[<p>A component with an <code>oci://</code> source and <code>provision.workdir.enabled: true</code> failed the moment you ran any Terraform operation against it. JIT auto-provisioning (the <code>before.terraform.init</code> hook) failed with go-getter's <code>download not supported for scheme 'oci'</code>, even though <code>atmos vendor pull</code> handled the exact same source fine. Registries distributing modules in OpenTofu's native OCI module-package format couldn't be pulled by either path at all.</p>
<h2 class="anchor anchorTargetStickyNavbar_K69Q" id="the-problem">The Problem<a href="https://atmos.tools/changelog/oci-source-jit-provisioning#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="">JIT auto-provisioning and <code>atmos vendor pull</code> had two separate, non-overlapping implementations of "download a source." Only the vendor-pull one understood <code>oci://</code>.</li>
<li class="">Registries publishing modules via OpenTofu's native "install modules from OCI registries" format ship their content as a ZIP-archive layer, not the tar+gzip layer Atmos expected. Pulling one failed with <code>archive/tar: invalid tar header</code> regardless of which path you used.</li>
<li class="">OCI pulls also had no timeout, so a slow or unresponsive registry could hang a command indefinitely.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_K69Q" id="the-fix">The Fix<a href="https://atmos.tools/changelog/oci-source-jit-provisioning#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<ul>
<li class="">The OCI-fetch implementation moved into a shared <code>pkg/oci</code> package so both <code>atmos vendor pull</code> and JIT auto-provisioning use the same implementation instead of two divergent ones.</li>
<li class="">The puller now recognizes ZIP-layer OCI artifacts (OpenTofu's module-package format) in addition to Atmos's own tar+gzip format, with the same directory-traversal and decompression-size guards either way.</li>
<li class="">OCI pulls are now bounded by a 10-minute timeout, matching the existing go-getter download path.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_K69Q" id="how-to-use-it">How to Use It<a href="https://atmos.tools/changelog/oci-source-jit-provisioning#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">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">my-component</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">source</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">uri</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)">"oci://ghcr.io/my-org/my-module:v1.2.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 key atrule">provision</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">workdir</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>Running <code>atmos terraform plan my-component -s &lt;stack&gt;</code> now auto-provisions the source before running, the same way it already does for git and HTTP sources.</p>
<p>Authentication works the same way it already does for <code>atmos vendor pull</code>: your existing registry credentials are picked up automatically, with an anonymous fallback if none are configured.</p>
<h2 class="anchor anchorTargetStickyNavbar_K69Q" id="get-involved">Get Involved<a href="https://atmos.tools/changelog/oci-source-jit-provisioning#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>See the <a class="" href="https://atmos.tools/stacks/components/provision/workdir">Workdir Provisioning</a> docs for the full <code>provision.workdir</code> reference, or open an issue if you hit an OCI registry format that still doesn't extract cleanly.</p>]]></content:encoded>
            <category>Feature</category>
            <category>Bug Fix</category>
        </item>
        <item>
            <title><![CDATA[Bulk `terraform init --all` and `--affected`]]></title>
            <link>https://atmos.tools/changelog/terraform-init-bulk-execution</link>
            <guid>https://atmos.tools/changelog/terraform-init-bulk-execution</guid>
            <pubDate>Mon, 13 Jul 2026 12:00:00 GMT</pubDate>
            <description><![CDATA[Bulk commands like terraform apply, plan, and destroy could already run across every component in dependency order with --all, but init couldn't — reinitializing a whole stack meant scripting a loop over components yourself, or falling back to one-at-a-time runs.]]></description>
            <content:encoded><![CDATA[<p>Bulk commands like <code>terraform apply</code>, <code>plan</code>, and <code>destroy</code> could already run across every component in dependency order with <code>--all</code>, but <code>init</code> couldn't — reinitializing a whole stack meant scripting a loop over components yourself, or falling back to one-at-a-time runs.</p>
<h2 class="anchor anchorTargetStickyNavbar_K69Q" id="the-problem">The Problem<a href="https://atmos.tools/changelog/terraform-init-bulk-execution#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="">Bulk execution flags <code>--all</code> and <code>--affected</code> landed on <code>apply</code>/<code>plan</code>/<code>destroy</code> when Terraform bulk execution moved onto the scheduler-backed dependency graph, but <code>init</code> was left out.</li>
<li class="">Reinitializing every component after a provider upgrade, or bootstrapping a new environment, meant looping <code>atmos terraform init &lt;component&gt; -s &lt;stack&gt;</code> by hand.</li>
<li class="">The scheduler also capped concurrency to <code>1</code> for any subcommand it didn't explicitly recognize, so there was no way to route around it either.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_K69Q" id="the-fix">The Fix<a href="https://atmos.tools/changelog/terraform-init-bulk-execution#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<ul>
<li class=""><code>terraform init</code> now accepts <code>--all</code>, <code>--affected</code>, <code>--max-concurrency</code>, <code>--failure-mode</code>, and <code>--log-order</code>, matching <code>destroy</code>.</li>
<li class="">Init keeps the natural forward dependency order — prerequisites before dependents — unlike <code>destroy</code>, which reverses the graph.</li>
<li class="">Concurrent bulk init automatically disables the shared provider plugin cache for worker subprocesses, since sharing it isn't safe across concurrent <code>terraform init</code> runs.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_K69Q" id="how-to-use-it">How to Use It<a href="https://atmos.tools/changelog/terraform-init-bulk-execution#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-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 comment" style="color:rgb(99, 119, 119);font-style:italic"># Initialize every Terraform component, in dependency order</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos terraform init </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--all</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-s</span><span class="token plain"> prod</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"># Initialize only the affected components</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos terraform init </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--affected</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"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Run independent components concurrently</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos terraform init </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--all</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-s</span><span class="token plain"> prod --max-concurrency </span><span class="token number" style="color:rgb(247, 140, 108)">4</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"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Keep going past a failed component instead of stopping</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos terraform init </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--all</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-s</span><span class="token plain"> prod --failure-mode keep-going</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_K69Q" id="get-involved">Get Involved<a href="https://atmos.tools/changelog/terraform-init-bulk-execution#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>Have a bulk-execution flag you'd like to see on another command? Open an issue or join the discussion on <a href="https://github.com/cloudposse/atmos" target="_blank" rel="noopener noreferrer" class="">GitHub</a>.</p>]]></content:encoded>
            <category>Feature</category>
        </item>
        <item>
            <title><![CDATA[Get the exact stack-manifest schema for the Atmos you have installed]]></title>
            <link>https://atmos.tools/changelog/atmos-stack-schema-command</link>
            <guid>https://atmos.tools/changelog/atmos-stack-schema-command</guid>
            <pubDate>Mon, 13 Jul 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Editors, CI pipelines, and offline environments that want to validate stack manifests locally]]></description>
            <content:encoded><![CDATA[<p>Editors, CI pipelines, and offline environments that want to validate stack manifests locally
have had one option: fetch the JSON Schema from <code>atmos.tools</code> over the network and hope it
matches whatever <code>atmos</code> binary you actually have installed. There was no way to just ask your
own binary for its schema.</p>
<h2 class="anchor anchorTargetStickyNavbar_K69Q" id="the-fix">The Fix<a href="https://atmos.tools/changelog/atmos-stack-schema-command#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>A new command, <code>atmos stack schema</code>, prints the JSON Schema Atmos uses to validate stack
manifests — the exact one built into the binary you're running, not a version fetched from the
internet. Pass a path and it writes the schema to a file instead of stdout.</p>
<p>This is useful for:</p>
<ul>
<li class=""><strong>Offline/air-gapped environments</strong> — no network call needed, since the schema comes straight
out of the binary already on disk.</li>
<li class=""><strong>IDE setup</strong> — point your editor's YAML language server at a local file instead of a URL.</li>
<li class=""><strong>Version certainty</strong> — the output always matches the <code>atmos</code> version you ran it with, so there's
no risk of validating against a schema that's ahead of or behind your binary.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_K69Q" id="how-to-use-it">How to Use It<a href="https://atmos.tools/changelog/atmos-stack-schema-command#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-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 comment" style="color:rgb(99, 119, 119);font-style:italic"># Print the schema to stdout.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos stack schema</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"># Write it to a file for your editor or CI to use.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos stack schema ./atmos-manifest.json</span><br></div></code></pre></div></div>
<p>It lives under the existing <code>atmos stack</code> command group, alongside the other stack-manifest
commands (<code>get</code>, <code>set</code>, <code>delete</code>, <code>format</code>, <code>config</code>).</p>]]></content:encoded>
            <category>DX</category>
        </item>
    </channel>
</rss>