<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <id>https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog</id>
    <title>atmos Blog</title>
    <updated>2026-09-15T00:00:00.000Z</updated>
    <generator>https://github.com/jpmonette/feed</generator>
    <link rel="alternate" href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog"/>
    <subtitle>atmos Blog</subtitle>
    <icon>https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/img/atmos-logo.png</icon>
    <entry>
        <title type="html"><![CDATA[Faster Vendoring with Concurrent Downloads]]></title>
        <id>https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/concurrent-vendoring</id>
        <link href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/concurrent-vendoring"/>
        <updated>2026-09-15T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Waiting for each component download to finish before the next begins adds up in]]></summary>
        <content type="html"><![CDATA[<p>Waiting for each component download to finish before the next begins adds up in
large repositories. Atmos vendoring now prepares independent packages concurrently
and shows their progress together, while keeping destination writes in declaration
order.</p>
<div><div class="window_X9dN"><div class="titlebar_DN7h"><span class="dots_R2sg" aria-hidden="true"><i></i><i></i><i></i></span><span class="title_Dael">Concurrent vendoring and cleanup</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><div class="castActions_M13G"><div class="container_zGFV"><div class="group_ncGU" role="group" aria-label="Share this demo"><button type="button" class="primary_hpkh" title="Copy a link to this demo" aria-live="polite"><svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" class="icon_P_nE" aria-hidden="true" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><circle cx="18" cy="5" r="3"></circle><circle cx="6" cy="12" r="3"></circle><circle cx="18" cy="19" r="3"></circle><line x1="8.59" y1="13.51" x2="15.42" y2="17.49"></line><line x1="15.41" y1="6.51" x2="8.59" y2="10.49"></line></svg><span>Share</span></button><button type="button" class="caret_pPxC" aria-expanded="false" aria-label="More share options" title="More share options"><svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" class="icon_P_nE" aria-hidden="true" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><polyline points="6 9 12 15 18 9"></polyline></svg></button></div></div><div class="container_EXko"><button type="button" class="trigger_WxG7" aria-expanded="false" aria-label="Download cast"><svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" class="icon_LbC3" aria-hidden="true" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline points="7 10 12 15 17 10"></polyline><line x1="12" y1="15" x2="12" y2="3"></line></svg><span>Download</span><svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" class="icon_LbC3" aria-hidden="true" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><polyline points="6 9 12 15 18 9"></polyline></svg></button></div></div></div>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/concurrent-vendoring#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>A repository can contain many component sources, mixins, and targets. Fetching
these one at a time leaves the network idle between jobs and makes a large update
hard to follow. Overlapping destinations also mean downloads cannot simply copy
files whenever they finish.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/concurrent-vendoring#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p><a class="" href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/vendor/pull">Vendor pull</a> prepares up to four packages at once and
installs them in declaration order. Local sources wait for earlier writes before
being read. <a class="" href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/vendor/vendor-update">Vendor update</a> checks upstream
versions concurrently and preserves the order and formatting of manifest edits.</p>
<p>The shared progress display shows active phases, download percentages when the total
size is known, retries, and completed results. A ready package is waiting for its turn
to install. The overall bar advances during downloads with known sizes and when
packages become ready, with equal weight for preparation and installation. The
completed count advances only after processing finishes. CI receives plain result
lines, and structured update reports stay on stdout.</p>
<p>The <a class="" href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/vendor/vendor-clean">vendor clean</a> command displays relative paths
and preserves every lock entry when removing vendored files. Recorded versions,
checksums, and provenance remain available for the next pull. Fully cleaned packages
reinstall without drift warnings; partial deletion and modified files still trigger checks.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/concurrent-vendoring#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 plain">atmos vendor pull --max-concurrency </span><span class="token number" style="color:rgb(247, 140, 108)">8</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos vendor update </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--check</span><span class="token plain"> --max-concurrency </span><span class="token number" style="color:rgb(247, 140, 108)">8</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos vendor update </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--pull</span><span class="token plain"> --max-concurrency </span><span class="token number" style="color:rgb(247, 140, 108)">8</span><br></div></code></pre></div></div>
<p>Set <a class="" href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/vendor#concurrency"><code>vendor.max_concurrency</code></a> in <code>atmos.yaml</code>
or use <code>ATMOS_VENDOR_MAX_CONCURRENCY</code>. Explicit flags take precedence over the
environment and configuration. Set one worker for serial execution.</p>
<p>Projects with an <a class="" href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/edition">edition pin</a> before <code>2026-09-15</code> keep
one worker by default. All editions receive the progress display, and explicit
concurrency settings override the pin.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/concurrent-vendoring#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 commands on your component catalog and share feedback in
<a href="https://github.com/cloudposse/atmos/discussions" target="_blank" rel="noopener noreferrer" class="">Atmos GitHub Discussions</a>.</p>]]></content>
        <author>
            <name>Erik Osterman</name>
            <uri>https://github.com/osterman</uri>
        </author>
        <category label="Enhancement" term="Enhancement"/>
        <category label="DX" term="DX"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Quieter Workflow Output and Daily Experimental Warnings]]></title>
        <id>https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/quieter-workflow-notices</id>
        <link href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/quieter-workflow-notices"/>
        <updated>2026-09-14T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Workflows and custom commands can invoke Atmos many times, repeating startup banners and experimental warnings before each step. Those repeated notices make it harder to find the output that matters. Atmos now shows each experimental feature's warning once every 24 hours by default and suppresses repeated startup banners in child invocations.]]></summary>
        <content type="html"><![CDATA[<p>Workflows and custom commands can invoke Atmos many times, repeating startup banners and experimental warnings before each step. Those repeated notices make it harder to find the output that matters. Atmos now shows each experimental feature's warning once every 24 hours by default and suppresses repeated startup banners in child invocations.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/quieter-workflow-notices#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>An experimental warning is useful when you first use a feature. Seeing it again for every component in a workflow adds noise, especially alongside repeated Atmos version, CI, and Pro status messages.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/quieter-workflow-notices#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 <a class="" href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/settings/experimental">experimental mode</a> <code>warn-daily</code> gives each feature its own 24-hour timer. A toolchain warning does not suppress the first warning for devcontainers or an experimental setting. Commands in the same experimental family share a timer, and CI commands and CI hooks share the CI feature's timer.</p>
<p>Atmos stores readable feature names and timestamps in its shared local cache. The timers apply across invocations and projects using that cache. Clearing the cache makes warnings eligible again; an unavailable cache never blocks the command. Concurrent suppression is best effort on Windows.</p>
<p>Startup banners appear at the top-level invocation and are suppressed in child Atmos calls. Markdown output also follows Atmos's explicit theme and color profile without automatic terminal-style probing.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/quieter-workflow-notices#how-to-use-it" class="hash-link" aria-label="Direct link to How to Use It" title="Direct link to How to Use It" translate="no">​</a></h2>
<p>The new default requires no configuration for unpinned projects. To choose it explicitly:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockTitle_JJ7b">atmos.yaml</div><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token key atrule">settings</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">experimental</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> warn</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">daily</span></span><br></div></code></pre></div></div>
<p>Projects pinned to a <a class="" href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/edition">config edition</a> before <code>2026-09-14</code> retain <code>warn</code> as the default. An explicit <code>settings.experimental</code> value or <code>ATMOS_EXPERIMENTAL</code> takes precedence over the edition default.</p>
<p>To show experimental warnings on each top-level invocation, set <code>experimental: warn</code>. Child command and setting notices are now suppressed in this mode too, independently of the edition pin. CI hooks retain their existing <code>warn</code> behavior. The <code>error</code> and <code>disable</code> modes remain enforced on every invocation, including nested calls, regardless of cached warnings.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/quieter-workflow-notices#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-3136.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/settings/experimental">experimental settings reference</a> for all modes, or <a href="https://github.com/cloudposse/atmos/issues" target="_blank" rel="noopener noreferrer" class="">report unexpected output</a>.</p>]]></content>
        <author>
            <name>Erik Osterman</name>
            <uri>https://github.com/osterman</uri>
        </author>
        <category label="Enhancement" term="Enhancement"/>
        <category label="DX" term="DX"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Terraform init now runs only when it needs to]]></title>
        <id>https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/smart-terraform-init</id>
        <link href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/smart-terraform-init"/>
        <updated>2026-09-11T12:00:00.000Z</updated>
        <summary type="html"><![CDATA[Running terraform init is necessary the first time you touch a working directory, and again]]></summary>
        <content type="html"><![CDATA[<p>Running <code>terraform init</code> is necessary the first time you touch a working directory, and again
after a real change — a new provider, an updated module, a different backend. Repeating that same
work before every single command, whether or not anything changed, adds real time to a workflow:
provider downloads, backend re-initialization, module resolution, all over again for a component
that's identical to how it was a few seconds ago.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/smart-terraform-init#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>That's exactly what Atmos did. Every Terraform subcommand — <code>plan</code>, <code>apply</code>, <code>shell</code>, <code>destroy</code>,
and even the read path behind <code>!terraform.output</code> and <code>atmos.Component</code> — started with a full
<code>terraform init -reconfigure</code>, unconditionally:</p>
<div class="language-shell codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-shell codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A"><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos terraform apply demo </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-s</span><span class="token plain"> dev</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Initializing provider plugins...</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"># Initializing the backend...</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"># ...apply completes...</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">atmos terraform output demo </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-s</span><span class="token plain"> dev</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Initializing provider plugins...   &lt;- nothing changed, but init runs again</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"># Initializing the backend...</span><br></div></code></pre></div></div>
<p>Nothing about <code>demo</code> changed between those two commands, but the second one pays the full init
cost anyway. On a slow connection, or with a component that pulls in a lot of providers, that
turns a fast edit-plan-apply loop into a slow one. <a href="https://github.com/cloudposse/atmos/issues/620" target="_blank" rel="noopener noreferrer" class="">Issue #620</a>
asked Atmos to be smarter about this — Terragrunt-style Auto-Init, where init only re-runs when it
actually needs to. <a href="https://github.com/cloudposse/atmos/issues/1263" target="_blank" rel="noopener noreferrer" class="">Issue #1263</a> asked for
something related: a way to have Atmos run <code>init -upgrade</code> automatically when a provider
constraint changes, instead of requiring <code>-upgrade</code> to be typed by hand after every version bump.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/smart-terraform-init#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 fingerprints the inputs that actually affect <code>terraform init</code> — the component's root
Terraform/OpenTofu files, the lock file, the CLI configuration, the resolved binary, and relevant
environment variables — and compares that fingerprint against the one recorded after the last
successful init. When nothing has changed, and the working directory still looks initialized,
Atmos skips init entirely. Applying a component and then reading one of its outputs no longer
performs two full inits.</p>
<p><code>-reconfigure</code> and <code>-upgrade</code> get the same treatment instead of being added unconditionally:
<code>-reconfigure</code> only goes on when the backend configuration actually changed (or on the first
init, or after a working directory is re-provisioned), and <code>-upgrade</code> only goes on when Terraform
or OpenTofu itself reports that an upgrade is required — the behavior <a href="https://github.com/cloudposse/atmos/issues/1263" target="_blank" rel="noopener noreferrer" class="">#1263</a>
asked for.</p>
<p>None of this trusts the fingerprint blindly. If a skip turns out to have been wrong — a nested
module changed, or <code>.terraform</code> was altered by hand — Terraform or OpenTofu fails with a
diagnostic like <em>"Backend initialization required"</em> or <em>"Required plugins are not installed"</em>
before it ever touches state. Atmos recognizes that class of diagnostic, runs the init that should
have run, and retries the command once. The one gap this doesn't close is a change inside a
nested local module, which isn't part of the fingerprint — that's caught by the same retry path
rather than avoided up front, and it's a limitation Terragrunt's own Auto-Init shares.</p>
<p><strong>Behavior change, automatically protected by <a class="" href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/edition">editions</a>:</strong> init no
longer runs unconditionally, and <code>-reconfigure</code>/<code>-upgrade</code> are no longer added to every init, by
default. If your project is pinned to an <a class="" href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/edition">edition</a> from before
2026-09-12, you see byte-for-byte the same behavior Atmos always had — no config changes needed.
Unpinned projects, and anything pinned on or after that date, get the new defaults automatically.
See <a class="" href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/config-editions">Config Editions</a> for how pinning works.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/smart-terraform-init#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>Three new settings under <code>components.terraform.init</code>, all defaulting to <code>auto</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">init</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">mode</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> auto         </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># auto | always | never</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">reconfigure</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> auto  </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># auto | always | never</span><span class="token plain"></span></span><br></div><div class="token-line 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"> auto       </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># auto | always | never</span></span><br></div></code></pre></div></div>
<p><code>mode</code> controls whether init runs at all: <code>auto</code> skips it when nothing relevant changed, <code>always</code>
restores the previous behavior, <code>never</code> disables the ordinary implicit init — but <code>terraform workspace select/new</code> still forces a reconfigured init regardless, since it always needs one;
<code>--skip-init</code> is the flag that suppresses init unconditionally, including for <code>workspace</code>.
<code>reconfigure</code> and <code>upgrade</code> control the two flags the same way, independently.</p>
<p><code>mode</code> and <code>upgrade</code> are <a class="" href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/edition">edition</a>-protected: pin <code>edition: "2026-09-11"</code> or earlier and both roll back to their pre-this-PR behavior (<code>always</code> and <code>never</code>
respectively) with no other config changes. <code>reconfigure</code> isn't — see the note on
<code>init_run_reconfigure</code> below.</p>
<p>Each setting also has a matching flag and environment variable for one-off overrides:</p>
<div class="language-shell codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-shell codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A"><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos terraform plan vpc </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-s</span><span class="token plain"> dev --init-mode</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">always</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"> dev --init-reconfigure</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">always</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 --init-upgrade</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">always</span><br></div></code></pre></div></div>
<p>The existing <code>init_run_reconfigure</code> boolean keeps working: <code>false</code> maps to <code>init.reconfigure: never</code>, and the previous default <code>true</code> now maps to <code>init.reconfigure: auto</code> rather than
<code>always</code>. Unlike <code>mode</code>/<code>upgrade</code>, this one isn't edition-protected — pinning an earlier edition
doesn't restore it, because <code>init.reconfigure</code> has to stay unset internally for the legacy
<code>init_run_reconfigure</code> mapping to keep working at all. Set <code>init.reconfigure: always</code> explicitly
to keep the exact previous behavior.</p>
<p>See <a class="" href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/components/terraform#configuration-reference">Terraform Configuration</a> for
the full setting reference, and <a class="" href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/terraform/init#automatic-initialization">Automatic Initialization</a>
for how the skip decision and recovery path work.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/smart-terraform-init#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>
        <author>
            <name>Erik Osterman</name>
            <uri>https://github.com/osterman</uri>
        </author>
        <category label="Feature" term="Feature"/>
        <category label="DX" term="DX"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Test Your Infrastructure After Deployment]]></title>
        <id>https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/test-steps</id>
        <link href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/test-steps"/>
        <updated>2026-09-11T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Run post-deployment checks with a test tree, progress, and failure-only output.]]></summary>
        <content type="html"><![CDATA[<p>A successful deployment still needs checks that the application is healthy.
Running those checks as ordinary commands can bury failures in successful logs
or stop before the remaining tests run. The new <a class="" href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/workflows/steps/type/test">test step</a>
collects the results, keeps passing output quiet, and reveals each failed check's logs.</p>
<div><div class="window_X9dN"><div class="titlebar_DN7h"><span class="dots_R2sg" aria-hidden="true"><i></i><i></i><i></i></span><span class="title_Dael">Post-deployment tests</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><div class="castActions_M13G"><div class="container_zGFV"><div class="group_ncGU" role="group" aria-label="Share this demo"><button type="button" class="primary_hpkh" title="Copy a link to this demo" aria-live="polite"><svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" class="icon_P_nE" aria-hidden="true" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><circle cx="18" cy="5" r="3"></circle><circle cx="6" cy="12" r="3"></circle><circle cx="18" cy="19" r="3"></circle><line x1="8.59" y1="13.51" x2="15.42" y2="17.49"></line><line x1="15.41" y1="6.51" x2="8.59" y2="10.49"></line></svg><span>Share</span></button><button type="button" class="caret_pPxC" aria-expanded="false" aria-label="More share options" title="More share options"><svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" class="icon_P_nE" aria-hidden="true" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><polyline points="6 9 12 15 18 9"></polyline></svg></button></div></div><div class="container_EXko"><button type="button" class="trigger_WxG7" aria-expanded="false" aria-label="Download cast"><svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" class="icon_LbC3" aria-hidden="true" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline points="7 10 12 15 17 10"></polyline><line x1="12" y1="15" x2="12" y2="3"></line></svg><span>Download</span><svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" class="icon_LbC3" aria-hidden="true" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><polyline points="6 9 12 15 18 9"></polyline></svg></button></div></div></div>
<p><a class="" href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/examples/tests">View the full example</a></p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/test-steps#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>Post-deployment checks need a clear result for every test, including independent
checks that can still run after another fails. Shell wrappers and CI-specific
reporting make that behavior harder to reuse locally and across deployments.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/test-steps#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>Atmos supports <code>type: test</code> in workflows, custom commands, and lifecycle hooks.
Tests continue by default, while a tree with green/red dots and a bottom progress
bar shows the results. Nested <a class="" href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/workflows/steps/type/parallel">parallel</a> and
<a class="" href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/workflows/steps/type/matrix">matrix</a> groups share the same report.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/test-steps#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>Attach a test step to an <code>after.terraform.apply</code> hook with <code>kind: step</code> and
<code>on_failure: fail</code> to make checks part of the deployment result. Use <code>output: all</code>
when debugging, or <code>fail.mode: fail_fast</code> when remaining checks should stop after
an error. CI receives a static tree with the same failure details.</p>
<p>See the <a class="" href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/workflows/steps/type/test">test step reference</a> for configuration and
failure behavior.</p>
<p>The local example runs without stacks. Running bare <a class="" href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/cli"><code>atmos</code></a> now displays
usage and available commands, including custom commands, without requiring stack
configuration.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/test-steps#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 <a class="" href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/examples/tests">local example</a> and share feedback in
<a href="https://github.com/cloudposse/atmos/discussions" target="_blank" rel="noopener noreferrer" class="">GitHub Discussions</a>.</p>]]></content>
        <author>
            <name>Erik Osterman</name>
            <uri>https://github.com/osterman</uri>
        </author>
        <category label="Feature" term="Feature"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Preview and Deploy Native Helm Value Overrides]]></title>
        <id>https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/native-helm-cli-value-overrides</id>
        <link href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/native-helm-cli-value-overrides"/>
        <updated>2026-09-09T12:00:00.000Z</updated>
        <summary type="html"><![CDATA[An urgent image rollback, a temporary feature flag, or a one-off chart setting should not require]]></summary>
        <content type="html"><![CDATA[<p>An urgent image rollback, a temporary feature flag, or a one-off chart setting should not require
editing a stack manifest just to make one deployment. Yet a preview is only useful when it renders
the exact values that the later deployment will use. When temporary values live in a shell wrapper
or are applied only at deploy time, teams cannot reliably see the change before it reaches a
cluster.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/native-helm-cli-value-overrides#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>Native Helm components already resolve chart values from inherited stack configuration, component
value files, and inline values. Before this update, there was no Helm-compatible command-line
override surface for those resolved values. Operators had to commit a temporary configuration
change, use a separate wrapper around Helm, or accept that a <code>diff</code> did not necessarily match the
subsequent deployment.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/native-helm-cli-value-overrides#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 now accepts repeatable Helm-compatible <code>-f</code>/<code>--values</code>, <code>--set</code>, <code>--set-string</code>,
<code>--set-file</code>, <code>--set-json</code>, and <code>--set-literal</code> flags on <code>template</code>/<code>render</code>, <code>diff</code>/<code>plan</code>, and
<code>apply</code>/<code>deploy</code>. The overrides apply only to the current invocation and take precedence over the
resolved component values; they never modify stack configuration.</p>
<p>The new <code>atmos helm values</code> command prints the final, masked value map as formatted YAML. It lets
you inspect the value set that a preview or deployment will consume, including temporary command
line overrides, without contacting Kubernetes.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/native-helm-cli-value-overrides#how-to-use-it" class="hash-link" aria-label="Direct link to How to Use It" title="Direct link to How to Use It" translate="no">​</a></h2>
<p>Use the same override arguments for inspection, preview, and deployment:</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 values monitoring </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-s</span><span class="token plain"> plat-ue2-dev </span><span class="token punctuation" style="color:rgb(199, 146, 234)">\</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-f</span><span class="token plain"> incident-values.yaml </span><span class="token punctuation" style="color:rgb(199, 146, 234)">\</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--set</span><span class="token plain"> </span><span class="token assign-left variable" style="color:rgb(214, 222, 235)">image.tag</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token number" style="color:rgb(247, 140, 108)">2026.09</span><span class="token plain">.09</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">atmos helm </span><span class="token function" style="color:rgb(130, 170, 255)">diff</span><span class="token plain"> monitoring </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-s</span><span class="token plain"> plat-ue2-dev </span><span class="token punctuation" style="color:rgb(199, 146, 234)">\</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-f</span><span class="token plain"> incident-values.yaml </span><span class="token punctuation" style="color:rgb(199, 146, 234)">\</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--set</span><span class="token plain"> </span><span class="token assign-left variable" style="color:rgb(214, 222, 235)">image.tag</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token number" style="color:rgb(247, 140, 108)">2026.09</span><span class="token plain">.09</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">atmos helm apply monitoring </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-s</span><span class="token plain"> plat-ue2-dev </span><span class="token punctuation" style="color:rgb(199, 146, 234)">\</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-f</span><span class="token plain"> incident-values.yaml </span><span class="token punctuation" style="color:rgb(199, 146, 234)">\</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--set</span><span class="token plain"> </span><span class="token assign-left variable" style="color:rgb(214, 222, 235)">image.tag</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token number" style="color:rgb(247, 140, 108)">2026.09</span><span class="token plain">.09</span><br></div></code></pre></div></div>
<p>Atmos layers command-line value files and each supported <code>--set</code> variant over the component's
resolved values using Helm's normal parsing and precedence rules. That includes nested paths,
list indexes, typed values, string and literal handling, JSON input, and file-backed values.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/native-helm-cli-value-overrides#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-3136.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/helm/usage#runtime-value-overrides">native Helm command reference</a> for
the complete override reference and the <a class="" href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/helm/values"><code>values</code></a> command guide.
Have feedback? <a href="https://github.com/cloudposse/atmos/issues" target="_blank" rel="noopener noreferrer" class="">Open an issue</a> or join the
<a href="https://cloudposse.com/slack" target="_blank" rel="noopener noreferrer" class="">Cloud Posse community Slack</a>.</p>]]></content>
        <author>
            <name>Erik Osterman</name>
            <uri>https://github.com/osterman</uri>
        </author>
        <category label="Feature" term="Feature"/>
        <category label="Experimental" term="Experimental"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[GitHub Enterprise Server Support]]></title>
        <id>https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/github-enterprise-server-support</id>
        <link href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/github-enterprise-server-support"/>
        <updated>2026-09-09T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Plenty of organizations run their own GitHub instance behind the firewall instead of using public github.com. Standard tools are expected to just work against it: GITHUBSERVERURL and GITHUBAPIURL are the same two variables GitHub Actions already exports on both public github.com and a GitHub Enterprise Server runner, precisely so that scripts and CLIs don't need special-casing.]]></summary>
        <content type="html"><![CDATA[<p>Plenty of organizations run their own GitHub instance behind the firewall instead of using public github.com. Standard tools are expected to just work against it: <code>GITHUB_SERVER_URL</code> and <code>GITHUB_API_URL</code> are the same two variables GitHub Actions already exports on both public github.com and a GitHub Enterprise Server runner, precisely so that scripts and CLIs don't need special-casing.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/github-enterprise-server-support#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>Atmos read those variables in a couple of places, but not consistently. The token allowlist that decides whether to attach a GitHub token to an outgoing request only recognized <code>api.github.com</code>, <code>raw.githubusercontent.com</code>, and <code>uploads.github.com</code>. Vendoring, remote imports, the CI provider, and the low-level GitHub API client each had their own github.com assumption baked in, hardcoded in a handful of different ways. On a GitHub Enterprise Server instance, that meant private-repo authentication, raw-content fetches, and CI metadata could silently fail or fall back to unauthenticated requests, depending on which code path happened to run.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/github-enterprise-server-support#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 resolves <code>GITHUB_SERVER_URL</code> and <code>GITHUB_API_URL</code> from one place and honors that resolution everywhere it talks to your own repositories: the CI provider, imports and vendoring, release/tag/artifact lookups, the token host allowlist, and token injection for git operations. Point Atmos at your GitHub Enterprise Server instance and vendoring, remote imports, <code>atmos git clone</code>, and CI metadata all resolve against it, with no <code>atmos.yaml</code> changes required.</p>
<p>Toolchain installs are a deliberately separate concern. The public Aqua registry that backs <code>atmos toolchain install</code> lives on public github.com regardless of where your own repositories are hosted, so toolchain traffic does <strong>not</strong> follow <code>GITHUB_SERVER_URL</code>. Without that separation, pointing Atmos at your GitHub Enterprise Server instance would break every <code>atmos toolchain install</code> on a GitHub Enterprise Server runner, since your instance obviously doesn't mirror the Aqua registry. Toolchain traffic gets its own variables instead, which default to public github.com and only need to be touched if you run a corporate release proxy or mirror.</p>
<p>One shorthand stays github.com-only on purpose: writing <code>github.com/org/repo</code> (or bare <code>org/repo</code>) in an import, a vendor manifest, or an AI skill source can't be resolved against an arbitrary Enterprise Server host, because a bare hostname is indistinguishable from a relative path. On GitHub Enterprise Server, write the full URL instead — with one exception: AI skill sources also recognize the <em>actual</em> configured host without a scheme (<code>github.example.com/org/repo</code>), since a skill source is always meant to be a repository reference, never a local path. Imports and vendor manifests don't make that same assumption, so they need the explicit scheme there too (<code>https://github.example.com/org/repo</code>). <code>atmos git clone</code> has no shorthand form at all, on github.com or GitHub Enterprise Server alike — it always needs a full URI (HTTPS, SCP-style, or go-getter syntax).</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/github-enterprise-server-support#how-to-use-it" class="hash-link" aria-label="Direct link to How to Use It" title="Direct link to How to Use It" translate="no">​</a></h2>
<p>Set the two standard variables to point Atmos at your instance:</p>
<div class="language-shell codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-shell codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A"><div class="token-line" style="color:#d6deeb"><span class="token builtin class-name" style="color:rgb(255, 203, 139)">export</span><span class="token plain"> </span><span class="token assign-left variable" style="color:rgb(214, 222, 235)">GITHUB_SERVER_URL</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">https://github.example.com</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token builtin class-name" style="color:rgb(255, 203, 139)">export</span><span class="token plain"> </span><span class="token assign-left variable" style="color:rgb(214, 222, 235)">GITHUB_API_URL</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">https://github.example.com/api/v3</span><br></div></code></pre></div></div>
<p>If you run a corporate proxy or mirror in front of public GitHub releases for toolchain installs, point the toolchain at it separately:</p>
<div class="language-shell codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-shell codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A"><div class="token-line" style="color:#d6deeb"><span class="token builtin class-name" style="color:rgb(255, 203, 139)">export</span><span class="token plain"> </span><span class="token assign-left variable" style="color:rgb(214, 222, 235)">ATMOS_TOOLCHAIN_GITHUB_URL</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">https://releases.corp.example.com</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token builtin class-name" style="color:rgb(255, 203, 139)">export</span><span class="token plain"> </span><span class="token assign-left variable" style="color:rgb(214, 222, 235)">ATMOS_TOOLCHAIN_GITHUB_API_URL</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">https://releases.corp.example.com/api/v3</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token builtin class-name" style="color:rgb(255, 203, 139)">export</span><span class="token plain"> </span><span class="token assign-left variable" style="color:rgb(214, 222, 235)">ATMOS_TOOLCHAIN_AQUA_REGISTRY_URL</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">https://releases.corp.example.com/aqua-registry/main</span><br></div></code></pre></div></div>
<p>Leave the toolchain variables unset and <code>atmos toolchain install</code> keeps installing tools from public github.com, exactly as before — even when <code>GITHUB_SERVER_URL</code> points at your own instance. See the <a class="" href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/cli/environment-variables#github-enterprise-server-ghes">environment variables reference</a> for the complete list and defaults.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/github-enterprise-server-support#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>Running Atmos against GitHub Enterprise Server and hitting a spot that still assumes public github.com? <a href="https://github.com/cloudposse/atmos/issues" target="_blank" rel="noopener noreferrer" class="">Open an issue</a> — the routing above covers the paths we could verify, but Enterprise Server deployments vary.</p>]]></content>
        <author>
            <name>Erik Osterman</name>
            <uri>https://github.com/osterman</uri>
        </author>
        <category label="Feature" term="Feature"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Read One Component Label with an Optional Default]]></title>
        <id>https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/label-value-lookup</id>
        <link href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/label-value-lookup"/>
        <updated>2026-09-09T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[A component can have several labels, while a variable may need only one value.]]></summary>
        <content type="html"><![CDATA[<p>A component can have several labels, while a variable may need only one value.
The <a class="" href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/functions/yaml/labels"><code>!labels</code> function</a> now accepts a key to read a single
component label, with an optional fallback when that label is absent.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/label-value-lookup#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>Individual labels are already accessible through Go templates, such as
<code>{{ .metadata.labels.owner }}</code>. The <a class="" href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/functions/yaml/labels"><code>!labels</code> function</a>
previously returned only the full map and accepted no key or fallback argument.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/label-value-lookup#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>Use <a class="" href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/functions/yaml/labels#single-label-lookup"><code>!labels key [default]</code></a> to retrieve a string
from the component’s resolved <a class="" href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/stacks/components/component-metadata#labels">metadata labels</a>.
An absent key uses the explicit default or produces an error if none was supplied.
Existing empty-string values are preserved. Bare <code>!labels</code> continues to return the full map.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/label-value-lookup#how-to-use-it" class="hash-link" aria-label="Direct link to How to Use It" title="Direct link to How to Use It" translate="no">​</a></h2>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token key atrule">components</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">terraform</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">vpc</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">metadata</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">labels</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">          </span><span class="token key atrule">cost-center</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> platform</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">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">cost_center</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token tag" style="color:rgb(127, 219, 202)">!labels</span><span class="token plain"> cost</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">center</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">owner</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token tag" style="color:rgb(127, 219, 202)">!labels</span><span class="token plain"> owner "Platform Team"</span></span><br></div></code></pre></div></div>
<p>Here <code>cost_center</code> resolves to <code>platform</code>. If the resolved metadata has no <code>owner</code> label
after stack defaults and component inheritance, <code>owner</code> resolves to the explicit fallback,
<code>Platform Team</code>. An inherited <code>owner</code> label supplies its value instead.</p>
<p>Keys are literal, including dots, slashes, and hyphens. Quote fallback values containing spaces;
use <code>""</code> when the fallback should be an empty string. Values reflect
<a class="" href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/stacks/components/component-metadata#global-stack-wide-metadata">stack defaults and component inheritance</a>.</p>
<p>See the <a class="" href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/functions/yaml/labels">label lookup reference</a> for full-map access and
Go template equivalents.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/label-value-lookup#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>Share your label lookup use cases in <a href="https://github.com/orgs/cloudposse/discussions" target="_blank" rel="noopener noreferrer" class="">Atmos discussions</a>.</p>]]></content>
        <author>
            <name>Erik Osterman</name>
            <uri>https://github.com/osterman</uri>
        </author>
        <category label="Enhancement" term="Enhancement"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Conditional Component Dependencies]]></title>
        <id>https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/conditional-component-dependencies</id>
        <link href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/conditional-component-dependencies"/>
        <updated>2026-09-08T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Infrastructure graphs often include dependencies that are useful when present but should not block an environment when a component is intentionally absent or disabled. Treating every dependency as mandatory forces stack-specific workarounds and makes reusable manifests harder to share.]]></summary>
        <content type="html"><![CDATA[<p>Infrastructure graphs often include dependencies that are useful when present but should not block an environment when a component is intentionally absent or disabled. Treating every dependency as mandatory forces stack-specific workarounds and makes reusable manifests harder to share.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/conditional-component-dependencies#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>A component dependency previously meant that the target had to exist and be available. That is correct for core infrastructure, but too strict for optional integrations such as observability, auxiliary services, or environment-specific components. Teams had to duplicate manifests or maintain separate dependency lists just to handle those differences.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/conditional-component-dependencies#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>Component dependencies can now declare <code>required: false</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">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">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 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"> observability</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">required</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><br></div></code></pre></div></div>
<p>Required dependencies remain the default, preserving existing behavior. Optional dependencies are included normally when their target is present, enabled, and concrete. Missing, disabled, or abstract targets simply omit that edge. Invalid dependency configuration still fails instead of being hidden by optionality.</p>
<p>The <code>required</code> value can also be rendered from a template. Atmos applies the configured template delimiters before parsing the result as a boolean:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A"><div class="token-line" style="color:#d6deeb"><span class="token key atrule">required</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)">"[[ .vars.enable_monitoring ]]"</span><br></div></code></pre></div></div>
<p>This allows one manifest to use environment-specific optionality without assuming the default <code>{{</code> and <code>}}</code> delimiters.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/conditional-component-dependencies#how-to-use-it" class="hash-link" aria-label="Direct link to How to Use It" title="Direct link to How to Use It" translate="no">​</a></h2>
<p>Use <code>required: false</code> for a dependency that should participate in ordering when available but should not prevent the declaring component from running when unavailable:</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">application</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line 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">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 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"> network</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">          </span><span class="token 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"> monitoring</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">            </span><span class="token key atrule">stack</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"{{ .vars.environment }}-observability"</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">            </span><span class="token key atrule">required</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><br></div></code></pre></div></div>
<p>Omit <code>required</code> when the target must be present, enabled, and concrete. Optionality only suppresses missing, disabled, or abstract targets; malformed entries remain errors.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/conditional-component-dependencies#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>Try conditional dependencies in your stack manifests and share feedback through <a href="https://github.com/cloudposse/atmos/issues" target="_blank" rel="noopener noreferrer" class="">GitHub</a>.</p>]]></content>
        <author>
            <name>Zack A</name>
            <uri>https://github.com/zack-is-cool</uri>
        </author>
        <category label="Feature" term="Feature"/>
        <category label="Enhancement" term="Enhancement"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Keep version fields in YAML files in sync without losing comments]]></title>
        <id>https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/version-tracker-yaml-manager</id>
        <link href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/version-tracker-yaml-manager"/>
        <updated>2026-09-07T13:00:00.000Z</updated>
        <summary type="html"><![CDATA[A Helm values file, a docker-compose override, or any other hand-maintained YAML config often carries]]></summary>
        <content type="html"><![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-3136.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-3136.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-3136.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 <a class="" href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/config/config-set"><code>atmos config set</code></a> and
<a class="" href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/stack/stack-set"><code>atmos stack set</code></a> — 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-3136.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><a class="" href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/version/track/apply"><code>atmos version track apply</code></a> 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-3136.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-3136.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>
        <author>
            <name>Erik Osterman</name>
            <uri>https://github.com/osterman</uri>
        </author>
        <category label="Feature" term="Feature"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Reshape a version before writing it into a JSON file]]></title>
        <id>https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/json-manager-format</id>
        <link href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/json-manager-format"/>
        <updated>2026-09-07T12:00:00.000Z</updated>
        <summary type="html"><![CDATA[Git tags on GitHub almost always carry a v prefix — v1.228.0 — because that's the convention]]></summary>
        <content type="html"><![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-3136.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-3136.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-3136.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-3136.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-3136.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-3136.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>
        <author>
            <name>Erik Osterman</name>
            <uri>https://github.com/osterman</uri>
        </author>
        <category label="Enhancement" term="Enhancement"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Declarative Release Lifecycle for Native Helm Components]]></title>
        <id>https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/native-helm-release-lifecycle</id>
        <link href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/native-helm-release-lifecycle"/>
        <updated>2026-09-07T00:00:00.000Z</updated>
        <summary type="html"><![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.]]></summary>
        <content type="html"><![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-3136.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-3136.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-3136.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>
<p>For usage and configuration, see <a class="" href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/helm/apply">atmos helm apply</a>.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-3136.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>
        <author>
            <name>Mikhail Shirkov</name>
            <uri>https://github.com/shirkevich</uri>
        </author>
        <category label="Feature" term="Feature"/>
        <category label="Experimental" term="Experimental"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Vendor Update Pull Requests, Now on Azure DevOps]]></title>
        <id>https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/azuredevops-pull-request-provider</id>
        <link href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/azuredevops-pull-request-provider"/>
        <updated>2026-09-04T12:00:00.000Z</updated>
        <summary type="html"><![CDATA[Automating the last mile of a dependency bump — branch, commit, push, open a pull request — only]]></summary>
        <content type="html"><![CDATA[<p>Automating the last mile of a dependency bump — branch, commit, push, open a pull request — only
pays off if it works wherever the repository actually lives. A team standardized on Azure DevOps
Repos instead of GitHub gets none of that: every vendor sync still ends in a manual PR, or a
one-off script bolted on just to close the gap.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/azuredevops-pull-request-provider#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>The Component Updater (<code>atmos vendor update --pull-request</code>) already discovers component updates
and opens or refreshes a pull request for them, but it only spoke to GitHub. Projects hosted in
Azure DevOps Repos couldn't use the flag at all — every automated sync there still ended with
someone opening the PR by hand.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/azuredevops-pull-request-provider#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>The <code>ci.pull_request.provider</code> field now accepts <code>azuredevops</code> alongside the existing <code>github</code> value. It
follows the same create-or-update contract: Atmos looks for an already-open pull request between
the same source and target branches first, updates that pull request's title and description in
place when one exists, and only opens a new one when none does — so re-running a vendor sync never
piles up duplicate PRs, regardless of which provider is configured.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/azuredevops-pull-request-provider#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>Azure DevOps addresses a repository with three parts — organization, project, and repository —
rather than GitHub's owner/repository pair, so those are explicit config fields instead of being
derived from the Git remote:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token key atrule">vendor</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">ci</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">pull_request</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">provider</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> azuredevops</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">organization</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> my</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">org</span></span><br></div><div class="token-line 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</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">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">repository</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">repo</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">branch_prefix</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> atmos/component</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">updater</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">title</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"chore(components): update {{ .scope.name }}"</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">labels</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token plain">component</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">update</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">reviewers</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">alice</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> bob</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span></span><br></div></code></pre></div></div>
<p>Authenticate with a personal access token in <code>AZURE_DEVOPS_EXT_PAT</code>, granted Code (Read &amp; Write)
on the target project, then run the update exactly as before:</p>
<div class="language-shell codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-shell codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A"><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos vendor update --pull-request</span><br></div></code></pre></div></div>
<p>Labels and reviewers apply the same way they do on GitHub. Assignees don't — Azure DevOps pull
requests have no assignee concept, so setting <code>ci.pull_request.assignees</code> with
<code>provider: azuredevops</code> fails loudly instead of silently dropping the configuration; use
<code>reviewers</code> there instead.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/azuredevops-pull-request-provider#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>Questions about the Azure DevOps provider, or requests for another forge, are welcome in the
<a href="https://github.com/cloudposse/atmos" target="_blank" rel="noopener noreferrer" class="">Atmos GitHub repository</a> and the community Slack.</p>]]></content>
        <author>
            <name>Jorrit Elfferich</name>
            <uri>https://github.com/jorrite</uri>
        </author>
        <category label="Feature" term="Feature"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Automatically Create the Configured Namespace for Helm Releases]]></title>
        <id>https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/native-helm-create-namespace</id>
        <link href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/native-helm-create-namespace"/>
        <updated>2026-09-02T12:00:00.000Z</updated>
        <summary type="html"><![CDATA[Atmos lets you configure the Kubernetes namespace where a Helm release should be installed. This]]></summary>
        <content type="html"><![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-3136.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-3136.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-3136.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>
<p>For usage and configuration, see <a class="" href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/helm/apply">atmos helm apply</a>.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-3136.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>
        <author>
            <name>Andriy Knysh</name>
            <uri>https://github.com/aknysh</uri>
        </author>
        <category label="Enhancement" term="Enhancement"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Toolchain Installs Are Reproducible by Default Now]]></title>
        <id>https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/toolchain-lockfile-default</id>
        <link href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/toolchain-lockfile-default"/>
        <updated>2026-09-01T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Atmos's toolchain has had a lockfile for a while. The lockfile records the exact resolved artifact]]></summary>
        <content type="html"><![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-3136.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 <a class="" href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/toolchain/install"><code>atmos toolchain install</code></a> 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-3136.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 <a class="" href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/toolchain/lock"><code>atmos toolchain lock</code></a> (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-3136.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 <a class="" href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/toolchain/usage"><code>atmos toolchain</code></a> 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-3136.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>
        <author>
            <name>Erik Osterman</name>
            <uri>https://github.com/osterman</uri>
        </author>
        <category label="Experimental" term="Experimental"/>
        <category label="Enhancement" term="Enhancement"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Component retry now covers Helmfile, Packer, and Ansible too]]></title>
        <id>https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/retry-helmfile-packer-ansible</id>
        <link href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/retry-helmfile-packer-ansible"/>
        <updated>2026-08-31T13:00:00.000Z</updated>
        <summary type="html"><![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.]]></summary>
        <content type="html"><![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-3136.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-3136.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-3136.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-3136.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-3136.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>
        <author>
            <name>Erik Osterman</name>
            <uri>https://github.com/osterman</uri>
        </author>
        <category label="Enhancement" term="Enhancement"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Distribute scaffold templates through your existing OCI registry]]></title>
        <id>https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/scaffold-oci-sources</id>
        <link href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/scaffold-oci-sources"/>
        <updated>2026-08-31T12:00:00.000Z</updated>
        <summary type="html"><![CDATA[If your team already publishes container images, Atmos components, or Helm charts to a private]]></summary>
        <content type="html"><![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-3136.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 <a class="" href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/scaffold/generate"><code>atmos scaffold generate</code></a> and <a class="" href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/init"><code>atmos init</code></a> 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-3136.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 <a class="" href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/vendor/pull"><code>atmos vendor pull</code></a> 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-3136.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. <a class="" href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/scaffold/generate"><code>--update</code></a>'s three-way merge, <a class="" href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/scaffold/generate"><code>--git</code></a>/<a class="" href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/scaffold/generate"><code>--no-git</code></a>, 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-3136.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>
        <author>
            <name>Jorrit Elfferich</name>
            <uri>https://github.com/jorrite</uri>
        </author>
        <category label="Feature" term="Feature"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Set one retry policy for a whole stack]]></title>
        <id>https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/stack-level-retry-defaults</id>
        <link href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/stack-level-retry-defaults"/>
        <updated>2026-08-31T12:00:00.000Z</updated>
        <summary type="html"><![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.]]></summary>
        <content type="html"><![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-3136.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-3136.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-3136.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-3136.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-3136.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>
        <author>
            <name>Erik Osterman</name>
            <uri>https://github.com/osterman</uri>
        </author>
        <category label="Enhancement" term="Enhancement"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Prompt choices that follow earlier answers]]></title>
        <id>https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/scaffold-dynamic-options</id>
        <link href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/scaffold-dynamic-options"/>
        <updated>2026-08-28T12:00:00.000Z</updated>
        <summary type="html"><![CDATA[Every interactive form with a fixed set of choices eventually hits the same problem: at some]]></summary>
        <content type="html"><![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-3136.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-3136.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-3136.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-3136.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-3136.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>
        <author>
            <name>Jorrit Elfferich</name>
            <uri>https://github.com/jorrite</uri>
        </author>
        <category label="Feature" term="Feature"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[See CI and Atmos Pro Status at a Glance]]></title>
        <id>https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/ci-startup-status</id>
        <link href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/ci-startup-status"/>
        <updated>2026-08-27T12:00:00.000Z</updated>
        <summary type="html"><![CDATA[GitHub Actions is the most popular way teams run Atmos in CI, and a lot of those pipelines are]]></summary>
        <content type="html"><![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-3136.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-3136.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-3136.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-3136.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-3136.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/ci"><code>ci</code></a> and <a class="" href="https://pr-3136.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-3136.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>
        <author>
            <name>Erik Osterman</name>
            <uri>https://github.com/osterman</uri>
        </author>
        <category label="Feature" term="Feature"/>
        <category label="DX" term="DX"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Introducing Streaming UI: Real-Time Progress for Terraform Commands]]></title>
        <id>https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/terraform-streaming-ui</id>
        <link href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/terraform-streaming-ui"/>
        <updated>2026-08-25T00:00:00.000Z</updated>
        <summary type="html"><![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.]]></summary>
        <content type="html"><![CDATA[<p>Say goodbye to overwhelming Terraform output. The new <a class="" href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/components/terraform">streaming UI</a> 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><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><div class="castActions_M13G"><div class="container_zGFV"><div class="group_ncGU" role="group" aria-label="Share this demo"><button type="button" class="primary_hpkh" title="Copy a link to this demo" aria-live="polite"><svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" class="icon_P_nE" aria-hidden="true" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><circle cx="18" cy="5" r="3"></circle><circle cx="6" cy="12" r="3"></circle><circle cx="18" cy="19" r="3"></circle><line x1="8.59" y1="13.51" x2="15.42" y2="17.49"></line><line x1="15.41" y1="6.51" x2="8.59" y2="10.49"></line></svg><span>Share</span></button><button type="button" class="caret_pPxC" aria-expanded="false" aria-label="More share options" title="More share options"><svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" class="icon_P_nE" aria-hidden="true" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><polyline points="6 9 12 15 18 9"></polyline></svg></button></div></div><div class="container_EXko"><button type="button" class="trigger_WxG7" aria-expanded="false" aria-label="Download cast"><svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" class="icon_LbC3" aria-hidden="true" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline points="7 10 12 15 17 10"></polyline><line x1="12" y1="15" x2="12" y2="3"></line></svg><span>Download</span><svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" class="icon_LbC3" aria-hidden="true" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><polyline points="6 9 12 15 18 9"></polyline></svg></button></div></div></div>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="what-changed">What Changed<a href="https://pr-3136.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-3136.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-3136.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-3136.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-3136.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-3136.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-3136.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-3136.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-3136.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-3136.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-3136.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-3136.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-3136.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-3136.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/components/terraform">Terraform Configuration Reference</a></li>
<li class=""><a class="" href="https://pr-3136.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/terraform/plan">atmos terraform plan</a></li>
<li class=""><a class="" href="https://pr-3136.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-3136.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>
        <author>
            <name>Erik Osterman</name>
            <uri>https://github.com/osterman</uri>
        </author>
        <category label="Feature" term="Feature"/>
        <category label="DX" term="DX"/>
    </entry>
</feed>