<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>atmos Blog</title>
        <link>https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog</link>
        <description>atmos Blog</description>
        <lastBuildDate>Mon, 07 Sep 2026 13: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[Keep version fields in YAML files in sync without losing comments]]></title>
            <link>https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/version-tracker-yaml-manager</link>
            <guid>https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/version-tracker-yaml-manager</guid>
            <pubDate>Mon, 07 Sep 2026 13:00:00 GMT</pubDate>
            <description><![CDATA[A Helm values file, a docker-compose override, or any other hand-maintained YAML config often carries]]></description>
            <content:encoded><![CDATA[<p>A Helm values file, a docker-compose override, or any other hand-maintained YAML config often carries
one field that tracks an external dependency's version, alongside comments explaining what the
surrounding settings do and anchors sharing config between sections. Keeping that one field in sync
usually means either editing it by hand on every release, or running it through a full parse-and-
regenerate step that throws the comments and anchors away.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/version-tracker-yaml-manager#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>The <a class="" href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/version/files">Version Tracker</a>'s <code>template</code> manager covers YAML by treating
a <code>*.tmpl</code> source as the source of truth and rendering it to a sibling output file — a good fit when
the whole file is generated, but overkill for a hand-maintained file that only has one or two managed
fields. The <code>marker</code> manager can annotate a line with a comment, but its rewrite is a plain token
substitution, not an assignment into structured YAML. Neither manager patches a single field in an
existing, hand-authored YAML document while leaving everything else — comments, anchors, key order —
untouched.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/version-tracker-yaml-manager#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 <code>yaml</code> file manager writes locked values directly into YAML files at configured field paths. It
reuses Atmos's own format-preserving YAML editor — the same engine behind <code>atmos config set</code> and
<code>atmos stack set</code> — so comments, anchors and aliases, and key order on untouched fields all survive
the edit.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/version-tracker-yaml-manager#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">version</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">dependencies</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">cli</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">ecosystem</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> github/releases</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">datasource</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> github</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">releases</span></span><br></div><div class="token-line 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"> github</span></span><br></div><div class="token-line 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"> cli/cli</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">desired</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)">"~2"</span><span class="token plain"></span></span><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">files</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> </span><span class="token key atrule">manager</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> yaml</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">paths</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="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"> charts/</span><span class="token important">*/values.yaml</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">options</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">set</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="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">path</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> version</span></span><br></div><div class="token-line 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"> cli</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">            </span><span class="token key atrule">format</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)">'{{ trimPrefix "v" .Version }}'</span></span><br></div></code></pre></div></div>
<p><code>atmos version track apply</code> rewrites the configured field from the lock, stripping the <code>v</code> prefix
GitHub tags carry via the optional <code>format</code> template; <code>--check</code> fails and lists any file that's out
of date, so CI can catch drift before it merges.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/version-tracker-yaml-manager#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>See the <a class="" href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/version/files#updating-yaml-files">Version Files</a> docs for the full path
syntax and the <code>format</code> field. Have feedback on this feature?
<a href="https://github.com/cloudposse/atmos/issues" target="_blank" rel="noopener noreferrer" class="">Open an issue</a> or join the conversation 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[Reshape a version before writing it into a JSON file]]></title>
            <link>https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/json-manager-format</link>
            <guid>https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/json-manager-format</guid>
            <pubDate>Mon, 07 Sep 2026 12:00:00 GMT</pubDate>
            <description><![CDATA[Git tags on GitHub almost always carry a v prefix — v1.228.0 — because that's the convention]]></description>
            <content:encoded><![CDATA[<p>Git tags on GitHub almost always carry a <code>v</code> prefix — <code>v1.228.0</code> — because that's the convention
both <code>git tag</code> and GitHub releases nudge toward. Package manifests, on the other hand, almost never
want that prefix: <code>package.json</code>, plugin manifests, and marketplace listings all expect bare
semver. Whenever a version comes from GitHub and needs to land in one of those files, something has
to strip the <code>v</code> first.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/json-manager-format#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>The <a class="" href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/version/files">Version Tracker</a>'s <code>json</code> file manager writes a locked
dependency's resolved value directly into a JSON field, byte-for-byte. For a dependency sourced
from <code>github-releases</code> or <code>github-tags</code>, that resolved value is the raw git tag — so a target field
that needed bare semver got <code>v1.228.0</code> verbatim, with no way to reshape it before the write.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/json-manager-format#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p><code>options.set</code> entries in the <code>json</code> manager now accept an optional <code>format</code>: a small Go template
rendered against the resolved version, whose output replaces the verbatim value instead. Trimming a
<code>v</code> prefix is the common case, but any Sprig string function — <code>trimSuffix</code>, <code>replace</code>,
<code>regexReplaceAll</code> — is available too.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/json-manager-format#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">version</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">files</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> </span><span class="token key atrule">manager</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> json</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">paths</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="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"> package.json</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">options</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">set</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="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">path</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> version</span></span><br></div><div class="token-line 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"> cli</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">            </span><span class="token key atrule">format</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)">'{{ trimPrefix "v" .Version }}'</span></span><br></div></code></pre></div></div>
<p>Leaving <code>format</code> off keeps today's default: the resolved value is written verbatim, exactly as
before.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/json-manager-format#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>See the <a class="" href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/version/files#updating-json-files">Version Files</a> docs for the full
<code>set</code> syntax. Have feedback on this feature? <a href="https://github.com/cloudposse/atmos/issues" target="_blank" rel="noopener noreferrer" class="">Open an issue</a>
or join the conversation in the <a href="https://cloudposse.com/slack" target="_blank" rel="noopener noreferrer" class="">Cloud Posse community Slack</a>.</p>]]></content:encoded>
            <category>Enhancement</category>
        </item>
        <item>
            <title><![CDATA[Declarative Release Lifecycle for Native Helm Components]]></title>
            <link>https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/native-helm-release-lifecycle</link>
            <guid>https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/native-helm-release-lifecycle</guid>
            <pubDate>Mon, 07 Sep 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Shipping a Helm release is rarely a single helm upgrade --install. A first install onto a cold cluster needs a generous timeout; a routine upgrade should fail fast. A broken upgrade should roll back and clean up the resources it left behind; a broken first install should uninstall itself so it doesn't wedge the next attempt. Some releases must wait for their Jobs to finish, others only for a readiness gate, and a few shouldn't wait at all. Getting this right usually means memorizing a pile of Helm flags and threading them into shell wrappers per command — and trusting that every environment runs the same incantation.]]></description>
            <content:encoded><![CDATA[<p>Shipping a Helm release is rarely a single <code>helm upgrade --install</code>. A first install onto a cold cluster needs a generous timeout; a routine upgrade should fail fast. A broken upgrade should roll back and clean up the resources it left behind; a broken first install should uninstall itself so it doesn't wedge the next attempt. Some releases must wait for their Jobs to finish, others only for a readiness gate, and a few shouldn't wait at all. Getting this right usually means memorizing a pile of Helm flags and threading them into shell wrappers per command — and trusting that every environment runs the same incantation.</p>
<p>Native Helm components in Atmos now let you declare that entire lifecycle as configuration — per operation — and inherit it the same way you inherit everything else in a stack.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/native-helm-release-lifecycle#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>Helm exposes the knobs — waiting, timeouts, atomic upgrades, cleanup-on-failure, history retention, waiting for Jobs, CRD handling, hook control — but only as flags on individual command invocations. That has two costs:</p>
<ul>
<li class=""><strong>The policy lives in shell history, not in your repo.</strong> The intent behind a release ("wait for the watcher, keep ten revisions, roll back on a failed upgrade") is invisible to the next person and drifts between laptops, CI, and production because nothing pins it down.</li>
<li class=""><strong>One flat set of flags can't express operation-specific intent.</strong> A slow first install and a quick upgrade want different timeouts. Rollback is the right recovery for an upgrade but meaningless on a first install — there is no previous revision to return to. Uninstall-on-failure is the opposite: exactly right for a first install, wrong for an upgrade you want to preserve. A single set of flags forces one compromise across all three.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/native-helm-release-lifecycle#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>Native Helm components take a <code>release</code> policy with release-wide defaults and operation-specific overlays for <code>install</code>, <code>upgrade</code>, and <code>delete</code>. The whole tree deep-merges through your stack defaults, abstract/base components, and the concrete component — so a platform team can set org-wide defaults and individual components override only what they need. Explicit CLI flags still win at the highest precedence, so incident-time overrides remain a one-liner.</p>
<p>The policy covers the lifecycle end to end:</p>
<ul>
<li class=""><strong>Wait strategy</strong> — pick the status watcher, a hook-only wait, or legacy waiting, and optionally wait for Jobs to complete.</li>
<li class=""><strong>Per-operation timeouts</strong> — a long budget for the first install, a short one for upgrades and deletes.</li>
<li class=""><strong>Failure recovery</strong> — uninstall a failed first install; roll back a failed upgrade and clean up its partial resources.</li>
<li class=""><strong>History retention, chart hooks, and CRD policy</strong> — keep N revisions, enable or skip chart hooks, and choose whether CRDs are created or left alone.</li>
<li class=""><strong>Dry run</strong> — preview an apply without persisting a release or touching the cluster.</li>
</ul>
<p>Invalid combinations fail early and clearly — asking for <code>rollback</code> on an install, or a field that doesn't apply to the selected operation, is rejected before anything runs rather than silently ignored.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/native-helm-release-lifecycle#how-to-use-it" class="hash-link" aria-label="Direct link to How to Use It" title="Direct link to How to Use It" translate="no">​</a></h2>
<p>Declare the lifecycle on the component. Release-wide settings sit at the top; <code>install</code>, <code>upgrade</code>, and <code>delete</code> refine them:</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">helm</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line 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-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">chart</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 class="token plain"></span></span><br></div><div class="token-line 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"> my</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">app</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">release</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">timeout</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> 4m</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">wait</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">          </span><span class="token key atrule">strategy</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> watcher</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">history</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line 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</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)">10</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">install</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">          </span><span class="token key atrule">timeout</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> 10m            </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># a cold-start install gets more room</span><span class="token plain"></span></span><br></div><div class="token-line 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_failure</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> uninstall   </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># don't leave a wedged half-install behind</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">upgrade</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line 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_failure</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> rollback    </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># return to the last good revision</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">          </span><span class="token key atrule">cleanup_on_failure</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">delete</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">          </span><span class="token key atrule">wait</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">            </span><span class="token key atrule">strategy</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> legacy</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">values</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">replicaCount</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)">2</span></span><br></div></code></pre></div></div>
<p>Atmos selects the operation for you and applies the matching overlay:</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 helm apply my-app </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-s</span><span class="token plain"> dev            </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># install or upgrade, per the release's state</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos helm apply my-app </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-s</span><span class="token plain"> dev --dry-run  </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># preview, no release persisted</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos helm apply my-app </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-s</span><span class="token plain"> dev </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--timeout</span><span class="token plain"> 15m   </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># incident-time override wins</span><br></div></code></pre></div></div>
<p>Native Helm support is still experimental (Atmos prints a 🧪 notice when you use it), so the surface may evolve — but the release policy above is what you'll reach for to make deployments deterministic across environments.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/native-helm-release-lifecycle#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>The full contract lives in the native Helm release lifecycle PRD in the repo, and the <code>atmos-helm</code> skill documents day-to-day usage. If you run Helm through Atmos, try declaring a <code>release</code> policy on a component and tell us where the defaults or precedence surprised you — that feedback is what shapes the feature out of experimental.</p>]]></content:encoded>
            <category>Feature</category>
            <category>Experimental</category>
        </item>
        <item>
            <title><![CDATA[Automatically Create the Configured Namespace for Helm Releases]]></title>
            <link>https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/native-helm-create-namespace</link>
            <guid>https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/native-helm-create-namespace</guid>
            <pubDate>Wed, 02 Sep 2026 12:00:00 GMT</pubDate>
            <description><![CDATA[Atmos lets you configure the Kubernetes namespace where a Helm release should be installed. This]]></description>
            <content:encoded><![CDATA[<p>Atmos lets you configure the Kubernetes namespace where a Helm release should be installed. This
prevents charts that do not specify a namespace from being installed into <code>default</code>.</p>
<p>That namespace may not exist. Native Helm creates it for you automatically, so a release
deploys in a single operation instead of requiring a separate command, component, or workflow to
create the namespace first.</p>
<p>Sometimes, though, the deployment should not be creating namespaces at all.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/native-helm-create-namespace#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>A Helm chart does not always specify the namespace where its resources should be installed. Atmos
solves this by installing the release into the namespace configured for the component:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token 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">helm</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line 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-api</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">chart</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)">"backend-api"</span><span class="token plain"></span></span><br></div><div class="token-line 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"> backend</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">api</span></span><br></div></code></pre></div></div>
<p>This keeps the release out of the <code>default</code> namespace, and native Helm creates the namespace
automatically when it is missing, so the deployment is self-contained.</p>
<p>Automatic creation is not always wanted. When a platform team owns the namespace along with its
labels, quotas, and NetworkPolicies, the release should not create it. And when the deploy identity
is scoped to a single namespace and cannot create namespaces, the forced creation fails with a <code>403</code>,
even when the namespace already exists.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/native-helm-create-namespace#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>Native Helm components now support <code>create_namespace</code>. It defaults to <code>true</code>, so the namespace is
created automatically as before. Set it to <code>false</code> to install into a pre-existing namespace instead:</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">helm</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line 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-api</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">chart</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)">"backend-api"</span><span class="token plain"></span></span><br></div><div class="token-line 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"> backend</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">api</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">create_namespace</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token boolean important" style="color:rgb(255, 88, 116)">false</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">values</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">replicaCount</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)">1</span></span><br></div></code></pre></div></div>
<p>The release then deploys into the namespace that already exists, with no cluster-level permission to
create namespaces:</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 helm apply backend-api </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-s</span><span class="token plain"> plat-ue2-dev</span><br></div></code></pre></div></div>
<p>Left at its default, Helm creates the namespace when it is missing. Set to <code>false</code>, Helm installs
into the namespace that is already there.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="when-to-use-it">When to Use It<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/native-helm-create-namespace#when-to-use-it" class="hash-link" aria-label="Direct link to When to Use It" title="Direct link to When to Use It" translate="no">​</a></h2>
<p>Keep <code>create_namespace</code> enabled (the default) when the Helm deployment should manage its own namespace
and the deploying identity has permission to create namespaces.</p>
<p>Set it to <code>false</code> when namespaces are managed separately, for example when a platform component is
responsible for namespace labels, quotas, NetworkPolicies, or other guardrails, or when the deploy
identity is scoped to a single namespace.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/native-helm-create-namespace#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>Atmos is open source and we'd love your feedback. Join the conversation in the
<a href="https://cloudposse.com/slack" target="_blank" rel="noopener noreferrer" class="">Atmos community Slack</a> or open an issue on
<a href="https://github.com/cloudposse/atmos" target="_blank" rel="noopener noreferrer" class="">GitHub</a>.</p>]]></content:encoded>
            <category>Enhancement</category>
        </item>
        <item>
            <title><![CDATA[Toolchain Installs Are Reproducible by Default Now]]></title>
            <link>https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/toolchain-lockfile-default</link>
            <guid>https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/toolchain-lockfile-default</guid>
            <pubDate>Tue, 01 Sep 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Atmos's toolchain has had a lockfile for a while. The lockfile records the exact resolved artifact]]></description>
            <content:encoded><![CDATA[<p>Atmos's toolchain has had a lockfile for a while. The lockfile records the exact resolved artifact
and checksum for each platform. A package manager's lockfile pins a dependency tree the same way.
But the lockfile was opt-in. The setting was not documented anywhere a user could find it. Almost
nobody turned it on. Almost nobody's installs were actually reproducible. The installs only looked
reproducible, because the version string matched.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/toolchain-lockfile-default#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>A version in <code>.tool-versions</code> pins what you asked for. It does not pin what Atmos actually
installed. Every <code>atmos toolchain install</code> command resolves that version against the live registry
again. The exact download URL, checksum, and platform artifact are not fixed anywhere. Only the
version number is fixed.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/toolchain-lockfile-default#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>Toolchain installs now write a lockfile by default. You do not need to configure anything. Run
<code>atmos toolchain install</code>. Atmos records the exact resolved version, download URL, checksum, and
size for your platform. Installs skip a tool that already exists on disk, so an already-installed
tool will not get a lockfile entry until you run <code>atmos toolchain lock</code> (or reinstall it with
<code>atmos toolchain install --reinstall</code>). Once every tool has an entry, the next install resolves
against the lockfile instead of asking the registry again, on your machine, a teammate's, or in
CI. Reproducibility holds per platform: everyone on an operating system and architecture with a
matching lock entry gets the same artifact, byte for byte.</p>
<p>If a project's <code>atmos.yaml</code> pins an edition dated before this change, the project keeps the old
opt-in behavior. Nothing changes for a project that relied on the previous default. New and
unpinned projects get the lockfile from the start.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/toolchain-lockfile-default#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>You do not need to opt in. Install as usual:</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><br></div></code></pre></div></div>
<p>Commit the resulting <code>toolchain.lock.yaml</code> file next to <code>.tool-versions</code>. If some of those tools
were already installed before you ran this, run <code>atmos toolchain lock</code> too -- <code>atmos toolchain install</code> won't touch a tool it finds already on disk, so it can leave that tool's entry missing.
Once every tool has an entry, every install resolves the exact pinned artifact for that platform.
This applies on your machine, a teammate's machine, and a CI runner. Atmos does not resolve the
version against the registry again.</p>
<p>The <code>atmos toolchain</code> command is still experimental. Its interface may change. The reproducibility
does not depend on that.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/toolchain-lockfile-default#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>If you already use the toolchain, check whether <code>toolchain.lock.yaml</code> has an entry for every tool
in <code>.tool-versions</code>. Run <code>atmos toolchain lock</code> to fill in any <code>atmos toolchain install</code> skipped
because they were already installed, then commit the lockfile. If your installs still do not
reproduce the same way across machines with matching lock entries, <a href="https://github.com/cloudposse/atmos/issues" target="_blank" rel="noopener noreferrer" class="">open an
issue</a>. That is exactly the gap this fix closes.</p>]]></content:encoded>
            <category>Experimental</category>
            <category>Enhancement</category>
        </item>
        <item>
            <title><![CDATA[Component retry now covers Helmfile, Packer, and Ansible too]]></title>
            <link>https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/retry-helmfile-packer-ansible</link>
            <guid>https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/retry-helmfile-packer-ansible</guid>
            <pubDate>Mon, 31 Aug 2026 13:00:00 GMT</pubDate>
            <description><![CDATA[Terraform components already recover from a transient error automatically — a 502, a dropped registry connection, an S3 backend timeout. Helmfile, Packer, and Ansible components in that same pipeline did not. The exact same class of failure that Terraform shrugged off would still fail your Helmfile sync or Ansible playbook outright, because a retry: block on either was silently inert. Now all four component types share the same retry engine.]]></description>
            <content:encoded><![CDATA[<p>Terraform components already recover from a transient error automatically — a 502, a dropped registry connection, an S3 backend timeout. Helmfile, Packer, and Ansible components in that same pipeline did not. The exact same class of failure that Terraform shrugged off would still fail your Helmfile sync or Ansible playbook outright, because a <code>retry:</code> block on either was silently inert. Now all four component types share the same retry engine.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/retry-helmfile-packer-ansible#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>The same class of error can just as easily hit <code>helmfile sync</code> pulling a chart, <code>packer build</code> downloading a plugin, or <code>ansible-playbook</code> reaching a remote inventory. None of those got the same protection until now.</p>
<p>That gap got harder to miss once stacks could set retry once for the whole stack. A stack-root <code>retry:</code> block reads as "every component here recovers from this." But that was only true for the Terraform components.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/retry-helmfile-packer-ansible#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p><code>retry:</code> now works the same way for every component type that shells out to a binary. Terraform, Helmfile, Packer, and Ansible all share the same retry engine. It captures the subprocess output, matches it against your <code>conditions</code> regex patterns, and retries with backoff only on a match.</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">helmfile</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">myapp</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">retry</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">max_attempts</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">5</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">backoff_strategy</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> exponential</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">initial_delay</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> 2s</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">conditions</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="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"> /Bad Gateway/</span></span><br></div><div class="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"> /connection reset/</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">packer</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">ami</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">retry</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">max_attempts</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">3</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">conditions</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="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"> /rate limit/</span></span><br></div></code></pre></div></div>
<p>Nothing changes for existing Terraform retry configuration. This change only adds new coverage. A real failure still fails immediately. Examples include a bad Helmfile release, a Packer template error, or a broken playbook. Only output that matches your <code>conditions</code> triggers a retry.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/retry-helmfile-packer-ansible#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>retry:</code> to any Helmfile, Packer, or Ansible component the same way you would for Terraform. See the <a class="" href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/stacks/components/terraform/retry">component retry docs</a> for the full field reference. A stack-root <code>retry:</code> block now protects every supported component in the stack.</p>
<p>Native Kubernetes and native Helm components don't shell out to a binary. They call Go SDKs directly. So they aren't covered by this change yet. That gap is tracked as a follow-up.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/retry-helmfile-packer-ansible#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>Open a discussion in the <a href="https://github.com/cloudposse/atmos" target="_blank" rel="noopener noreferrer" class="">Atmos repo</a>. Let us know if you hit a transient failure pattern in Helmfile, Packer, or Ansible that <code>conditions</code> doesn't catch cleanly.</p>]]></content:encoded>
            <category>Enhancement</category>
        </item>
        <item>
            <title><![CDATA[Distribute scaffold templates through your existing OCI registry]]></title>
            <link>https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/scaffold-oci-sources</link>
            <guid>https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/scaffold-oci-sources</guid>
            <pubDate>Mon, 31 Aug 2026 12:00:00 GMT</pubDate>
            <description><![CDATA[If your team already publishes container images, Atmos components, or Helm charts to a private]]></description>
            <content:encoded><![CDATA[<p>If your team already publishes container images, Atmos components, or Helm charts to a private
OCI registry, that registry is probably the most secure, versioned, and well-understood
distribution channel you have. Reusable project scaffolding rarely gets to use it — instead it
tends to live in its own git repository, with its own access controls and its own line in the
onboarding docs, just to hand out a <code>scaffold.yaml</code> and a handful of files.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/scaffold-oci-sources#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>Both <code>atmos scaffold generate</code> and <code>atmos init</code> could already pull templates from git, HTTPS, and
S3 sources, but nothing else. A team standardizing on OCI for internal distribution —
components, container images, Helm charts — had no way to publish a scaffold template the same
way. Templates were the one artifact type still forced onto a separate channel.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/scaffold-oci-sources#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>Both commands now accept an <code>oci://</code> source directly, pulled through the same client Atmos
already uses for <code>atmos vendor pull</code> and just-in-time component provisioning. Authentication
follows the identical precedence: Docker credentials from <code>docker login</code>, then
<code>ATMOS_GITHUB_TOKEN</code> for <code>ghcr.io</code>, then anonymous — nothing new to configure if OCI sources are
already working elsewhere in the project.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/scaffold-oci-sources#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>Point either command at an OCI reference the same way you would a git URL:</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 scaffold generate oci://ghcr.io/example/templates:v1.0.0 ./components/terraform/vpc</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos init oci://ghcr.io/example/templates:v1.0.0 ./my-project</span><br></div></code></pre></div></div>
<p>A version lives directly in the reference (<code>:v1.0.0</code>), the same way an OCI vendor source is
pinned — there's no separate <code>--ref</code> flag to learn for this case, since that flag only ever
applied to git sources. <code>--update</code>'s three-way merge, <code>--git</code>/<code>--no-git</code>, and <code>--base-ref</code> all
work exactly as they already do for every other source type: the merge base always comes from
the generated project's own git history, never from re-fetching the template, so switching a
template to OCI changes nothing about how updates behave.
A <code>scaffold.templates</code> entry in <code>atmos.yaml</code> can point at an <code>oci://...</code> source too, right
alongside existing git-hosted entries.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/scaffold-oci-sources#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p><a href="https://github.com/cloudposse/atmos/issues" target="_blank" rel="noopener noreferrer" class="">Open an issue</a> with feedback, or let us know what
registry you're publishing scaffold templates to.</p>]]></content:encoded>
            <category>Feature</category>
        </item>
        <item>
            <title><![CDATA[Set one retry policy for a whole stack]]></title>
            <link>https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/stack-level-retry-defaults</link>
            <guid>https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/stack-level-retry-defaults</guid>
            <pubDate>Mon, 31 Aug 2026 12:00:00 GMT</pubDate>
            <description><![CDATA[Component retry already recovers a single component from a transient error block onto each component, wire up a shared abstract base component just to hold it, or set up a mixin. Now you can define the policy once at the stack level, and every component in that stack inherits it automatically.]]></description>
            <content:encoded><![CDATA[<p>Component retry already recovers a single component from a transient error: a 502, a dropped registry connection, a flaky provider lookup. The hard part was sharing that same policy across every component in a stack. You'd copy the same <code>retry:</code> block onto each component, wire up a shared abstract base component just to hold it, or set up a mixin. Now you can define the policy once at the stack level, and every component in that stack inherits it automatically.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/stack-level-retry-defaults#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>Component retry matches transient failures against <code>conditions</code> regex patterns and retries with backoff. That mechanism works well for one component. Restructuring unrelated components to share an abstract base just so they inherit a policy, or setting up a mixin file with <code>overrides.retry</code> and importing it everywhere, gets you there too — but none of those match the real goal: every component in this stack should recover the same way, without extra plumbing.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/stack-level-retry-defaults#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>Stacks now accept a top-level <code>retry:</code> block. This works the same way as the existing top-level <code>vars</code>, <code>metadata</code>, and <code>hooks</code> blocks. Set it once at the root of a stack manifest. Every supported component in that stack then picks it up:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockTitle_JJ7b">stacks/deploy/prod.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">retry</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">max_attempts</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">5</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">backoff_strategy</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> exponential</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">initial_delay</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> 2s</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">max_delay</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> 30s</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">conditions</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="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"> /Bad Gateway/</span></span><br></div><div class="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"> /GOAWAY/</span></span><br></div><div class="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"> /could not query provider 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" style="display:inline-block"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain"></span><span class="token key atrule">components</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">terraform</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">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 comment" style="color:rgb(99, 119, 119);font-style:italic"># ...</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">transit-gateway</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="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"># ...</span></span><br></div></code></pre></div></div>
<p>A concrete component's <code>retry:</code> overrides stack and abstract-base values for keys it sets. Missing keys inherit from lower-precedence layers. The full precedence order, lowest to highest, is: stack-level default → abstract base component → concrete component → <code>overrides.retry</code>.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/stack-level-retry-defaults#how-to-use-it" class="hash-link" aria-label="Direct link to How to Use It" title="Direct link to How to Use It" translate="no">​</a></h2>
<p>Add <code>retry:</code> to the root of any stack manifest, alongside <code>vars:</code> and <code>components:</code>. You need no mixin file, no shared base component, and no per-component copies:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockTitle_JJ7b">stacks/deploy/prod.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">retry</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">max_attempts</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">3</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">conditions</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="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"> /Bad Gateway/</span></span><br></div><div class="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"> /connection reset/</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain" style="display:inline-block"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain"></span><span class="token key atrule">components</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">terraform</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">vpc</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">vars</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">name</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">rds</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">vars</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> rds</span></span><br></div></code></pre></div></div>
<p>Both <code>vpc</code> and <code>rds</code> retry on the same conditions without either one declaring <code>retry:</code> itself. If one component needs a different policy, set <code>retry:</code> directly on that component. Its values override lower-precedence layers unless <code>overrides.retry</code> sets the same keys. Missing keys continue through the precedence chain.</p>
<p>The mixin pattern from the <a class="" href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/stacks/components/terraform/retry#stack-level-defaults">component retry docs</a> is still the right tool for a policy that applies to only part of a stack.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/stack-level-retry-defaults#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>Open a discussion in the <a href="https://github.com/cloudposse/atmos" target="_blank" rel="noopener noreferrer" class="">Atmos repo</a> or post in the SweetOps Slack. Let us know if you hit a retry scenario that the current scoping (stack, base component, component, overrides) doesn't cover well.</p>]]></content:encoded>
            <category>Enhancement</category>
        </item>
        <item>
            <title><![CDATA[Prompt choices that follow earlier answers]]></title>
            <link>https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/scaffold-dynamic-options</link>
            <guid>https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/scaffold-dynamic-options</guid>
            <pubDate>Fri, 28 Aug 2026 12:00:00 GMT</pubDate>
            <description><![CDATA[Every interactive form with a fixed set of choices eventually hits the same problem: at some]]></description>
            <content:encoded><![CDATA[<p>Every interactive form with a fixed set of choices eventually hits the same problem: at some
point, what a question <em>should</em> offer depends on how an earlier question was answered. List every
possible environment when asking "which one deploys first," and people have to hunt through
options they never actually set up. Show raw values like <code>dev</code> or <code>prod</code> just to avoid maintaining
a separate label mapping, and people have to mentally translate those into what they actually
mean. The only real fix is letting choices adapt to prior answers — and letting them look nicer
than the underlying values.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/scaffold-dynamic-options#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>In a scaffold template, <code>select</code> and <code>multiselect</code> fields normally take their choices from
<code>options:</code>, a static list fixed at authoring time. That's fine when the choices really are fixed,
but two situations don't fit:</p>
<ul>
<li class="">Narrowing to a previous answer. Someone selects their environments (<code>dev</code>, <code>staging</code>,
<code>production</code>) via a <code>multiselect</code>; a later <code>select</code> field should default to offering just those chosen
environments — not the entire list the template supports.</li>
<li class="">Friendly labels vs. stored values. You want to display something readable while still storing
the actual value (<code>dev</code>/<code>staging</code>/<code>production</code>) that generated files and conditions rely on.
Previously this meant either showing raw values on screen, or hand-maintaining a separate label
mapping elsewhere in the template.</li>
</ul>
<p>A static <code>options:</code> list can't handle either case — it's decided once and never revisited.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/scaffold-dynamic-options#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>A field's <code>options:</code> can now be computed dynamically, using the same <code>answers.</code>-dot-path syntax
and Go-template conventions already available elsewhere in scaffold templates:</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">spec</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">fields</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="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"> envs</span></span><br></div><div class="token-line 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"> multiselect</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">options</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token plain">dev</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> staging</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> 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 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"> default_env</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">type</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> select</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">options</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> answers.envs</span></span><br></div></code></pre></div></div>
<p>If someone picks <code>staging</code> and <code>prod</code>, <code>default_env</code> will only offer those two — <code>dev</code> is
excluded. The source field doesn't need to be a <code>multiselect</code>; a plain text input works too,
combined with a template expression that converts it to a list:</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">spec</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">fields</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="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"> csv_owners</span></span><br></div><div class="token-line 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"> input</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">default</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"platform-team,security-team"</span><span class="token plain"></span></span><br></div><div class="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"> primary_owner</span></span><br></div><div class="token-line 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"> select</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">options</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'{{ splitList "," answers.csv_owners }}'</span></span><br></div></code></pre></div></div>
<p>Both forms resolve <code>options:</code> based on whatever was supplied for the earlier field, whether
answers come from an interactive prompt or are passed in non-interactively.</p>
<p>The same <code>options:</code> field also accepts a list of label/value pairs, so what's displayed and what's
stored can differ:</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">spec</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">fields</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="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"> envs</span></span><br></div><div class="token-line 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"> multiselect</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">options</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> </span><span class="token key atrule">label</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> Development</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">          </span><span class="token key atrule">value</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> dev</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> </span><span class="token key atrule">label</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> Staging</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">          </span><span class="token key atrule">value</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> staging</span></span><br></div><div class="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">label</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> Production</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">          </span><span class="token key atrule">value</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> 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 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"> default_env</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">type</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> select</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">options</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> answers.envs</span></span><br></div></code></pre></div></div>
<p>Here, <code>envs</code> displays "Development," "Staging," and "Production" while storing
<code>dev</code>/<code>staging</code>/<code>prod</code> everywhere they're actually needed — generated files, <code>when:</code>
conditions, and other fields' <code>options:</code>. Since <code>default_env</code> pulls its choices dynamically from
<code>envs</code>, it inherits those same friendly labels for whatever was picked, rather than falling back
to raw stored values.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/scaffold-dynamic-options#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>Point <code>options:</code> at <code>answers.&lt;field&gt;</code> (or a template expression) on any <code>select</code>/<code>multiselect</code>
field to source its choices from an earlier answer instead of a fixed list, and switch a plain
string list to label/value object entries wherever the stored value and the display text should
differ. See the <a class="" href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/scaffold/generate"><code>atmos scaffold generate</code></a> docs for the full
field reference.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/scaffold-dynamic-options#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p><a href="https://github.com/cloudposse/atmos/issues" target="_blank" rel="noopener noreferrer" class="">Open an issue</a> with feedback, or share templates that
put dynamic options to use in your own projects.</p>]]></content:encoded>
            <category>Feature</category>
        </item>
        <item>
            <title><![CDATA[See CI and Atmos Pro Status at a Glance]]></title>
            <link>https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/ci-startup-status</link>
            <guid>https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/ci-startup-status</guid>
            <pubDate>Thu, 27 Aug 2026 12:00:00 GMT</pubDate>
            <description><![CDATA[GitHub Actions is the most popular way teams run Atmos in CI, and a lot of those pipelines are]]></description>
            <content:encoded><![CDATA[<p>GitHub Actions is the most popular way teams run Atmos in CI, and a lot of those pipelines are
still calling into the original <code>cloudposse/github-action-atmos-*</code> actions. Those actions were the
recommendation for years. They're no longer where investment goes — <a class="" href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/ci">Native CI</a> replaced them
with a more capable, end-to-end-tested integration. Plenty of teams don't know it exists, let alone
that the actions they're on are effectively on life support.</p>
<p>Even teams already on Native CI run into a quieter version of the same problem: a setting that
doesn't take effect looks exactly like one that does. Maybe <code>ci.enabled</code> is set on one profile but
not another, or an Atmos Pro workspace never got configured in the first place — nothing errors
either way. The pipeline finishes green, and the first symptom is a status check or an upload
that isn't there, discovered days later.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/ci-startup-status#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>Confirming any of it meant checking for side effects after the fact: did the expected status check
show up, did the drift upload happen, is this pipeline still wired to a marketplace action. None of
that was visible from the CI run itself, so a misconfigured pipeline was only ever discovered
because something else broke first.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/ci-startup-status#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 prints a short status banner the moment it detects it's running inside a CI provider:
the version, whether Native CI mode is on or off, and whether Atmos Pro is configured. If it's
invoked from one of the older marketplace actions, it also warns directly in the run log and
points at migrating to Native CI — which has more features, gets tested end-to-end as part of the
Atmos core test suite, and is where all future investment is going. Teams still on the legacy
actions should treat this as a prompt to move now, not eventually.</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">▶ Atmos version 1.228.0 linux/amd64</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">✓ Atmos CI is enabled; learn more at https://atmos.tools/ci</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">✗ Atmos Pro is disabled; learn more at https://atmos.tools/pro</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">⚠ Detected legacy action cloudposse/github-action-atmos-terraform-plan; migrate to Native CI for better performance — learn more at https://atmos.tools/ci</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/ci-startup-status#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>There's nothing to configure — the banner appears automatically at the start of every <code>atmos</code>
command you run inside a detected CI provider, and it's a complete no-op on a local machine. It
reads the same <a class="" href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/ci"><code>ci</code></a> and <a class="" href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/settings/pro"><code>settings.pro</code></a>
configuration you already have, so what it reports always matches your actual setup.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/ci-startup-status#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>Atmos is open source and we'd love your feedback. Join the conversation in the
<a href="https://cloudposse.com/slack" target="_blank" rel="noopener noreferrer" class="">Cloud Posse community</a> or open an issue on
<a href="https://github.com/cloudposse/atmos" target="_blank" rel="noopener noreferrer" class="">GitHub</a>.</p>]]></content:encoded>
            <category>Feature</category>
            <category>DX</category>
        </item>
        <item>
            <title><![CDATA[Introducing Streaming UI: Real-Time Progress for Terraform Commands]]></title>
            <link>https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/terraform-streaming-ui</link>
            <guid>https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/terraform-streaming-ui</guid>
            <pubDate>Tue, 25 Aug 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Say goodbye to overwhelming Terraform output. The new streaming UI mode transforms verbose terraform output into a clean, Docker-build-style progress display with interactive confirmations, resource dependency tree visualization, and attribute-level change details.]]></description>
            <content:encoded><![CDATA[<p>Say goodbye to overwhelming Terraform output. The new streaming UI mode transforms verbose terraform output into a clean, Docker-build-style progress display with interactive confirmations, resource dependency tree visualization, and attribute-level change details.</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 terraform --ui: plan, apply, destroy</span></div><pre class="screen__b5c noPreWrap_ImkX screenLoading_abuO"><span> </span></pre><div class="controls_eyLV"><button type="button" class="playButton_kD9r" aria-label="Pause cast"><svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 24 24" aria-hidden="true" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M6 5H8V19H6V5ZM16 5H18V19H16V5Z"></path></svg></button><input aria-label="Cast position" type="range" min="0" max="0" step="0.01" value="0"><span>00:00.0<!-- --> / <!-- -->00:00.0</span></div></div>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="what-changed">What Changed<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/terraform-streaming-ui#what-changed" class="hash-link" aria-label="Direct link to What Changed" title="Direct link to What Changed" translate="no">​</a></h2>
<p>We've added an optional streaming UI mode for Terraform commands (<code>plan</code>, <code>apply</code>, <code>deploy</code>, <code>init</code>, <code>destroy</code>) that displays real-time resource status with visual indicators, progress tracking, interactive confirmations, and condensed completion summaries.</p>
<h3 class="anchor anchorTargetStickyNavbar_cA1_" id="real-time-progress-display">Real-Time Progress Display<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/terraform-streaming-ui#real-time-progress-display" class="hash-link" aria-label="Direct link to Real-Time Progress Display" title="Direct link to Real-Time Progress Display" translate="no">​</a></h3>
<p><strong>During execution:</strong></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 codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">⠋ apply plat-ue2-dev/vpc Creating aws_security_group.default (5.2s)  ████████░░░░ 2/5</span></span><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">  ✓ Created  aws_vpc.main (2.1s)</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  ✓ Created  aws_subnet.public[0] (1.3s)</span></span><br></div></code></pre></div></div>
<p>The inline progress bar shows the current activity, elapsed time, and completion status on a single line.</p>
<p><strong>On completion:</strong></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">✓ Apply plat-ue2-dev/vpc completed (15.2s)</span><br></div></code></pre></div></div>
<p><strong>On error:</strong></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 codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">✗ Apply plat-ue2-dev/vpc failed: 1 error (12.1s)</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  Error: aws_instance.web[0]: InvalidAMIID.NotFound</span></span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_cA1_" id="dependency-tree-with-attribute-changes">Dependency Tree with Attribute Changes<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/terraform-streaming-ui#dependency-tree-with-attribute-changes" class="hash-link" aria-label="Direct link to Dependency Tree with Attribute Changes" title="Direct link to Dependency Tree with Attribute Changes" translate="no">​</a></h3>
<p>The streaming UI shows a visual dependency tree of resources being changed, with color-coded indicators:</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 codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">     plat-ue2-dev/myapp</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  ●  ├── aws_s3_object.file</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">     │     content_type  "text/html"  →  "text/plain"</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">     │     source        "hello.html" →  "hello.txt"</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  ●  └── aws_instance.new</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">           ami            (none)       →  "ami-12345"</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">           instance_type  (none)       →  "t3.micro"</span></span><br></div></code></pre></div></div>
<p>Resources are marked with colored dots (●): green for create, yellow for update, red for delete. Attribute changes show old → new values in a two-column layout.</p>
<p>For multi-line values (like file content), each line is shown with add/remove indicators:</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 codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  ●  └── aws_s3_object.weather</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">           content</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">          - Current weather: Sunny, 72°F</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">          - Humidity: 45%</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">          + Current weather: Cloudy, 65°F</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">          + Humidity: 80%</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">          + Wind: 15 mph NW</span></span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_cA1_" id="interactive-confirmation">Interactive Confirmation<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/terraform-streaming-ui#interactive-confirmation" class="hash-link" aria-label="Direct link to Interactive Confirmation" title="Direct link to Interactive Confirmation" translate="no">​</a></h3>
<p>Before applying changes, the UI displays a confirmation prompt:</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 codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  Do you want to apply these changes?</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  &gt; Yes   No</span></span><br></div></code></pre></div></div>
<p>The confirmation is styled with the Atmos theme and includes proper margins for visual clarity.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="why-this-matters">Why This Matters<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/terraform-streaming-ui#why-this-matters" class="hash-link" aria-label="Direct link to Why This Matters" title="Direct link to Why This Matters" translate="no">​</a></h2>
<p>Terraform's default output is overwhelming, especially for new users. A simple infrastructure change can produce hundreds of lines containing:</p>
<ul>
<li class="">Verbose state refresh messages for every resource</li>
<li class="">Provider initialization logs</li>
<li class="">JSON-like attribute diffs that obscure actual changes</li>
<li class="">Technical identifiers and ARNs</li>
</ul>
<p>This creates several problems:</p>
<ol>
<li class=""><strong>Information overload</strong> - Important changes are buried in noise</li>
<li class=""><strong>Progress blindness</strong> - No clear indication of completion percentage during long operations</li>
<li class=""><strong>Error obscurity</strong> - Errors get buried in the output stream</li>
<li class=""><strong>Context switching</strong> - Mental overhead parsing Terraform syntax</li>
</ol>
<p>The streaming UI solves these by showing only what matters: which resources are changing, what attributes are affected, and their current status.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/terraform-streaming-ui#how-to-use-it" class="hash-link" aria-label="Direct link to How to Use It" title="Direct link to How to Use It" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_cA1_" id="enable-via-flag">Enable via Flag<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/terraform-streaming-ui#enable-via-flag" class="hash-link" aria-label="Direct link to Enable via Flag" title="Direct link to Enable via Flag" translate="no">​</a></h3>
<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"># Enable for a single command</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos terraform plan vpc </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-s</span><span class="token plain"> dev </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--ui</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"># Disable explicitly when enabled by config</span><span class="token plain"></span><br></div><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"> prod </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--ui</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">false</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_cA1_" id="enable-via-configuration">Enable via Configuration<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/terraform-streaming-ui#enable-via-configuration" class="hash-link" aria-label="Direct link to Enable via Configuration" title="Direct link to Enable via Configuration" translate="no">​</a></h3>
<p>Add to your <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">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">ui</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line 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>Or set it directly from the CLI without hand-editing YAML:</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 </span><span class="token builtin class-name" style="color:rgb(255, 203, 139)">set</span><span class="token plain"> components.terraform.ui.enabled </span><span class="token boolean" style="color:rgb(255, 88, 116)">true</span><br></div></code></pre></div></div>
<p>With this on, the UI turns on automatically whenever a real terminal is detected — no <code>--ui</code> flag needed — and still auto-disables in the same piped/CI cases described below. Use <code>--ui=false</code> per-command to override it off.</p>
<h3 class="anchor anchorTargetStickyNavbar_cA1_" id="enable-via-environment-variable">Enable via Environment Variable<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/terraform-streaming-ui#enable-via-environment-variable" class="hash-link" aria-label="Direct link to Enable via Environment Variable" title="Direct link to Enable via Environment Variable" translate="no">​</a></h3>
<div class="language-shell codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-shell codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A"><div class="token-line" style="color:#d6deeb"><span class="token builtin class-name" style="color:rgb(255, 203, 139)">export</span><span class="token plain"> </span><span class="token assign-left variable" style="color:rgb(214, 222, 235)">ATMOS_TERRAFORM_UI</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">true</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos terraform plan vpc </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>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="smart-auto-disable">Smart Auto-Disable<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/terraform-streaming-ui#smart-auto-disable" class="hash-link" aria-label="Direct link to Smart Auto-Disable" title="Direct link to Smart Auto-Disable" translate="no">​</a></h2>
<p>The streaming UI automatically falls back to standard output when:</p>
<ul>
<li class=""><strong>No TTY attached</strong> - Output is piped or redirected</li>
<li class=""><strong>CI environment detected</strong> - <code>CI=true</code> environment variable is set</li>
<li class=""><strong>Unsupported commands</strong> - Commands that don't support JSON streaming</li>
</ul>
<p>This means your existing scripts and CI pipelines continue to work without modification.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="supported-commands">Supported Commands<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/terraform-streaming-ui#supported-commands" class="hash-link" aria-label="Direct link to Supported Commands" title="Direct link to Supported Commands" translate="no">​</a></h2>
<table><thead><tr><th>Command</th><th>Streaming UI</th></tr></thead><tbody><tr><td><code>plan</code></td><td>✓</td></tr><tr><td><code>apply</code></td><td>✓</td></tr><tr><td><code>deploy</code></td><td>✓</td></tr><tr><td><code>init</code></td><td>✓</td></tr><tr><td><code>destroy</code></td><td>✓</td></tr><tr><td><code>refresh</code></td><td>✗ (no <code>-json</code> streaming support in Terraform's <code>refresh</code>)</td></tr></tbody></table>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="technical-details">Technical Details<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/terraform-streaming-ui#technical-details" class="hash-link" aria-label="Direct link to Technical Details" title="Direct link to Technical Details" translate="no">​</a></h2>
<p>The implementation uses Terraform's machine-readable JSON output format (<code>-json</code> flag):</p>
<ol>
<li class="">Atmos automatically adds <code>-json</code> to terraform commands when UI mode is enabled</li>
<li class="">Parses plan files to build a dependency tree with attribute-level changes</li>
<li class="">Renders a Bubbletea-based TUI with spinners, progress bars, and status indicators</li>
<li class="">Displays interactive confirmation prompts using the <code>huh</code> library</li>
<li class="">Preserves exit codes (critical for <code>plan -detailed-exitcode</code>)</li>
</ol>
<p>This is a pure Go implementation using charmbracelet/bubbletea and huh, requiring no external binaries or CGO.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="learn-more">Learn More<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/terraform-streaming-ui#learn-more" class="hash-link" aria-label="Direct link to Learn More" title="Direct link to Learn More" translate="no">​</a></h2>
<ul>
<li class=""><a class="" href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/components/terraform">Terraform Configuration Reference</a></li>
<li class=""><a class="" href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/terraform/plan">atmos terraform plan</a></li>
<li class=""><a class="" href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/terraform/apply">atmos terraform apply</a></li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/terraform-streaming-ui#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>We'd love your feedback on the streaming UI. Try it out and let us know how it works for your workflow. Open an issue on <a href="https://github.com/cloudposse/atmos/issues" target="_blank" rel="noopener noreferrer" class="">GitHub</a> or join us in <a href="https://slack.cloudposse.com/" target="_blank" rel="noopener noreferrer" class="">Slack</a>.</p>]]></content:encoded>
            <category>Feature</category>
            <category>DX</category>
        </item>
        <item>
            <title><![CDATA[Atmos binaries now build with Go's FIPS 140-3 crypto module by default]]></title>
            <link>https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/fips-140-mode</link>
            <guid>https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/fips-140-mode</guid>
            <pubDate>Mon, 24 Aug 2026 12:00:00 GMT</pubDate>
            <description><![CDATA[Federal agencies, financial institutions, and healthcare organizations are often required to run]]></description>
            <content:encoded><![CDATA[<p>Federal agencies, financial institutions, and healthcare organizations are often required to run
only cryptography that's been validated against FIPS 140, the U.S. government's standard for
approved algorithms and key sizes. For a command-line tool built on a general-purpose language
runtime, meeting that bar has traditionally meant compiling against a separate validated crypto
library, or simply hoping the runtime's own TLS and encryption code happens to stick to approved
algorithms.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/fips-140-mode#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>Atmos talks to a lot of TLS endpoints — cloud provider APIs, git servers, artifact registries,
the Terraform module registry. Every one of those connections depends on the cryptography built
into the Go runtime atmos is compiled with. Until now, nothing about that cryptography was
validated or restricted to FIPS-approved algorithms; it just used whatever Go's standard library
picked. Operators who needed a FIPS 140-3 claim for their toolchain had no way to get one from an
official atmos release.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/fips-140-mode#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>Every officially released atmos binary — along with every binary built from a checkout using
<code>atmos build</code> — now links Go's own FIPS 140-3 crypto module and defaults to enforcing FIPS
140-3 mode at runtime. Go standard-library TLS connections, key generation, and hashing are
restricted to FIPS-approved algorithms and key sizes automatically. No flag, environment
variable, or config change is required.</p>
<p>This covers the TLS and cryptography atmos itself uses for outbound connections, and it's FIPS
140-3 <em>mode</em> — enforced by Go's runtime — not a CMVP compliance certification for the atmos
binary itself. Declarative secrets management (<code>atmos secret keygen</code> and the age-based SOPS
backend, along with the sealed values atmos pushes to GitHub Actions secrets) relies on its own
encryption, chosen for compatibility with those specific ecosystems, and sits outside Go's FIPS
module boundary entirely — worth knowing if your compliance program needs FIPS coverage across
secrets handling too.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/fips-140-mode#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 to opt into — every current and future atmos release ships this way by default. To confirm
it on any binary, ask atmos itself:</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 version </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--format</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">json</span><br></div></code></pre></div></div>
<div class="language-json codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-json codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token property" style="color:rgb(128, 203, 196)">"version"</span><span class="token operator" style="color:rgb(127, 219, 202)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"1.226.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 property" style="color:rgb(128, 203, 196)">"os"</span><span class="token operator" style="color:rgb(127, 219, 202)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"darwin"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token property" style="color:rgb(128, 203, 196)">"arch"</span><span class="token operator" style="color:rgb(127, 219, 202)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"arm64"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token property" style="color:rgb(128, 203, 196)">"fips"</span><span class="token operator" style="color:rgb(127, 219, 202)">:</span><span class="token plain"> </span><span class="token boolean" style="color:rgb(255, 88, 116)">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 punctuation" style="color:rgb(199, 146, 234)">}</span></span><br></div></code></pre></div></div>
<p>If you'd rather check without atmos installed yet — say, auditing a downloaded binary — any
standard Go toolchain can tell you the same thing:</p>
<div class="language-shell codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-shell codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A"><div class="token-line" style="color:#d6deeb"><span class="token plain">go version </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-m</span><span class="token plain"> ./atmos </span><span class="token operator" style="color:rgb(127, 219, 202)">|</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">grep</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-i</span><span class="token plain"> fips</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 codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">build   DefaultGODEBUG=fips140=on</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">build   GOFIPS140=latest</span></span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/fips-140-mode#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>Have feedback on this, or a compliance requirement it doesn't yet cover? <a href="https://github.com/cloudposse/atmos/issues" target="_blank" rel="noopener noreferrer" class="">Open an
issue</a> or join the conversation in the <a href="https://cloudposse.com/slack" target="_blank" rel="noopener noreferrer" class="">Cloud Posse
community Slack</a>.</p>]]></content:encoded>
            <category>Security</category>
        </item>
        <item>
            <title><![CDATA[Stop retyping -lock-timeout on every terraform command]]></title>
            <link>https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/terraform-lock-timeout-flags</link>
            <guid>https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/terraform-lock-timeout-flags</guid>
            <pubDate>Mon, 24 Aug 2026 12:00:00 GMT</pubDate>
            <description><![CDATA[Terraform locks state before it writes to it, and by default it gives up the instant that lock]]></description>
            <content:encoded><![CDATA[<p>Terraform locks state before it writes to it, and by default it gives up the instant that lock
is already held — no retry, no wait. That's fine for a single engineer running commands one at a
time. It falls apart the moment two pipelines, or a pipeline and an engineer, touch the same
component's state around the same moment: whichever process loses the race just fails, even
though the lock would have cleared in a few seconds.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/terraform-lock-timeout-flags#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>Terraform and OpenTofu support <code>-lock-timeout=&lt;duration&gt;</code> to poll for a held lock instead of
failing immediately, but it has to be typed on every single invocation. <code>TF_CLI_ARGS_&lt;command&gt;</code>
can automate it, but it is a single flat string rather than a structured, independently merged
<code>flags:</code> block — so a component that wants to override one flag has to restate the rest or lose
them. Teams running concurrent CI matrices, or Atmos Pro-driven deployments, would hit avoidable
failures from Terraform's <code>0s</code> default when no lock timeout is configured.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/terraform-lock-timeout-flags#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>Terraform CLI execution flags — <code>lock_timeout</code>, <code>lock</code>, <code>parallelism</code>, <code>refresh</code>, and
<code>compact_warnings</code> — can now be declared once under a <code>flags:</code> block: globally in <code>atmos.yaml</code>,
for an entire stack, or for a single component, with each layer overriding the one before it. An
<code>ATMOS_COMPONENTS_TERRAFORM_FLAGS_*</code> environment variable can override the <code>atmos.yaml</code> default
too — the same environment-variable handling every other Atmos setting already gets, not a
special case invented for these five flags. An explicit flag typed directly on the command line
still wins over every declared default, so nothing about existing one-off usage changes.</p>
<p>Atmos only injects a flag into commands that actually support it — for example <code>-refresh</code> isn't
valid when applying a saved plan, and <code>terraform import</code> doesn't accept <code>-parallelism</code> — so you
don't have to track those exceptions yourself.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/terraform-lock-timeout-flags#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 comment" style="color:rgb(99, 119, 119);font-style:italic"># atmos.yaml — fleet-wide default</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain"></span><span class="token key atrule">components</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">terraform</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">flags</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">lock_timeout</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)">"5m"</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">parallelism</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)">10</span><span class="token plain"></span></span><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"># stack manifest — applies to every terraform component in this 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">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">flags</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">lock_timeout</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)">"5m"</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain" style="display:inline-block"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain"></span><span class="token key atrule">components</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">terraform</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">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 comment" style="color:rgb(99, 119, 119);font-style:italic"># per-component override</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">flags</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">lock_timeout</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)">"10m"</span></span><br></div></code></pre></div></div>
<div class="language-shell codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-shell codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A"><div class="token-line" style="color:#d6deeb"><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># one-off override still works exactly as before, and always wins</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos terraform plan vpc </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-s</span><span class="token plain"> plat-ue2-dev -- -lock-timeout</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">30s</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"># environment variable overrides the atmos.yaml default — handy for a per-CI-job</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"># tweak without touching the fleet-wide config</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token assign-left variable" style="color:rgb(214, 222, 235)">ATMOS_COMPONENTS_TERRAFORM_FLAGS_LOCK_TIMEOUT</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">2m atmos terraform plan 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></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="why-not-just-use-tf_cli_args">Why not just use TF_CLI_ARGS?<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/terraform-lock-timeout-flags#why-not-just-use-tf_cli_args" class="hash-link" aria-label="Direct link to Why not just use TF_CLI_ARGS?" title="Direct link to Why not just use TF_CLI_ARGS?" translate="no">​</a></h2>
<p>Yes, you could. Atmos's <code>env:</code> section also merges by stack and component. Set
<code>env: { TF_CLI_ARGS_plan: "-lock-timeout=5m" }</code>, and it scopes the same way <code>flags:</code> does.</p>
<p>But <code>TF_CLI_ARGS_plan</code> is one flat string with no separate fields. If a component overrides
<code>-parallelism</code>, it must also restate <code>-lock-timeout</code>, or the component loses that value.</p>
<p>Fields in <code>flags:</code> merge one at a time. A component can override <code>parallelism</code> alone and still
inherit <code>lock_timeout</code> from the stack. Every other Atmos section merges the same way.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/terraform-lock-timeout-flags#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>See the <a class="" href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/components/terraform#flags">Terraform Configuration</a> docs for the
full field reference, defaults, and environment variable overrides. Have feedback on this
feature? <a href="https://github.com/cloudposse/atmos/issues" target="_blank" rel="noopener noreferrer" class="">Open an issue</a> or join the conversation 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[Gate custom command steps on their own flags and arguments]]></title>
            <link>https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/cel-when-flags-arguments</link>
            <guid>https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/cel-when-flags-arguments</guid>
            <pubDate>Fri, 21 Aug 2026 12:00:00 GMT</pubDate>
            <description><![CDATA[A custom command often needs to behave differently depending on how it was called — skip the]]></description>
            <content:encoded><![CDATA[<p>A custom command often needs to behave differently depending on how it was called — skip the
destructive step on <code>--dry-run</code>, only run a cleanup step for a particular <code>environment</code> argument,
or branch on whichever component the caller targeted. Doing that meant wrapping the command in a
shell script that inspected <code>$@</code> itself, because a step's <code>when:</code> condition had no visibility into
the command's own <code>--flag</code> or positional argument values.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/cel-when-flags-arguments#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>Custom command steps already supported <code>when:</code> conditions built on CEL — <code>ci</code>, <code>stack</code>,
<code>component</code>, and more — but a step could never see the values the user actually passed to the
command that's running it:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token key atrule">commands</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> deploy</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">flags</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="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"> dry</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">run</span></span><br></div><div class="token-line 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"> bool</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">steps</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> </span><span class="token key atrule">type</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> shell</span></span><br></div><div class="token-line 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"> terraform apply</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># No way to reference --dry-run here.</span></span><br></div></code></pre></div></div>
<p>The flag values were already being extracted for Go/gomplate templates as <code>{{ .Flags.dry_run }}</code>,
but that data never reached the CEL evaluator, so <code>when:</code> conditions couldn't use it.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/cel-when-flags-arguments#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p><code>when:</code> expressions can now read <code>flags</code> and <code>arguments</code>, mirroring the same data already
available to steps in templates. <code>component</code> is also resolved for custom commands now, the same
way it already was for component hooks — via a semantic-typed flag or argument.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/cel-when-flags-arguments#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">commands</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> deploy</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">flags</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="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"> dry</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">run</span></span><br></div><div class="token-line 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"> bool</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">steps</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> </span><span class="token key atrule">type</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> shell</span></span><br></div><div class="token-line 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"> terraform apply</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">when</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)">!cel</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'!flags["dry-run"]'</span></span><br></div></code></pre></div></div>
<p>See the <a class="" href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/commands/steps#conditional-steps">custom command steps</a> docs for the
full list of available <code>when:</code> facts.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/cel-when-flags-arguments#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>Have feedback on this feature? <a href="https://github.com/cloudposse/atmos/issues" target="_blank" rel="noopener noreferrer" class="">Open an issue</a> or join
the conversation 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[Container Build Paths Depended on Where You Ran Atmos From]]></title>
            <link>https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/container-component-base-path</link>
            <guid>https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/container-component-base-path</guid>
            <pubDate>Fri, 21 Aug 2026 12:00:00 GMT</pubDate>
            <description><![CDATA[A container component's build.context and dockerfile looked like ordinary relative paths, but]]></description>
            <content:encoded><![CDATA[<p>A container component's <code>build.context</code> and <code>dockerfile</code> looked like ordinary relative paths, but
they weren't resolved against anything in particular — they resolved against whatever directory
your shell happened to be in the moment you ran <code>atmos container build</code>. Run it from the repo root
and it worked. Run it from a subdirectory, a CI job with a different working directory, or a
script that changes directories first, and the build silently picked up the wrong Dockerfile or
found nothing at all. Setting <code>components.container.base_path</code> didn't help — that option was
accepted but quietly ignored.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/container-component-base-path#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>Terraform, Helmfile, Kubernetes, and Helm components have always resolved their working directory
the same way: a configurable <code>base_path</code> per component type, joined with the component's own name,
computed once and used consistently no matter where <code>atmos</code> is invoked from. Container components
never got wired into that mechanism. <code>build.context</code> and <code>build.dockerfile</code> were passed straight
through to <code>docker build</code>/<code>podman build</code> with no anchoring at all, and <code>run.mounts[].source</code>
anchored only to the bare project root — never to the component itself.
<code>components.container.base_path</code> existed in the config schema, but nothing ever read it.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/container-component-base-path#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>Container components now resolve <code>build.context</code>, <code>build.dockerfile</code>, and <code>run.mounts[].source</code>
the same way every other component type does: relative to <code>components.container.base_path</code>
(default <code>components/container</code>) joined with the component's own name, independent of the
directory <code>atmos</code> happens to be invoked from. <code>components.container.base_path</code> is now a real,
working setting. Container components also gained the same just-in-time source provisioning as
Terraform and Helmfile components — a component that declares <code>source:</code> is now auto-vendored into
a workdir, and that workdir becomes the anchor for build and mount paths instead of the static base
path.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="breaking-change">Breaking Change<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/container-component-base-path#breaking-change" class="hash-link" aria-label="Direct link to Breaking Change" title="Direct link to Breaking Change" translate="no">​</a></h2>
<p>If your container component's <code>build.context</code>, <code>build.dockerfile</code>, or <code>run.mounts[].source</code> are
relative paths, they now resolve against <code>&lt;base_path&gt;/&lt;component-name&gt;/</code> instead of the previous
CWD-dependent (build) or bare-project-root (mounts) behavior. Update your setup one of two ways:
move build assets under <code>components/container/&lt;component-name&gt;/</code> to match the same convention
Terraform components already use, or point <code>components.container.base_path</code> at wherever your
container build assets currently live.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/container-component-base-path#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 comment" style="color:rgb(99, 119, 119);font-style:italic"># atmos.yaml</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain"></span><span class="token key atrule">components</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">container</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">base_path</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> components/container   </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># default</span></span><br></div></code></pre></div></div>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token key atrule">components</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">container</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">api</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">build</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line 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"> app           </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># resolves to components/container/api/app</span><span class="token plain"></span></span><br></div><div class="token-line 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 class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># resolves to components/container/api/app/Dockerfile</span></span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/container-component-base-path#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>Try it out with an existing container component or a fresh one. Questions or ideas? Start a thread
in <a href="https://github.com/cloudposse/atmos/discussions" target="_blank" rel="noopener noreferrer" class="">GitHub Discussions</a>, or open an issue in the
<a href="https://github.com/cloudposse/atmos/issues" target="_blank" rel="noopener noreferrer" class="">issue tracker</a>.</p>]]></content:encoded>
            <category>Bug Fix</category>
            <category>Breaking Change</category>
        </item>
        <item>
            <title><![CDATA[Keep version fields in JSON files in sync without a template]]></title>
            <link>https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/version-tracker-json-manager</link>
            <guid>https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/version-tracker-json-manager</guid>
            <pubDate>Thu, 20 Aug 2026 12:00:00 GMT</pubDate>
            <description><![CDATA[Plain JSON has no comment syntax, so there's nowhere to put an annotation telling a tool which]]></description>
            <content:encoded><![CDATA[<p>Plain JSON has no comment syntax, so there's nowhere to put an annotation telling a tool which
field carries a managed version. Rewriting the whole file from a parsed structure works, but it
reflows formatting, reorders keys, and turns a one-line diff into a noisy one. Neither option was
a good fit for keeping a <code>version</code> field in a <code>package.json</code>, plugin manifest, or marketplace
listing in sync with a locked dependency.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/version-tracker-json-manager#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>The <a class="" href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/version/files">Version Tracker</a>'s <code>marker</code> manager rewrites version
tokens on lines annotated with an <code>atmos:version</code> comment — but JSON has no comment syntax, so
there's no line to annotate. The <code>template</code> manager covers formats like this by rendering a
<code>*.tmpl</code> source to a sibling output file, but that means maintaining a template and a generated
file as two files that have to be kept in sync by hand every time an unrelated field in the JSON
document changes.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/version-tracker-json-manager#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 <code>json</code> file manager writes locked values directly into JSON files at configured field
paths. It patches only the targeted field and leaves everything else in the document — key
order, spacing, unrelated fields — exactly as it was, so <code>atmos version track apply</code> produces a
minimal, single-field diff instead of a fully reformatted file.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/version-tracker-json-manager#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">version</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">dependencies</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">atmos</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">ecosystem</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> github/actions</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">datasource</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> github</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">releases</span></span><br></div><div class="token-line 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"> github</span></span><br></div><div class="token-line 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"> cloudposse/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">desired</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"~1.160"</span><span class="token plain"></span></span><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">files</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> </span><span class="token key atrule">manager</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> json</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">paths</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="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"> package.json</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">options</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">set</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="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">path</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> version</span></span><br></div><div class="token-line 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"> atmos</span></span><br></div></code></pre></div></div>
<p>A single rule can target more than one file, and a single file can carry more than one managed
field — each just needs its own <code>path</code>/<code>from</code> entry under <code>set</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 plain">  </span><span class="token key atrule">files</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> </span><span class="token key atrule">manager</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> json</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">paths</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="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"> package.json</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">options</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">set</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="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">path</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> version</span></span><br></div><div class="token-line 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"> cli</span></span><br></div><div class="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">path</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> engines.node</span></span><br></div><div class="token-line 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"> node</span></span><br></div></code></pre></div></div>
<p><code>atmos version track apply</code> rewrites every configured field from the lock; <code>--check</code> fails and
lists any file that's out of date, so CI can catch drift before it merges.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/version-tracker-json-manager#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>See the <a class="" href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/version/files#updating-json-files">Version Files</a> docs for the full
<code>path</code>/<code>from</code> syntax, including array indexing and escaping keys that contain literal dots. Have
feedback on this feature? <a href="https://github.com/cloudposse/atmos/issues" target="_blank" rel="noopener noreferrer" class="">Open an issue</a> or join the
conversation 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[Pick configuration profiles interactively with a bare --profile]]></title>
            <link>https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/interactive-profile-selection</link>
            <guid>https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/interactive-profile-selection</guid>
            <pubDate>Tue, 18 Aug 2026 12:00:00 GMT</pubDate>
            <description><![CDATA[Naming things from memory is one of the more tedious parts of a CLI workflow. You know you want]]></description>
            <content:encoded><![CDATA[<p>Naming things from memory is one of the more tedious parts of a CLI workflow. You know you want
to switch configuration contexts before running a command, but you don't always remember every
profile name your team has defined, especially on a project you don't touch daily. Until now,
<code>--profile</code> required you to type that name exactly, or go check <code>atmos profile list</code> first and
copy it over.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/interactive-profile-selection#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p><code>--profile</code> activates one or more named configuration overlays — dev settings, CI settings,
security overrides, whatever a project defines. But the flag always required an explicit value.
Typing <code>--profile</code> alone, expecting the CLI to prompt you the way <code>-i</code>/<code>--identity</code> already does
when used bare, instead produced a raw usage error:</p>
<div class="language-shell codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-shell codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A"><div class="token-line" style="color:#d6deeb"><span class="token plain">$ atmos auth login </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-i</span><span class="token plain"> core-auto/terraform </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--profile</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">Incorrect Usage</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">Error: </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--profile</span><span class="token plain"> flag needs an argument </span><span class="token keyword" style="color:rgb(127, 219, 202)">for</span><span class="token plain"> </span><span class="token builtin class-name" style="color:rgb(255, 203, 139)">command</span><span class="token plain"> atmos auth login</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/interactive-profile-selection#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p><code>--profile</code> with no value now opens an interactive multi-select listing every profile Atmos
discovers across your configured profile locations. Nothing is checked by default — toggle the
ones you want with space, confirm, and they activate left-to-right in the order shown, exactly as
if you'd typed them explicitly.</p>
<p>Any profile name you already typed alongside the bare flag starts pre-checked, so
<code>--profile ci --profile</code> opens with <code>ci</code> already selected, ready to confirm or adjust. In a
non-interactive context — CI, scripts, no TTY — bare <code>--profile</code> returns a clear error instead of
hanging or guessing, so automation fails fast rather than silently.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/interactive-profile-selection#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"># Interactively choose which profiles to activate</span><span class="token plain"></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)">-i</span><span class="token plain"> core-auto/terraform </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--profile</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"># Explicit values still work exactly as before</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--profile</span><span class="token plain"> developer terraform plan vpc </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">atmos </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--profile</span><span class="token plain"> ci,security terraform plan vpc </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-s</span><span class="token plain"> prod</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/interactive-profile-selection#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>See the <a class="" href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/profiles#interactive-selection">Profiles</a> docs for the full behavior,
including profile discovery order and merge precedence. Have feedback on this feature? <a href="https://github.com/cloudposse/atmos/issues" target="_blank" rel="noopener noreferrer" class="">Open an
issue</a> or join the conversation 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[A Typo in a Container Step's `with:` Block Used to Just... Do Nothing]]></title>
            <link>https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/container-config-validation-and-workdir-path-encoding</link>
            <guid>https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/container-config-validation-and-workdir-path-encoding</guid>
            <pubDate>Mon, 17 Aug 2026 12:00:00 GMT</pubDate>
            <description><![CDATA[You add platforms: [linux/amd64] to a container build step, run it, and nothing happens]]></description>
            <content:encoded><![CDATA[<p>You add <code>platforms: [linux/amd64]</code> to a container build step, run it, and nothing happens
differently. No error, no warning — the field is just gone, like it was never written. You spend
ten minutes checking your YAML indentation before realizing the field name was never real to
begin with.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/container-config-validation-and-workdir-path-encoding#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p><code>type: container</code> steps take their configuration under <code>with:</code> (and, for the driver, a nested
<code>driver:</code> block) as a typed mapping — <code>run</code>, <code>build</code>, <code>push</code>, and <code>inspect</code> actions each have a
fixed set of real fields. But nothing checked that the keys you wrote were actually among them.
A typo'd field name, a field copied from Docker Compose that doesn't exist in Atmos, or a
straight-up nonexistent option all decoded the same way: silently discarded, with the rest of the
mapping loaded normally. The step would run — just without the setting you thought you'd
configured.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/container-config-validation-and-workdir-path-encoding#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p><code>with:</code> and <code>driver:</code> blocks on container steps now reject unknown fields outright, in both
standalone workflow files and custom commands. A typo like <code>platforms:</code> (not a real field) now
fails the step with a clear decode error naming the field, instead of quietly doing nothing.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="breaking-change">Breaking Change<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/container-config-validation-and-workdir-path-encoding#breaking-change" class="hash-link" aria-label="Direct link to Breaking Change" title="Direct link to Breaking Change" translate="no">​</a></h2>
<p>If a <code>with:</code> or <code>driver:</code> block on a <code>type: container</code> step currently has a field that isn't one
of the real, documented fields, it will now fail to load instead of being silently ignored.
Check your container steps for typos or leftover fields from a different tool's config format
before upgrading.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="also-in-this-release-local-backend-state-was-being-deleted-on-re-provision">Also in This Release: Local Backend State Was Being Deleted on Re-Provision<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/container-config-validation-and-workdir-path-encoding#also-in-this-release-local-backend-state-was-being-deleted-on-re-provision" class="hash-link" aria-label="Direct link to Also in This Release: Local Backend State Was Being Deleted on Re-Provision" title="Direct link to Also in This Release: Local Backend State Was Being Deleted on Re-Provision" translate="no">​</a></h2>
<p>If you used a <code>local</code> Terraform backend on a component with just-in-time (JIT) workdir
provisioning enabled, your state was gone after the second run. Not corrupted — deleted, cleanly,
with no error. <code>apply</code> would create it, and the very next <code>plan</code> would silently start over with
an empty state, because the workdir provisioner's incremental sync treated the state file the
same way it treats any file that isn't part of your component's source: not present in source,
so remove it. <code>terraform.tfstate</code> was never protected from that cleanup the way provider lock
files already were.</p>
<p>The workdir provisioner now leaves <code>terraform.tfstate</code>, <code>terraform.tfstate.backup</code>, and the
transient <code>.terraform.tfstate.lock.info</code> marker alone, in both directions — never copied in from
source, never deleted from the workdir. If you were working around this by avoiding JIT workdir
provisioning for local-backend components, that workaround is no longer necessary.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="also-in-this-release-workdir-path-encoding">Also in This Release: Workdir Path Encoding<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/container-config-validation-and-workdir-path-encoding#also-in-this-release-workdir-path-encoding" class="hash-link" aria-label="Direct link to Also in This Release: Workdir Path Encoding" title="Direct link to Also in This Release: Workdir Path Encoding" translate="no">​</a></h2>
<p>Separately, the internal <code>.workdir/</code> directory Atmos uses for JIT component provisioning now
encodes component and stack names more carefully, to guarantee two differently named components
(e.g. one named <code>app/local</code> and another named <code>app-local</code>) can never accidentally resolve to the
same on-disk directory and share files or state.</p>
<p>This changes the on-disk directory name for any component whose name contains a literal <code>-</code>,
<code>/</code>, or <code>\</code>. Atmos migrates a workdir it finds at the old location automatically the next time
that component is provisioned, so this should be transparent for most setups.</p>]]></content:encoded>
            <category>Bug Fix</category>
            <category>Breaking Change</category>
        </item>
        <item>
            <title><![CDATA[GKE Kubeconfig Authentication: Native kubectl and Helm Access Without gcloud]]></title>
            <link>https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/gke-kubeconfig-authentication</link>
            <guid>https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/gke-kubeconfig-authentication</guid>
            <pubDate>Fri, 14 Aug 2026 12:00:00 GMT</pubDate>
            <description><![CDATA[Using an Atmos-managed GCP identity with GKE used to stop one step short of the cluster. The]]></description>
            <content:encoded><![CDATA[<p>Using an Atmos-managed GCP identity with GKE used to stop one step short of the cluster. The
identity could authenticate Terraform and other GCP clients, but operators still needed <code>gcloud</code>
or <code>gke-gcloud-auth-plugin</code> to discover the cluster, write kubeconfig, and refresh Kubernetes
credentials. Atmos now handles that complete path itself.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/gke-kubeconfig-authentication#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>Atmos Auth already supports Application Default Credentials, Workload Identity Federation, and
service account impersonation. GKE access still required a separate authentication flow outside
Atmos, though. That created two sources of truth for identity selection and added external tools
to local and CI environments solely to prepare kubeconfig.</p>
<p>The gap was especially visible with native Helm components: Atmos could resolve the intended GCP
identity, but an ambient kubeconfig could still point Helm at a different cluster.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/gke-kubeconfig-authentication#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>gcp/gke</code> Auth integration links a GKE cluster to an existing GCP identity. When Atmos
selects that identity, it uses the GKE API to discover the cluster endpoint and CA certificate,
writes an Atmos-managed kubeconfig, and injects its path into child commands:</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">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">example-gcp</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line 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"> gcp/adc</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">spec</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">project_id</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> example</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">project</span></span><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">example-deployer</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line 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"> gcp/project</span></span><br></div><div class="token-line 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"> example</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">gcp</span></span><br></div><div class="token-line 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">project_id</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> example</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">project</span></span><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">integrations</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">example-gke</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line 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"> gcp/gke</span></span><br></div><div class="token-line 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">identity</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> example</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">deployer</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">spec</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">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">name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> example</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">cluster</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">          </span><span class="token key atrule">project_id</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> example</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">project</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">          </span><span class="token key atrule">location</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> us</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">central1</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">          </span><span class="token key atrule">alias</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> example</span></span><br></div></code></pre></div></div>
<p>Run Kubernetes tools through the selected identity without a preparatory <code>gcloud</code> 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 auth </span><span class="token builtin class-name" style="color:rgb(255, 203, 139)">exec</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--identity</span><span class="token plain"> example-deployer -- kubectl get nodes</span><br></div></code></pre></div></div>
<p>The generated kubeconfig uses <code>atmos gcp gke token</code> as a Kubernetes exec credential plugin.
Kubernetes requests a fresh short-lived token when needed; the token and its expiration are
returned as <code>ExecCredential</code> JSON and are never stored in kubeconfig.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="guard-native-helm-targets">Guard Native Helm Targets<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/gke-kubeconfig-authentication#guard-native-helm-targets" class="hash-link" aria-label="Direct link to Guard Native Helm Targets" title="Direct link to Guard Native Helm Targets" translate="no">​</a></h2>
<p>Native Helm keeps its existing ambient-kubeconfig behavior by default. Components that must use
an Atmos-provisioned GKE identity can opt into a fail-closed endpoint check:</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">helm</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">example-release</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">auth</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">require_identity</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">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">example-deployer</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">            </span><span class="token key atrule">default</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token boolean important" style="color:rgb(255, 88, 116)">true</span></span><br></div></code></pre></div></div>
<p>For live plan, apply, and delete operations, Atmos provisions the linked integration and verifies
that Helm's effective Kubernetes API endpoint matches the endpoint returned by GKE before any
cluster request. Offline template and manifest-baseline operations remain credential-free.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="security-boundaries">Security Boundaries<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/gke-kubeconfig-authentication#security-boundaries" class="hash-link" aria-label="Direct link to Security Boundaries" title="Direct link to Security Boundaries" translate="no">​</a></h2>
<ul>
<li class="">The kubeconfig stores the HTTPS endpoint, CA certificate, context, and exec-plugin command—not
a bearer token.</li>
<li class="">The GCP identity needs permission to describe the cluster, normally <code>container.clusters.get</code>.</li>
<li class="">Kubernetes RBAC remains separate and determines what the authenticated principal may do inside
the cluster.</li>
<li class="">Explicit plaintext GKE API endpoints are rejected rather than written to kubeconfig.</li>
</ul>
<p>See the <a class="" href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/gcp/gke">GKE kubeconfig authentication command documentation</a> for
configuration, update modes, permissions, and troubleshooting details.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/gke-kubeconfig-authentication#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>Try the integration with your GCP identity chain and GKE clusters. Share feedback in the
<a href="https://cloudposse.com/slack" target="_blank" rel="noopener noreferrer" class="">Cloud Posse community</a> or open an issue on
<a href="https://github.com/cloudposse/atmos/issues" target="_blank" rel="noopener noreferrer" class="">GitHub</a>.</p>]]></content:encoded>
            <category>Feature</category>
        </item>
        <item>
            <title><![CDATA[Generate one file per selection with matrix]]></title>
            <link>https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/scaffold-matrix</link>
            <guid>https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/scaffold-matrix</guid>
            <pubDate>Fri, 14 Aug 2026 12:00:00 GMT</pubDate>
            <description><![CDATA[Every file a scaffold template declares renders at most once. when: can skip a file, but it]]></description>
            <content:encoded><![CDATA[<p>Every file a scaffold template declares renders at most once. <code>when:</code> can skip a file, but it
can never multiply one. You could work around that by authoring every combination up front and
letting <code>when:</code> prune down to what applies — but that only works if every combination is
knowable in advance. It breaks down for environments picked interactively from a longer list, or
names typed in by hand that no template author could have enumerated ahead of time. Until now,
that meant hand-rolling files outside the template, or maintaining a pile of near-duplicate ones
inside it.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/scaffold-matrix#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>The number of files a project needs often depends on what gets selected when the project is
generated. Pick three environments out of five, and you want three stack files, not five. That
output was already possible: declare all five stack files in the template up front, and gate each
one with its own <code>when:</code> on whether that specific environment got picked. The real cost was
authorship — five nearly-identical files, one per environment the template author had to
anticipate, kept in sync by hand as the shared parts drifted. Nothing let a template say "generate
one of these per selected value" from a single file; only "generate this specific file" or "skip
this specific file."</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/scaffold-matrix#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>Declaring <code>matrix:</code> on a file entry expands it into one generated file per combination of one or
more axes. It reuses the same shape Atmos workflow <code>matrix:</code> steps already use, so the syntax
should feel familiar. <code>when:</code> still prunes combinations that don't apply — the same conditional
engine that already gates whole files, now scoped to a single combination at a time:</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">spec</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">fields</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="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"> environments</span></span><br></div><div class="token-line 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"> multiselect</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">options</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token plain">dev</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> staging</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">files</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> </span><span class="token key atrule">path</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> stacks/deploy/environment.yaml</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">target</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)">"stacks/deploy/{{ .matrix.environment }}.yaml"</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">matrix</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line 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"> answers.environments</span></span><br></div></code></pre></div></div>
<p>Selecting <code>dev</code> and <code>staging</code> generates exactly <code>stacks/deploy/dev.yaml</code> and
<code>stacks/deploy/staging.yaml</code>. Declaring more than one axis expands their full combination, and
each resolved combination is available as <code>.matrix.&lt;axis&gt;</code> in Go-template fields such as the
output path and generated content, and as <code>matrix.&lt;axis&gt;</code> in <code>when:</code> conditions — so a file can
name itself and branch on its own combination.</p>
<h3 class="anchor anchorTargetStickyNavbar_cA1_" id="computed-axes">Computed axes<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/scaffold-matrix#computed-axes" class="hash-link" aria-label="Direct link to Computed axes" title="Direct link to Computed axes" translate="no">​</a></h3>
<p>Real answers aren't always a flat, pre-selected list. Say <code>environments</code> were a structured answer
instead of a <code>multiselect</code> — supplied through <code>--set</code> or a preset value — shaped like this:</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">environments</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">dev</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">regions</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">us-east-1</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">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">regions</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">us-east-1</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">us-west-2</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span></span><br></div></code></pre></div></div>
<p>The full list of regions actually used isn't something anyone picked directly — it has to be
derived from every environment's own <code>regions</code>. The <code>collectKeys</code> function does that: called with
one argument, it returns a map's keys; called with a second argument, it collects that key from
every value in the map, flattening and deduplicating across all of them.</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">files</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> </span><span class="token key atrule">path</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> deploy.yaml</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">target</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)">"deploy/{{ .matrix.environment }}/{{ .matrix.region }}.yaml"</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">matrix</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line 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"> </span><span class="token string" style="color:rgb(173, 219, 103)">'{{ collectKeys answers.environments }}'</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">region</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'{{ collectKeys answers.environments "regions" }}'</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">when</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)">"matrix.region in answers.environments[matrix.environment].regions"</span></span><br></div></code></pre></div></div>
<p><code>environment</code> resolves to <code>dev</code> and <code>production</code>; <code>region</code> resolves to every region used by any of
them (<code>us-east-1</code> and <code>us-west-2</code>). Their combination fans a single <code>deploy.yaml</code> out into
<code>deploy/dev/us-east-1.yaml</code>, <code>deploy/production/us-east-1.yaml</code>, and
<code>deploy/production/us-west-2.yaml</code> — <code>target:</code> names each one from <code>.matrix.&lt;axis&gt;</code>, and <code>when:</code>
prunes the combination down to each environment's actual regions, so <code>dev</code> never gets a
<code>us-west-2</code> file.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/scaffold-matrix#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="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: one file per selection via matrix</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>The <a class="" href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/examples/scaffolding-matrix">scaffolding-matrix example</a> is a minimal, runnable template —
one <code>multiselect</code> field driving one matrix axis:</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/scaffolding-matrix</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos scaffold generate example ./my-project</span><br></div></code></pre></div></div>
<p>Answering the <code>environments</code> prompt with <code>dev</code> and <code>staging</code> generates <code>stacks/dev.yaml</code> and
<code>stacks/staging.yaml</code> from the template's single <code>environment.yaml</code> file — or skip the prompt
entirely with <code>--set environments=dev,staging</code> for scripted, non-interactive use. Add <code>matrix:</code> to
any <code>spec.files[]</code> entry alongside <code>target:</code> to do the same in your own templates, using a literal
list, a <code>multiselect</code> answer, or a computed expression for each axis.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/scaffold-matrix#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>See the <a class="" href="https://pr-2889.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/scaffold/generate"><code>atmos scaffold generate</code></a> docs for the full reference,
or <a href="https://github.com/cloudposse/atmos/issues" target="_blank" rel="noopener noreferrer" class="">open an issue</a> with feedback.</p>]]></content:encoded>
            <category>Feature</category>
        </item>
    </channel>
</rss>