<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <id>https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog</id>
    <title>atmos Blog</title>
    <updated>2026-09-02T12:00:00.000Z</updated>
    <generator>https://github.com/jpmonette/feed</generator>
    <link rel="alternate" href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog"/>
    <subtitle>atmos Blog</subtitle>
    <icon>https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/img/atmos-logo.png</icon>
    <entry>
        <title type="html"><![CDATA[Automatically Create the Configured Namespace for Helm Releases]]></title>
        <id>https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/native-helm-create-namespace</id>
        <link href="https://pr-3036.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-3036.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-3036.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-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/native-helm-create-namespace#when-to-use-it" class="hash-link" aria-label="Direct link to When to Use It" title="Direct link to When to Use It" translate="no">​</a></h2>
<p>Keep <code>create_namespace</code> enabled (the default) when the Helm deployment should manage its own namespace
and the deploying identity has permission to create namespaces.</p>
<p>Set it to <code>false</code> when namespaces are managed separately, for example when a platform component is
responsible for namespace labels, quotas, NetworkPolicies, or other guardrails, or when the deploy
identity is scoped to a single namespace.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-3036.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[Template Engine Upgrade Drops the End-of-Life AWS SDK from Atmos]]></title>
        <id>https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/gomplate-v5</id>
        <link href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/gomplate-v5"/>
        <updated>2026-09-02T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Some scanner findings cannot be fixed by bumping a version. A dependency reaches end of life, its]]></summary>
        <content type="html"><![CDATA[<p>Some scanner findings cannot be fixed by bumping a version. A dependency reaches end of life, its
advisories stay open forever, and every project that pulls it in transitively inherits a permanent
red mark. Atmos had exactly this problem: the template engine embedded in Atmos depended on the
AWS SDK for Go v1, which is no longer maintained and carries advisories that no v1 release will
ever address. Atmos never executed the affected code, but supply-chain scanners flagged it
anyway, and there was no version of Atmos that could make the finding go away. The template
engine has now moved to Gomplate v5, and the end-of-life SDK is gone from the Atmos build
entirely.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/gomplate-v5#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>Atmos stack manifests support Go templates, and the Gomplate library supplies most of the
functions and every datasource behind them. The version Atmos embedded, Gomplate v3, was built on
the AWS SDK for Go v1. AWS retired that SDK, and its open advisories (GO-2022-0635 and
GO-2022-0646) will never be resolved upstream because there will never be another v1 release.</p>
<p>Tools like OpenSSF Scorecard and dependency scanners do not distinguish between a library you
call and a library that merely sits in your dependency tree. Every Atmos release showed the same
findings, and the only honest explanation was that the code is present but never reached. That is
not an answer anyone should have to keep giving. The only way to clear it was to remove the SDK
from the build altogether, which meant upgrading the template engine across two major versions.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/gomplate-v5#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>Atmos now embeds Gomplate v5, which is built on the AWS SDK for Go v2. Every Gomplate function and
datasource that Atmos supported before continues to work, and Sprig functions are still layered on
top by default. What changed is what ships inside the binary: the AWS SDK for Go v1 is no longer
present in any form.</p>
<p>One HashiCorp Vault authentication library still pulled the old SDK in its latest tagged release,
even though its development branch had already been ported to v2. Atmos pins that library to the
ported development revision until HashiCorp tags a release. That pin is temporary. Dependabot will
propose the bump automatically as soon as a tagged release exists, and nothing about how you use
Vault datasources changes in the meantime.</p>
<p>The same upgrade moved the Go cryptography library to a release that closes two SSH-related
denial-of-service advisories (GO-2026-6354 and GO-2026-6355). This is preventative hygiene, not a
response to an exploited issue, but it is one more finding that will no longer appear on a scan of
Atmos.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="what-to-check-in-your-stacks">What to Check in Your Stacks<a href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/gomplate-v5#what-to-check-in-your-stacks" class="hash-link" aria-label="Direct link to What to Check in Your Stacks" title="Direct link to What to Check in Your Stacks" translate="no">​</a></h2>
<p>Gomplate removed functions it had deprecated in v3 and changed a few datasource behaviors between
v3 and v5. Most stacks will need no changes. If yours uses any of the following, update the
template before upgrading. The <a class="" href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/templates">templates configuration reference</a>
and the <a class="" href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/templates/datasources">datasources reference</a> carry the same list.</p>
<h3 class="anchor anchorTargetStickyNavbar_cA1_" id="renamed-functions">Renamed functions<a href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/gomplate-v5#renamed-functions" class="hash-link" aria-label="Direct link to Renamed functions" title="Direct link to Renamed functions" translate="no">​</a></h3>
<p>Deprecated function names were removed. Replace them with their namespaced equivalents:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Before</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain"></span><span class="token key atrule">enabled</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'{{ conv.Bool .vars.flag }}'</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain"></span><span class="token key atrule">names</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'{{ conv.Slice "a" "b" }}'</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain"></span><span class="token key atrule">cfg</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'{{ conv.Dict "k" "v" }}'</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain"></span><span class="token key atrule">has</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'{{ conv.Has .vars "key" }}'</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain"></span><span class="token key atrule">sorted</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'{{ strings.Sort .vars.list }}'</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain"></span><span class="token key atrule">ip</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'{{ net.ParseIP .vars.addr }}'</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain"></span><span class="token key atrule">cidr</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'{{ net.ParseIPPrefix .vars.cidr }}'</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain" style="display:inline-block"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># After</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain"></span><span class="token key atrule">enabled</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'{{ conv.ToBool .vars.flag }}'</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain"></span><span class="token key atrule">names</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'{{ coll.Slice "a" "b" }}'</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain"></span><span class="token key atrule">cfg</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'{{ coll.Dict "k" "v" }}'</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain"></span><span class="token key atrule">has</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'{{ coll.Has .vars "key" }}'</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain"></span><span class="token key atrule">sorted</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'{{ coll.Sort .vars.list }}'</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain"></span><span class="token key atrule">ip</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'{{ net.ParseAddr .vars.addr }}'</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain"></span><span class="token key atrule">cidr</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'{{ net.ParsePrefix .vars.cidr }}'</span></span><br></div></code></pre></div></div>
<p>The unqualified aliases <code>slice</code>, <code>contains</code>, <code>hasPrefix</code>, <code>hasSuffix</code>, <code>split</code>, <code>splitN</code>, and
<code>trim</code> are no longer registered by Gomplate. In practice most of them keep working: <code>slice</code> is a
built-in of Go templates, and <code>contains</code>, <code>hasPrefix</code>, <code>hasSuffix</code>, <code>split</code>, and <code>trim</code> are also
defined by Sprig, which Atmos enables by default through <code>templates.settings.sprig.enabled</code>. Be
aware that Sprig's argument order differs from Gomplate's for some of these. The only alias with
no fallback is <code>splitN</code>; replace it with <code>strings.SplitN</code>. If you have disabled Sprig, switch all of
them to their <code>strings.*</code> or <code>coll.*</code> forms.</p>
<h3 class="anchor anchorTargetStickyNavbar_cA1_" id="conversions-and-regular-expressions-now-fail-loudly">Conversions and regular expressions now fail loudly<a href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/gomplate-v5#conversions-and-regular-expressions-now-fail-loudly" class="hash-link" aria-label="Direct link to Conversions and regular expressions now fail loudly" title="Direct link to Conversions and regular expressions now fail loudly" translate="no">​</a></h3>
<p>Conversion functions such as <code>conv.ToInt64</code>, <code>conv.ToFloat64</code>, and <code>conv.Atoi</code> used to return <code>0</code>
when handed something they could not convert. They now return an error, which surfaces as a
template processing failure. If a stack relied on the silent zero, guard the input first:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A"><div class="token-line" style="color:#d6deeb"><span class="token key atrule">retries</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'{{ if .vars.retries }}{{ conv.ToInt64 .vars.retries }}{{ else }}0{{ end }}'</span><br></div></code></pre></div></div>
<p>Similarly, the <code>regexp.*</code> functions return an error for an invalid pattern instead of panicking.
The failure is the same as before from your point of view, but the message now names the template
and the pattern.</p>
<h3 class="anchor anchorTargetStickyNavbar_cA1_" id="datasource-subpaths-are-relative-urls">Datasource subpaths are relative URLs<a href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/gomplate-v5#datasource-subpaths-are-relative-urls" class="hash-link" aria-label="Direct link to Datasource subpaths are relative URLs" title="Direct link to Datasource subpaths are relative URLs" translate="no">​</a></h3>
<p>A second argument to <code>datasource</code> is resolved as a relative URL against the datasource's <code>url</code>.
Directory datasources must end with a trailing <code>/</code>, and a subpath that begins with <code>/</code> replaces
the base path rather than appending to it:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token key atrule">settings</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">templates</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">settings</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">gomplate</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">datasources</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">          </span><span class="token key atrule">configs</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">            </span><span class="token key atrule">url</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"file:///configs/"</span><span class="token plain">   </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># trailing slash marks a directory</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain" style="display:inline-block"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain"></span><span class="token key atrule">components</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">terraform</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">app</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">vars</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'{{ (datasource "configs" "app.yaml").name }}'</span><span class="token plain">   </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># reads /configs/app.yaml</span></span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_cA1_" id="aws-parameter-store-values-are-returned-directly">AWS Parameter Store values are returned directly<a href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/gomplate-v5#aws-parameter-store-values-are-returned-directly" class="hash-link" aria-label="Direct link to AWS Parameter Store values are returned directly" title="Direct link to AWS Parameter Store values are returned directly" translate="no">​</a></h3>
<p>An <code>aws+smp://</code> datasource returns the parameter's value itself rather than an object with a
<code>.Value</code> field. Drop the field access, and if the parameter holds a JSON document, tell the
datasource to parse it with the <code>type</code> query parameter:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token key atrule">settings</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">templates</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">settings</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">gomplate</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">datasources</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">          </span><span class="token key atrule">database</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">            </span><span class="token key atrule">url</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"aws+smp:///myapp/database/config?type=application/json"</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain" style="display:inline-block"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain"></span><span class="token key atrule">components</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">terraform</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">app</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">vars</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Before: '{{ (datasource "database").Value.host }}'</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">db_host</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'{{ (datasource "database").host }}'</span></span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_cA1_" id="smaller-datasource-changes">Smaller datasource changes<a href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/gomplate-v5#smaller-datasource-changes" class="hash-link" aria-label="Direct link to Smaller datasource changes" title="Direct link to Smaller datasource changes" translate="no">​</a></h3>
<p>Consul directory listings (a <code>consul://</code> URL ending in <code>/</code>) return a list of key names instead of
a map. BoltDB datasources were removed upstream and are no longer available.</p>
<h3 class="anchor anchorTargetStickyNavbar_cA1_" id="new-semantic-version-helpers">New: semantic version helpers<a href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/gomplate-v5#new-semantic-version-helpers" class="hash-link" aria-label="Direct link to New: semantic version helpers" title="Direct link to New: semantic version helpers" translate="no">​</a></h3>
<p>Gomplate v5 adds a <code>semver.*</code> namespace for parsing and comparing versions inside templates, for
example <code>{{ semver.CheckConstraint "&gt;= 1.5.0" .vars.version }}</code>. See the
<a href="https://docs.gomplate.ca/functions/semver/" target="_blank" rel="noopener noreferrer" class="">Gomplate semver reference</a> for the full list.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/gomplate-v5#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>If a template that worked before this release fails after it, and the cause is not on the list
above, <a href="https://github.com/cloudposse/atmos/issues" target="_blank" rel="noopener noreferrer" class="">open an issue</a> with the template expression
and the error. The goal of this upgrade was to change what ships in the binary, not what your
stacks can do.</p>]]></content>
        <author>
            <name>Erik Osterman</name>
            <uri>https://github.com/osterman</uri>
        </author>
        <category label="Security" term="Security"/>
        <category label="Breaking Change" term="Breaking Change"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Toolchain Installs Are Reproducible by Default Now]]></title>
        <id>https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/toolchain-lockfile-default</id>
        <link href="https://pr-3036.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-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/toolchain-lockfile-default#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>A version in <code>.tool-versions</code> pins what you asked for. It does not pin what Atmos actually
installed. Every <code>atmos toolchain install</code> command resolves that version against the live registry
again. The exact download URL, checksum, and platform artifact are not fixed anywhere. Only the
version number is fixed.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/toolchain-lockfile-default#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>Toolchain installs now write a lockfile by default. You do not need to configure anything. Run
<code>atmos toolchain install</code>. Atmos records the exact resolved version, download URL, checksum, and
size for your platform. Installs skip a tool that already exists on disk, so an already-installed
tool will not get a lockfile entry until you run <code>atmos toolchain lock</code> (or reinstall it with
<code>atmos toolchain install --reinstall</code>). Once every tool has an entry, the next install resolves
against the lockfile instead of asking the registry again, on your machine, a teammate's, or in
CI. Reproducibility holds per platform: everyone on an operating system and architecture with a
matching lock entry gets the same artifact, byte for byte.</p>
<p>If a project's <code>atmos.yaml</code> pins an edition dated before this change, the project keeps the old
opt-in behavior. Nothing changes for a project that relied on the previous default. New and
unpinned projects get the lockfile from the start.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/toolchain-lockfile-default#how-to-use-it" class="hash-link" aria-label="Direct link to How to Use It" title="Direct link to How to Use It" translate="no">​</a></h2>
<p>You do not need to opt in. Install as usual:</p>
<div class="language-shell codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-shell codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A"><div class="token-line" style="color:#d6deeb"><span class="token plain">$ atmos toolchain </span><span class="token function" style="color:rgb(130, 170, 255)">install</span><br></div></code></pre></div></div>
<p>Commit the resulting <code>toolchain.lock.yaml</code> file next to <code>.tool-versions</code>. If some of those tools
were already installed before you ran this, run <code>atmos toolchain lock</code> too -- <code>atmos toolchain install</code> won't touch a tool it finds already on disk, so it can leave that tool's entry missing.
Once every tool has an entry, every install resolves the exact pinned artifact for that platform.
This applies on your machine, a teammate's machine, and a CI runner. Atmos does not resolve the
version against the registry again.</p>
<p>The <code>atmos toolchain</code> command is still experimental. Its interface may change. The reproducibility
does not depend on that.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-3036.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-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/retry-helmfile-packer-ansible</id>
        <link href="https://pr-3036.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-3036.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-3036.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-3036.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-3036.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-3036.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-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/scaffold-oci-sources</id>
        <link href="https://pr-3036.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-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/scaffold-oci-sources#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>Both <code>atmos scaffold generate</code> and <code>atmos init</code> could already pull templates from git, HTTPS, and
S3 sources, but nothing else. A team standardizing on OCI for internal distribution —
components, container images, Helm charts — had no way to publish a scaffold template the same
way. Templates were the one artifact type still forced onto a separate channel.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/scaffold-oci-sources#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>Both commands now accept an <code>oci://</code> source directly, pulled through the same client Atmos
already uses for <code>atmos vendor pull</code> and just-in-time component provisioning. Authentication
follows the identical precedence: Docker credentials from <code>docker login</code>, then
<code>ATMOS_GITHUB_TOKEN</code> for <code>ghcr.io</code>, then anonymous — nothing new to configure if OCI sources are
already working elsewhere in the project.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/scaffold-oci-sources#how-to-use-it" class="hash-link" aria-label="Direct link to How to Use It" title="Direct link to How to Use It" translate="no">​</a></h2>
<p>Point either command at an OCI reference the same way you would a git URL:</p>
<div class="language-shell codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-shell codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A"><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos scaffold generate oci://ghcr.io/example/templates:v1.0.0 ./components/terraform/vpc</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos init oci://ghcr.io/example/templates:v1.0.0 ./my-project</span><br></div></code></pre></div></div>
<p>A version lives directly in the reference (<code>:v1.0.0</code>), the same way an OCI vendor source is
pinned — there's no separate <code>--ref</code> flag to learn for this case, since that flag only ever
applied to git sources. <code>--update</code>'s three-way merge, <code>--git</code>/<code>--no-git</code>, and <code>--base-ref</code> all
work exactly as they already do for every other source type: the merge base always comes from
the generated project's own git history, never from re-fetching the template, so switching a
template to OCI changes nothing about how updates behave.
A <code>scaffold.templates</code> entry in <code>atmos.yaml</code> can point at an <code>oci://...</code> source too, right
alongside existing git-hosted entries.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-3036.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-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/stack-level-retry-defaults</id>
        <link href="https://pr-3036.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-3036.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-3036.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-3036.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-3036.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-3036.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-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/scaffold-dynamic-options</id>
        <link href="https://pr-3036.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-3036.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-3036.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-3036.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-3036.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-3036.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-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/ci-startup-status</id>
        <link href="https://pr-3036.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-3036.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-3036.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-3036.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-3036.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-3036.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/ci"><code>ci</code></a> and <a class="" href="https://pr-3036.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-3036.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[Atmos binaries now build with Go's FIPS 140-3 crypto module by default]]></title>
        <id>https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/fips-140-mode</id>
        <link href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/fips-140-mode"/>
        <updated>2026-08-24T12:00:00.000Z</updated>
        <summary type="html"><![CDATA[Federal agencies, financial institutions, and healthcare organizations are often required to run]]></summary>
        <content type="html"><![CDATA[<p>Federal agencies, financial institutions, and healthcare organizations are often required to run
only cryptography that's been validated against FIPS 140, the U.S. government's standard for
approved algorithms and key sizes. For a command-line tool built on a general-purpose language
runtime, meeting that bar has traditionally meant compiling against a separate validated crypto
library, or simply hoping the runtime's own TLS and encryption code happens to stick to approved
algorithms.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/fips-140-mode#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>Atmos talks to a lot of TLS endpoints — cloud provider APIs, git servers, artifact registries,
the Terraform module registry. Every one of those connections depends on the cryptography built
into the Go runtime atmos is compiled with. Until now, nothing about that cryptography was
validated or restricted to FIPS-approved algorithms; it just used whatever Go's standard library
picked. Operators who needed a FIPS 140-3 claim for their toolchain had no way to get one from an
official atmos release.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/fips-140-mode#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>Every officially released atmos binary — along with every binary built from a checkout using
<code>atmos build</code> — now links Go's own FIPS 140-3 crypto module and defaults to enforcing FIPS
140-3 mode at runtime. Go standard-library TLS connections, key generation, and hashing are
restricted to FIPS-approved algorithms and key sizes automatically. No flag, environment
variable, or config change is required.</p>
<p>This covers the TLS and cryptography atmos itself uses for outbound connections, and it's FIPS
140-3 <em>mode</em> — enforced by Go's runtime — not a CMVP compliance certification for the atmos
binary itself. Declarative secrets management (<code>atmos secret keygen</code> and the age-based SOPS
backend, along with the sealed values atmos pushes to GitHub Actions secrets) relies on its own
encryption, chosen for compatibility with those specific ecosystems, and sits outside Go's FIPS
module boundary entirely — worth knowing if your compliance program needs FIPS coverage across
secrets handling too.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/fips-140-mode#how-to-use-it" class="hash-link" aria-label="Direct link to How to Use It" title="Direct link to How to Use It" translate="no">​</a></h2>
<p>Nothing to opt into — every current and future atmos release ships this way by default. To confirm
it on any binary, ask atmos itself:</p>
<div class="language-shell codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-shell codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A"><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos version </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--format</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">json</span><br></div></code></pre></div></div>
<div class="language-json codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-json codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token property" style="color:rgb(128, 203, 196)">"version"</span><span class="token operator" style="color:rgb(127, 219, 202)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"1.226.1"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token property" style="color:rgb(128, 203, 196)">"os"</span><span class="token operator" style="color:rgb(127, 219, 202)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"darwin"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token property" style="color:rgb(128, 203, 196)">"arch"</span><span class="token operator" style="color:rgb(127, 219, 202)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"arm64"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token property" style="color:rgb(128, 203, 196)">"fips"</span><span class="token operator" style="color:rgb(127, 219, 202)">:</span><span class="token plain"> </span><span class="token boolean" style="color:rgb(255, 88, 116)">true</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span></span><br></div></code></pre></div></div>
<p>If you'd rather check without atmos installed yet — say, auditing a downloaded binary — any
standard Go toolchain can tell you the same thing:</p>
<div class="language-shell codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-shell codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A"><div class="token-line" style="color:#d6deeb"><span class="token plain">go version </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-m</span><span class="token plain"> ./atmos </span><span class="token operator" style="color:rgb(127, 219, 202)">|</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">grep</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-i</span><span class="token plain"> fips</span><br></div></code></pre></div></div>
<div class="language-text codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-text codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">build   DefaultGODEBUG=fips140=on</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">build   GOFIPS140=latest</span></span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/fips-140-mode#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>Have feedback on this, or a compliance requirement it doesn't yet cover? <a href="https://github.com/cloudposse/atmos/issues" target="_blank" rel="noopener noreferrer" class="">Open an
issue</a> or join the conversation in the <a href="https://cloudposse.com/slack" target="_blank" rel="noopener noreferrer" class="">Cloud Posse
community Slack</a>.</p>]]></content>
        <author>
            <name>Erik Osterman</name>
            <uri>https://github.com/osterman</uri>
        </author>
        <category label="Security" term="Security"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Stop retyping -lock-timeout on every terraform command]]></title>
        <id>https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/terraform-lock-timeout-flags</id>
        <link href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/terraform-lock-timeout-flags"/>
        <updated>2026-08-24T12:00:00.000Z</updated>
        <summary type="html"><![CDATA[Terraform locks state before it writes to it, and by default it gives up the instant that lock]]></summary>
        <content type="html"><![CDATA[<p>Terraform locks state before it writes to it, and by default it gives up the instant that lock
is already held — no retry, no wait. That's fine for a single engineer running commands one at a
time. It falls apart the moment two pipelines, or a pipeline and an engineer, touch the same
component's state around the same moment: whichever process loses the race just fails, even
though the lock would have cleared in a few seconds.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/terraform-lock-timeout-flags#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>Terraform and OpenTofu support <code>-lock-timeout=&lt;duration&gt;</code> to poll for a held lock instead of
failing immediately, but it has to be typed on every single invocation. <code>TF_CLI_ARGS_&lt;command&gt;</code>
can automate it, but it is a single flat string rather than a structured, independently merged
<code>flags:</code> block — so a component that wants to override one flag has to restate the rest or lose
them. Teams running concurrent CI matrices, or Atmos Pro-driven deployments, would hit avoidable
failures from Terraform's <code>0s</code> default when no lock timeout is configured.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/terraform-lock-timeout-flags#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>Terraform CLI execution flags — <code>lock_timeout</code>, <code>lock</code>, <code>parallelism</code>, <code>refresh</code>, and
<code>compact_warnings</code> — can now be declared once under a <code>flags:</code> block: globally in <code>atmos.yaml</code>,
for an entire stack, or for a single component, with each layer overriding the one before it. An
<code>ATMOS_COMPONENTS_TERRAFORM_FLAGS_*</code> environment variable can override the <code>atmos.yaml</code> default
too — the same environment-variable handling every other Atmos setting already gets, not a
special case invented for these five flags. An explicit flag typed directly on the command line
still wins over every declared default, so nothing about existing one-off usage changes.</p>
<p>Atmos only injects a flag into commands that actually support it — for example <code>-refresh</code> isn't
valid when applying a saved plan, and <code>terraform import</code> doesn't accept <code>-parallelism</code> — so you
don't have to track those exceptions yourself.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/terraform-lock-timeout-flags#how-to-use-it" class="hash-link" aria-label="Direct link to How to Use It" title="Direct link to How to Use It" translate="no">​</a></h2>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># atmos.yaml — fleet-wide default</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain"></span><span class="token key atrule">components</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">terraform</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">flags</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">lock_timeout</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"5m"</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">parallelism</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">10</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain" style="display:inline-block"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># stack manifest — applies to every terraform component in this stack</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain"></span><span class="token key atrule">terraform</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">flags</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">lock_timeout</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"5m"</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain" style="display:inline-block"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain"></span><span class="token key atrule">components</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">terraform</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">vpc</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># per-component override</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">flags</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">lock_timeout</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"10m"</span></span><br></div></code></pre></div></div>
<div class="language-shell codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-shell codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A"><div class="token-line" style="color:#d6deeb"><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># one-off override still works exactly as before, and always wins</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos terraform plan vpc </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-s</span><span class="token plain"> plat-ue2-dev -- -lock-timeout</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">30s</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># environment variable overrides the atmos.yaml default — handy for a per-CI-job</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># tweak without touching the fleet-wide config</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token assign-left variable" style="color:rgb(214, 222, 235)">ATMOS_COMPONENTS_TERRAFORM_FLAGS_LOCK_TIMEOUT</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">2m atmos terraform plan vpc </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-s</span><span class="token plain"> plat-ue2-dev</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="why-not-just-use-tf_cli_args">Why not just use TF_CLI_ARGS?<a href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/terraform-lock-timeout-flags#why-not-just-use-tf_cli_args" class="hash-link" aria-label="Direct link to Why not just use TF_CLI_ARGS?" title="Direct link to Why not just use TF_CLI_ARGS?" translate="no">​</a></h2>
<p>Yes, you could. Atmos's <code>env:</code> section also merges by stack and component. Set
<code>env: { TF_CLI_ARGS_plan: "-lock-timeout=5m" }</code>, and it scopes the same way <code>flags:</code> does.</p>
<p>But <code>TF_CLI_ARGS_plan</code> is one flat string with no separate fields. If a component overrides
<code>-parallelism</code>, it must also restate <code>-lock-timeout</code>, or the component loses that value.</p>
<p>Fields in <code>flags:</code> merge one at a time. A component can override <code>parallelism</code> alone and still
inherit <code>lock_timeout</code> from the stack. Every other Atmos section merges the same way.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/terraform-lock-timeout-flags#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>See the <a class="" href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/components/terraform#flags">Terraform Configuration</a> docs for the
full field reference, defaults, and environment variable overrides. Have feedback on this
feature? <a href="https://github.com/cloudposse/atmos/issues" target="_blank" rel="noopener noreferrer" class="">Open an issue</a> or join the conversation in
the <a href="https://cloudposse.com/slack" target="_blank" rel="noopener noreferrer" class="">Cloud Posse community Slack</a>.</p>]]></content>
        <author>
            <name>Erik Osterman</name>
            <uri>https://github.com/osterman</uri>
        </author>
        <category label="Feature" term="Feature"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Gate custom command steps on their own flags and arguments]]></title>
        <id>https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/cel-when-flags-arguments</id>
        <link href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/cel-when-flags-arguments"/>
        <updated>2026-08-21T12:00:00.000Z</updated>
        <summary type="html"><![CDATA[A custom command often needs to behave differently depending on how it was called — skip the]]></summary>
        <content type="html"><![CDATA[<p>A custom command often needs to behave differently depending on how it was called — skip the
destructive step on <code>--dry-run</code>, only run a cleanup step for a particular <code>environment</code> argument,
or branch on whichever component the caller targeted. Doing that meant wrapping the command in a
shell script that inspected <code>$@</code> itself, because a step's <code>when:</code> condition had no visibility into
the command's own <code>--flag</code> or positional argument values.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/cel-when-flags-arguments#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>Custom command steps already supported <code>when:</code> conditions built on CEL — <code>ci</code>, <code>stack</code>,
<code>component</code>, and more — but a step could never see the values the user actually passed to the
command that's running it:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token key atrule">commands</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> deploy</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">flags</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> dry</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">run</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">type</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> bool</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">steps</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> </span><span class="token key atrule">type</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> shell</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">command</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> terraform apply</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># No way to reference --dry-run here.</span></span><br></div></code></pre></div></div>
<p>The flag values were already being extracted for Go/gomplate templates as <code>{{ .Flags.dry_run }}</code>,
but that data never reached the CEL evaluator, so <code>when:</code> conditions couldn't use it.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/cel-when-flags-arguments#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p><code>when:</code> expressions can now read <code>flags</code> and <code>arguments</code>, mirroring the same data already
available to steps in templates. <code>component</code> is also resolved for custom commands now, the same
way it already was for component hooks — via a semantic-typed flag or argument.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/cel-when-flags-arguments#how-to-use-it" class="hash-link" aria-label="Direct link to How to Use It" title="Direct link to How to Use It" translate="no">​</a></h2>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token key atrule">commands</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> deploy</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">flags</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> dry</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">run</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">type</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> bool</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">steps</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> </span><span class="token key atrule">type</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> shell</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">command</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> terraform apply</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">when</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token tag" style="color:rgb(127, 219, 202)">!cel</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'!flags["dry-run"]'</span></span><br></div></code></pre></div></div>
<p>See the <a class="" href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/commands/steps#conditional-steps">custom command steps</a> docs for the
full list of available <code>when:</code> facts.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/cel-when-flags-arguments#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>Have feedback on this feature? <a href="https://github.com/cloudposse/atmos/issues" target="_blank" rel="noopener noreferrer" class="">Open an issue</a> or join
the conversation in the <a href="https://cloudposse.com/slack" target="_blank" rel="noopener noreferrer" class="">Cloud Posse community Slack</a>.</p>]]></content>
        <author>
            <name>Erik Osterman</name>
            <uri>https://github.com/osterman</uri>
        </author>
        <category label="Feature" term="Feature"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Container Build Paths Depended on Where You Ran Atmos From]]></title>
        <id>https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/container-component-base-path</id>
        <link href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/container-component-base-path"/>
        <updated>2026-08-21T12:00:00.000Z</updated>
        <summary type="html"><![CDATA[A container component's build.context and dockerfile looked like ordinary relative paths, but]]></summary>
        <content type="html"><![CDATA[<p>A container component's <code>build.context</code> and <code>dockerfile</code> looked like ordinary relative paths, but
they weren't resolved against anything in particular — they resolved against whatever directory
your shell happened to be in the moment you ran <code>atmos container build</code>. Run it from the repo root
and it worked. Run it from a subdirectory, a CI job with a different working directory, or a
script that changes directories first, and the build silently picked up the wrong Dockerfile or
found nothing at all. Setting <code>components.container.base_path</code> didn't help — that option was
accepted but quietly ignored.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/container-component-base-path#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>Terraform, Helmfile, Kubernetes, and Helm components have always resolved their working directory
the same way: a configurable <code>base_path</code> per component type, joined with the component's own name,
computed once and used consistently no matter where <code>atmos</code> is invoked from. Container components
never got wired into that mechanism. <code>build.context</code> and <code>build.dockerfile</code> were passed straight
through to <code>docker build</code>/<code>podman build</code> with no anchoring at all, and <code>run.mounts[].source</code>
anchored only to the bare project root — never to the component itself.
<code>components.container.base_path</code> existed in the config schema, but nothing ever read it.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/container-component-base-path#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>Container components now resolve <code>build.context</code>, <code>build.dockerfile</code>, and <code>run.mounts[].source</code>
the same way every other component type does: relative to <code>components.container.base_path</code>
(default <code>components/container</code>) joined with the component's own name, independent of the
directory <code>atmos</code> happens to be invoked from. <code>components.container.base_path</code> is now a real,
working setting. Container components also gained the same just-in-time source provisioning as
Terraform and Helmfile components — a component that declares <code>source:</code> is now auto-vendored into
a workdir, and that workdir becomes the anchor for build and mount paths instead of the static base
path.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="breaking-change">Breaking Change<a href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/container-component-base-path#breaking-change" class="hash-link" aria-label="Direct link to Breaking Change" title="Direct link to Breaking Change" translate="no">​</a></h2>
<p>If your container component's <code>build.context</code>, <code>build.dockerfile</code>, or <code>run.mounts[].source</code> are
relative paths, they now resolve against <code>&lt;base_path&gt;/&lt;component-name&gt;/</code> instead of the previous
CWD-dependent (build) or bare-project-root (mounts) behavior. Update your setup one of two ways:
move build assets under <code>components/container/&lt;component-name&gt;/</code> to match the same convention
Terraform components already use, or point <code>components.container.base_path</code> at wherever your
container build assets currently live.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/container-component-base-path#how-to-use-it" class="hash-link" aria-label="Direct link to How to Use It" title="Direct link to How to Use It" translate="no">​</a></h2>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># atmos.yaml</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain"></span><span class="token key atrule">components</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">container</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">base_path</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> components/container   </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># default</span></span><br></div></code></pre></div></div>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token key atrule">components</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">container</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">api</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">build</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">context</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> app           </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># resolves to components/container/api/app</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">dockerfile</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> Dockerfile  </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># resolves to components/container/api/app/Dockerfile</span></span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/container-component-base-path#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>Try it out with an existing container component or a fresh one. Questions or ideas? Start a thread
in <a href="https://github.com/cloudposse/atmos/discussions" target="_blank" rel="noopener noreferrer" class="">GitHub Discussions</a>, or open an issue in the
<a href="https://github.com/cloudposse/atmos/issues" target="_blank" rel="noopener noreferrer" class="">issue tracker</a>.</p>]]></content>
        <author>
            <name>Erik Osterman</name>
            <uri>https://github.com/osterman</uri>
        </author>
        <category label="Bug Fix" term="Bug Fix"/>
        <category label="Breaking Change" term="Breaking Change"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Keep version fields in JSON files in sync without a template]]></title>
        <id>https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/version-tracker-json-manager</id>
        <link href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/version-tracker-json-manager"/>
        <updated>2026-08-20T12:00:00.000Z</updated>
        <summary type="html"><![CDATA[Plain JSON has no comment syntax, so there's nowhere to put an annotation telling a tool which]]></summary>
        <content type="html"><![CDATA[<p>Plain JSON has no comment syntax, so there's nowhere to put an annotation telling a tool which
field carries a managed version. Rewriting the whole file from a parsed structure works, but it
reflows formatting, reorders keys, and turns a one-line diff into a noisy one. Neither option was
a good fit for keeping a <code>version</code> field in a <code>package.json</code>, plugin manifest, or marketplace
listing in sync with a locked dependency.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/version-tracker-json-manager#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>The <a class="" href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/version/files">Version Tracker</a>'s <code>marker</code> manager rewrites version
tokens on lines annotated with an <code>atmos:version</code> comment — but JSON has no comment syntax, so
there's no line to annotate. The <code>template</code> manager covers formats like this by rendering a
<code>*.tmpl</code> source to a sibling output file, but that means maintaining a template and a generated
file as two files that have to be kept in sync by hand every time an unrelated field in the JSON
document changes.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/version-tracker-json-manager#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>A new <code>json</code> file manager writes locked values directly into JSON files at configured field
paths. It patches only the targeted field and leaves everything else in the document — key
order, spacing, unrelated fields — exactly as it was, so <code>atmos version track apply</code> produces a
minimal, single-field diff instead of a fully reformatted file.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/version-tracker-json-manager#how-to-use-it" class="hash-link" aria-label="Direct link to How to Use It" title="Direct link to How to Use It" translate="no">​</a></h2>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token key atrule">version</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">dependencies</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">atmos</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">ecosystem</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> github/actions</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">datasource</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> github</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">releases</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">provider</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> github</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">package</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> cloudposse/atmos</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">desired</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"~1.160"</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain" style="display:inline-block"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">files</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> </span><span class="token key atrule">manager</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> json</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">paths</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> package.json</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">options</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">set</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">          </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> </span><span class="token key atrule">path</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> version</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">            </span><span class="token key atrule">from</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> atmos</span></span><br></div></code></pre></div></div>
<p>A single rule can target more than one file, and a single file can carry more than one managed
field — each just needs its own <code>path</code>/<code>from</code> entry under <code>set</code>:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">files</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> </span><span class="token key atrule">manager</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> json</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">paths</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> package.json</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">options</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">set</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">          </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> </span><span class="token key atrule">path</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> version</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">            </span><span class="token key atrule">from</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> cli</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">          </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> </span><span class="token key atrule">path</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> engines.node</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">            </span><span class="token key atrule">from</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> node</span></span><br></div></code></pre></div></div>
<p><code>atmos version track apply</code> rewrites every configured field from the lock; <code>--check</code> fails and
lists any file that's out of date, so CI can catch drift before it merges.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/version-tracker-json-manager#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>See the <a class="" href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/version/files#updating-json-files">Version Files</a> docs for the full
<code>path</code>/<code>from</code> syntax, including array indexing and escaping keys that contain literal dots. Have
feedback on this feature? <a href="https://github.com/cloudposse/atmos/issues" target="_blank" rel="noopener noreferrer" class="">Open an issue</a> or join the
conversation in the <a href="https://cloudposse.com/slack" target="_blank" rel="noopener noreferrer" class="">Cloud Posse community Slack</a>.</p>]]></content>
        <author>
            <name>Erik Osterman</name>
            <uri>https://github.com/osterman</uri>
        </author>
        <category label="Feature" term="Feature"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Pick configuration profiles interactively with a bare --profile]]></title>
        <id>https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/interactive-profile-selection</id>
        <link href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/interactive-profile-selection"/>
        <updated>2026-08-18T12:00:00.000Z</updated>
        <summary type="html"><![CDATA[Naming things from memory is one of the more tedious parts of a CLI workflow. You know you want]]></summary>
        <content type="html"><![CDATA[<p>Naming things from memory is one of the more tedious parts of a CLI workflow. You know you want
to switch configuration contexts before running a command, but you don't always remember every
profile name your team has defined, especially on a project you don't touch daily. Until now,
<code>--profile</code> required you to type that name exactly, or go check <code>atmos profile list</code> first and
copy it over.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/interactive-profile-selection#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p><code>--profile</code> activates one or more named configuration overlays — dev settings, CI settings,
security overrides, whatever a project defines. But the flag always required an explicit value.
Typing <code>--profile</code> alone, expecting the CLI to prompt you the way <code>-i</code>/<code>--identity</code> already does
when used bare, instead produced a raw usage error:</p>
<div class="language-shell codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-shell codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A"><div class="token-line" style="color:#d6deeb"><span class="token plain">$ atmos auth login </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-i</span><span class="token plain"> core-auto/terraform </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--profile</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">Incorrect Usage</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">Error: </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--profile</span><span class="token plain"> flag needs an argument </span><span class="token keyword" style="color:rgb(127, 219, 202)">for</span><span class="token plain"> </span><span class="token builtin class-name" style="color:rgb(255, 203, 139)">command</span><span class="token plain"> atmos auth login</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/interactive-profile-selection#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p><code>--profile</code> with no value now opens an interactive multi-select listing every profile Atmos
discovers across your configured profile locations. Nothing is checked by default — toggle the
ones you want with space, confirm, and they activate left-to-right in the order shown, exactly as
if you'd typed them explicitly.</p>
<p>Any profile name you already typed alongside the bare flag starts pre-checked, so
<code>--profile ci --profile</code> opens with <code>ci</code> already selected, ready to confirm or adjust. In a
non-interactive context — CI, scripts, no TTY — bare <code>--profile</code> returns a clear error instead of
hanging or guessing, so automation fails fast rather than silently.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/interactive-profile-selection#how-to-use-it" class="hash-link" aria-label="Direct link to How to Use It" title="Direct link to How to Use It" translate="no">​</a></h2>
<div class="language-shell codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-shell codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A"><div class="token-line" style="color:#d6deeb"><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Interactively choose which profiles to activate</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos auth login </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-i</span><span class="token plain"> core-auto/terraform </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--profile</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Explicit values still work exactly as before</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--profile</span><span class="token plain"> developer terraform plan vpc </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-s</span><span class="token plain"> prod</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--profile</span><span class="token plain"> ci,security terraform plan vpc </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-s</span><span class="token plain"> prod</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/interactive-profile-selection#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>See the <a class="" href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/profiles#interactive-selection">Profiles</a> docs for the full behavior,
including profile discovery order and merge precedence. Have feedback on this feature? <a href="https://github.com/cloudposse/atmos/issues" target="_blank" rel="noopener noreferrer" class="">Open an
issue</a> or join the conversation in the <a href="https://cloudposse.com/slack" target="_blank" rel="noopener noreferrer" class="">Cloud Posse
community Slack</a>.</p>]]></content>
        <author>
            <name>Erik Osterman</name>
            <uri>https://github.com/osterman</uri>
        </author>
        <category label="Feature" term="Feature"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[A Typo in a Container Step's `with:` Block Used to Just... Do Nothing]]></title>
        <id>https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/container-config-validation-and-workdir-path-encoding</id>
        <link href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/container-config-validation-and-workdir-path-encoding"/>
        <updated>2026-08-17T12:00:00.000Z</updated>
        <summary type="html"><![CDATA[You add platforms: [linux/amd64] to a container build step, run it, and nothing happens]]></summary>
        <content type="html"><![CDATA[<p>You add <code>platforms: [linux/amd64]</code> to a container build step, run it, and nothing happens
differently. No error, no warning — the field is just gone, like it was never written. You spend
ten minutes checking your YAML indentation before realizing the field name was never real to
begin with.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/container-config-validation-and-workdir-path-encoding#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p><code>type: container</code> steps take their configuration under <code>with:</code> (and, for the driver, a nested
<code>driver:</code> block) as a typed mapping — <code>run</code>, <code>build</code>, <code>push</code>, and <code>inspect</code> actions each have a
fixed set of real fields. But nothing checked that the keys you wrote were actually among them.
A typo'd field name, a field copied from Docker Compose that doesn't exist in Atmos, or a
straight-up nonexistent option all decoded the same way: silently discarded, with the rest of the
mapping loaded normally. The step would run — just without the setting you thought you'd
configured.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/container-config-validation-and-workdir-path-encoding#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p><code>with:</code> and <code>driver:</code> blocks on container steps now reject unknown fields outright, in both
standalone workflow files and custom commands. A typo like <code>platforms:</code> (not a real field) now
fails the step with a clear decode error naming the field, instead of quietly doing nothing.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="breaking-change">Breaking Change<a href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/container-config-validation-and-workdir-path-encoding#breaking-change" class="hash-link" aria-label="Direct link to Breaking Change" title="Direct link to Breaking Change" translate="no">​</a></h2>
<p>If a <code>with:</code> or <code>driver:</code> block on a <code>type: container</code> step currently has a field that isn't one
of the real, documented fields, it will now fail to load instead of being silently ignored.
Check your container steps for typos or leftover fields from a different tool's config format
before upgrading.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="also-in-this-release-local-backend-state-was-being-deleted-on-re-provision">Also in This Release: Local Backend State Was Being Deleted on Re-Provision<a href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/container-config-validation-and-workdir-path-encoding#also-in-this-release-local-backend-state-was-being-deleted-on-re-provision" class="hash-link" aria-label="Direct link to Also in This Release: Local Backend State Was Being Deleted on Re-Provision" title="Direct link to Also in This Release: Local Backend State Was Being Deleted on Re-Provision" translate="no">​</a></h2>
<p>If you used a <code>local</code> Terraform backend on a component with just-in-time (JIT) workdir
provisioning enabled, your state was gone after the second run. Not corrupted — deleted, cleanly,
with no error. <code>apply</code> would create it, and the very next <code>plan</code> would silently start over with
an empty state, because the workdir provisioner's incremental sync treated the state file the
same way it treats any file that isn't part of your component's source: not present in source,
so remove it. <code>terraform.tfstate</code> was never protected from that cleanup the way provider lock
files already were.</p>
<p>The workdir provisioner now leaves <code>terraform.tfstate</code>, <code>terraform.tfstate.backup</code>, and the
transient <code>.terraform.tfstate.lock.info</code> marker alone, in both directions — never copied in from
source, never deleted from the workdir. If you were working around this by avoiding JIT workdir
provisioning for local-backend components, that workaround is no longer necessary.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="also-in-this-release-workdir-path-encoding">Also in This Release: Workdir Path Encoding<a href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/container-config-validation-and-workdir-path-encoding#also-in-this-release-workdir-path-encoding" class="hash-link" aria-label="Direct link to Also in This Release: Workdir Path Encoding" title="Direct link to Also in This Release: Workdir Path Encoding" translate="no">​</a></h2>
<p>Separately, the internal <code>.workdir/</code> directory Atmos uses for JIT component provisioning now
encodes component and stack names more carefully, to guarantee two differently named components
(e.g. one named <code>app/local</code> and another named <code>app-local</code>) can never accidentally resolve to the
same on-disk directory and share files or state.</p>
<p>This changes the on-disk directory name for any component whose name contains a literal <code>-</code>,
<code>/</code>, or <code>\</code>. Atmos migrates a workdir it finds at the old location automatically the next time
that component is provisioned, so this should be transparent for most setups.</p>]]></content>
        <author>
            <name>Erik Osterman</name>
            <uri>https://github.com/osterman</uri>
        </author>
        <category label="Bug Fix" term="Bug Fix"/>
        <category label="Breaking Change" term="Breaking Change"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[GKE Kubeconfig Authentication: Native kubectl and Helm Access Without gcloud]]></title>
        <id>https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/gke-kubeconfig-authentication</id>
        <link href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/gke-kubeconfig-authentication"/>
        <updated>2026-08-14T12:00:00.000Z</updated>
        <summary type="html"><![CDATA[Using an Atmos-managed GCP identity with GKE used to stop one step short of the cluster. The]]></summary>
        <content type="html"><![CDATA[<p>Using an Atmos-managed GCP identity with GKE used to stop one step short of the cluster. The
identity could authenticate Terraform and other GCP clients, but operators still needed <code>gcloud</code>
or <code>gke-gcloud-auth-plugin</code> to discover the cluster, write kubeconfig, and refresh Kubernetes
credentials. Atmos now handles that complete path itself.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/gke-kubeconfig-authentication#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>Atmos Auth already supports Application Default Credentials, Workload Identity Federation, and
service account impersonation. GKE access still required a separate authentication flow outside
Atmos, though. That created two sources of truth for identity selection and added external tools
to local and CI environments solely to prepare kubeconfig.</p>
<p>The gap was especially visible with native Helm components: Atmos could resolve the intended GCP
identity, but an ambient kubeconfig could still point Helm at a different cluster.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/gke-kubeconfig-authentication#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>The new <code>gcp/gke</code> Auth integration links a GKE cluster to an existing GCP identity. When Atmos
selects that identity, it uses the GKE API to discover the cluster endpoint and CA certificate,
writes an Atmos-managed kubeconfig, and injects its path into child commands:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token key atrule">auth</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">providers</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">example-gcp</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">kind</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> gcp/adc</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">spec</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">project_id</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> example</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">project</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain" style="display:inline-block"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">identities</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">example-deployer</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">kind</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> gcp/project</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">via</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">provider</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> example</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">gcp</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">principal</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">project_id</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> example</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">project</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain" style="display:inline-block"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">integrations</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">example-gke</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">kind</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> gcp/gke</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">via</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">identity</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> example</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">deployer</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">spec</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">cluster</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">          </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> example</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">cluster</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">          </span><span class="token key atrule">project_id</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> example</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">project</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">          </span><span class="token key atrule">location</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> us</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">central1</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">          </span><span class="token key atrule">alias</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> example</span></span><br></div></code></pre></div></div>
<p>Run Kubernetes tools through the selected identity without a preparatory <code>gcloud</code> command:</p>
<div class="language-shell codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-shell codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A"><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos auth </span><span class="token builtin class-name" style="color:rgb(255, 203, 139)">exec</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--identity</span><span class="token plain"> example-deployer -- kubectl get nodes</span><br></div></code></pre></div></div>
<p>The generated kubeconfig uses <code>atmos gcp gke token</code> as a Kubernetes exec credential plugin.
Kubernetes requests a fresh short-lived token when needed; the token and its expiration are
returned as <code>ExecCredential</code> JSON and are never stored in kubeconfig.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="guard-native-helm-targets">Guard Native Helm Targets<a href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/gke-kubeconfig-authentication#guard-native-helm-targets" class="hash-link" aria-label="Direct link to Guard Native Helm Targets" title="Direct link to Guard Native Helm Targets" translate="no">​</a></h2>
<p>Native Helm keeps its existing ambient-kubeconfig behavior by default. Components that must use
an Atmos-provisioned GKE identity can opt into a fail-closed endpoint check:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token key atrule">components</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">helm</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">example-release</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">auth</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">require_identity</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token boolean important" style="color:rgb(255, 88, 116)">true</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">identities</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">          </span><span class="token key atrule">example-deployer</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">            </span><span class="token key atrule">default</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token boolean important" style="color:rgb(255, 88, 116)">true</span></span><br></div></code></pre></div></div>
<p>For live plan, apply, and delete operations, Atmos provisions the linked integration and verifies
that Helm's effective Kubernetes API endpoint matches the endpoint returned by GKE before any
cluster request. Offline template and manifest-baseline operations remain credential-free.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="security-boundaries">Security Boundaries<a href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/gke-kubeconfig-authentication#security-boundaries" class="hash-link" aria-label="Direct link to Security Boundaries" title="Direct link to Security Boundaries" translate="no">​</a></h2>
<ul>
<li class="">The kubeconfig stores the HTTPS endpoint, CA certificate, context, and exec-plugin command—not
a bearer token.</li>
<li class="">The GCP identity needs permission to describe the cluster, normally <code>container.clusters.get</code>.</li>
<li class="">Kubernetes RBAC remains separate and determines what the authenticated principal may do inside
the cluster.</li>
<li class="">Explicit plaintext GKE API endpoints are rejected rather than written to kubeconfig.</li>
</ul>
<p>See the <a class="" href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/gcp/gke">GKE kubeconfig authentication command documentation</a> for
configuration, update modes, permissions, and troubleshooting details.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/gke-kubeconfig-authentication#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>Try the integration with your GCP identity chain and GKE clusters. Share feedback in the
<a href="https://cloudposse.com/slack" target="_blank" rel="noopener noreferrer" class="">Cloud Posse community</a> or open an issue on
<a href="https://github.com/cloudposse/atmos/issues" target="_blank" rel="noopener noreferrer" class="">GitHub</a>.</p>]]></content>
        <author>
            <name>Mikhail Shirkov</name>
            <uri>https://github.com/shirkevich</uri>
        </author>
        <category label="Feature" term="Feature"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Generate one file per selection with matrix]]></title>
        <id>https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/scaffold-matrix</id>
        <link href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/scaffold-matrix"/>
        <updated>2026-08-14T12:00:00.000Z</updated>
        <summary type="html"><![CDATA[Every file a scaffold template declares renders at most once. when: can skip a file, but it]]></summary>
        <content type="html"><![CDATA[<p>Every file a scaffold template declares renders at most once. <code>when:</code> can skip a file, but it
can never multiply one. You could work around that by authoring every combination up front and
letting <code>when:</code> prune down to what applies — but that only works if every combination is
knowable in advance. It breaks down for environments picked interactively from a longer list, or
names typed in by hand that no template author could have enumerated ahead of time. Until now,
that meant hand-rolling files outside the template, or maintaining a pile of near-duplicate ones
inside it.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/scaffold-matrix#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>The number of files a project needs often depends on what gets selected when the project is
generated. Pick three environments out of five, and you want three stack files, not five. That
output was already possible: declare all five stack files in the template up front, and gate each
one with its own <code>when:</code> on whether that specific environment got picked. The real cost was
authorship — five nearly-identical files, one per environment the template author had to
anticipate, kept in sync by hand as the shared parts drifted. Nothing let a template say "generate
one of these per selected value" from a single file; only "generate this specific file" or "skip
this specific file."</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/scaffold-matrix#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>Declaring <code>matrix:</code> on a file entry expands it into one generated file per combination of one or
more axes. It reuses the same shape Atmos workflow <code>matrix:</code> steps already use, so the syntax
should feel familiar. <code>when:</code> still prunes combinations that don't apply — the same conditional
engine that already gates whole files, now scoped to a single combination at a time:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token key atrule">spec</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">fields</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> environments</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">type</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> multiselect</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">options</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token plain">dev</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> staging</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> production</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">files</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> </span><span class="token key atrule">path</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> stacks/deploy/environment.yaml</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">target</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"stacks/deploy/{{ .matrix.environment }}.yaml"</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">matrix</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">environment</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> answers.environments</span></span><br></div></code></pre></div></div>
<p>Selecting <code>dev</code> and <code>staging</code> generates exactly <code>stacks/deploy/dev.yaml</code> and
<code>stacks/deploy/staging.yaml</code>. Declaring more than one axis expands their full combination, and
each resolved combination is available as <code>.matrix.&lt;axis&gt;</code> in Go-template fields such as the
output path and generated content, and as <code>matrix.&lt;axis&gt;</code> in <code>when:</code> conditions — so a file can
name itself and branch on its own combination.</p>
<h3 class="anchor anchorTargetStickyNavbar_cA1_" id="computed-axes">Computed axes<a href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/scaffold-matrix#computed-axes" class="hash-link" aria-label="Direct link to Computed axes" title="Direct link to Computed axes" translate="no">​</a></h3>
<p>Real answers aren't always a flat, pre-selected list. Say <code>environments</code> were a structured answer
instead of a <code>multiselect</code> — supplied through <code>--set</code> or a preset value — shaped like this:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token key atrule">environments</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">dev</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">regions</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">us-east-1</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">production</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">regions</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">us-east-1</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">us-west-2</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span></span><br></div></code></pre></div></div>
<p>The full list of regions actually used isn't something anyone picked directly — it has to be
derived from every environment's own <code>regions</code>. The <code>collectKeys</code> function does that: called with
one argument, it returns a map's keys; called with a second argument, it collects that key from
every value in the map, flattening and deduplicating across all of them.</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token key atrule">files</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> </span><span class="token key atrule">path</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> deploy.yaml</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">target</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"deploy/{{ .matrix.environment }}/{{ .matrix.region }}.yaml"</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">matrix</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">environment</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'{{ collectKeys answers.environments }}'</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">region</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'{{ collectKeys answers.environments "regions" }}'</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">when</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"matrix.region in answers.environments[matrix.environment].regions"</span></span><br></div></code></pre></div></div>
<p><code>environment</code> resolves to <code>dev</code> and <code>production</code>; <code>region</code> resolves to every region used by any of
them (<code>us-east-1</code> and <code>us-west-2</code>). Their combination fans a single <code>deploy.yaml</code> out into
<code>deploy/dev/us-east-1.yaml</code>, <code>deploy/production/us-east-1.yaml</code>, and
<code>deploy/production/us-west-2.yaml</code> — <code>target:</code> names each one from <code>.matrix.&lt;axis&gt;</code>, and <code>when:</code>
prunes the combination down to each environment's actual regions, so <code>dev</code> never gets a
<code>us-west-2</code> file.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/scaffold-matrix#how-to-use-it" class="hash-link" aria-label="Direct link to How to Use It" title="Direct link to How to Use It" translate="no">​</a></h2>
<div class="window_X9dN"><div class="titlebar_DN7h"><span class="dots_R2sg" aria-hidden="true"><i></i><i></i><i></i></span><span class="title_Dael">atmos scaffold: one file per selection via matrix</span></div><pre class="screen__b5c noPreWrap_ImkX screenLoading_abuO"><span> </span></pre><div class="controls_eyLV"><button type="button" class="playButton_kD9r" aria-label="Pause cast"><svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 24 24" aria-hidden="true" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M6 5H8V19H6V5ZM16 5H18V19H16V5Z"></path></svg></button><input aria-label="Cast position" type="range" min="0" max="0" step="0.01" value="0"><span>00:00.0<!-- --> / <!-- -->00:00.0</span></div></div>
<p>The <a class="" href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/examples/scaffolding-matrix">scaffolding-matrix example</a> is a minimal, runnable template —
one <code>multiselect</code> field driving one matrix axis:</p>
<div class="language-shell codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-shell codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A"><div class="token-line" style="color:#d6deeb"><span class="token builtin class-name" style="color:rgb(255, 203, 139)">cd</span><span class="token plain"> examples/scaffolding-matrix</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos scaffold generate example ./my-project</span><br></div></code></pre></div></div>
<p>Answering the <code>environments</code> prompt with <code>dev</code> and <code>staging</code> generates <code>stacks/dev.yaml</code> and
<code>stacks/staging.yaml</code> from the template's single <code>environment.yaml</code> file — or skip the prompt
entirely with <code>--set environments=dev,staging</code> for scripted, non-interactive use. Add <code>matrix:</code> to
any <code>spec.files[]</code> entry alongside <code>target:</code> to do the same in your own templates, using a literal
list, a <code>multiselect</code> answer, or a computed expression for each axis.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/scaffold-matrix#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>See the <a class="" href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/scaffold/generate"><code>atmos scaffold generate</code></a> docs for the full reference,
or <a href="https://github.com/cloudposse/atmos/issues" target="_blank" rel="noopener noreferrer" class="">open an issue</a> with feedback.</p>]]></content>
        <author>
            <name>Jorrit Elfferich</name>
            <uri>https://github.com/jorrite</uri>
        </author>
        <category label="Feature" term="Feature"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Containers, Emulators, and Run Steps Now Resolve Each Other by Name]]></title>
        <id>https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/container-shared-networking</id>
        <link href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/container-shared-networking"/>
        <updated>2026-08-14T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Bring up two containers in the same environment and the first thing you hit is that they can't]]></summary>
        <content type="html"><![CDATA[<p>Bring up two containers in the same environment and the first thing you hit is that they can't
find each other. Docker's default bridge network hands out a private IP to each container but
gives you no way to resolve a sibling by name, so you either hardcode IPs that change on every
restart, or reach for <code>docker network create</code> and wire up the aliases yourself. Docker Compose
solved this years ago by giving every project its own network and naming each service after
itself. Atmos containers had no equivalent — every one landed on the default bridge, reachable
only through published host ports.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/container-shared-networking#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>A container component's <code>run</code> config could publish ports to the host, but two container
components in the same stack — or a container and a <a class="" href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/stacks/components/emulator">local emulator</a>
— had no way to talk to each other directly. A workflow step that spun up a one-shot container to
run tests against those services hit the same wall. The only fix was manual: create a network by
hand, or fall back to routing everything through the host.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/container-shared-networking#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>Every container component, one-shot container run, and stack-scoped workflow <code>type: container</code>
step now automatically joins a shared network for its stack and gets a predictable DNS alias — no
configuration required. It's the same idea as the network Docker Compose creates for a project,
scoped to your Atmos stack instead.</p>
<ul>
<li class="">A component named <code>api</code> in stack <code>dev</code> is reachable at <code>dev-api</code>.</li>
<li class="">An emulator and a container component in the same stack land on the same network, so either can
resolve the other by name.</li>
<li class="">A workflow <code>run</code> step that resolves a stack (its own <code>stack:</code> field, or the workflow's
<code>--stack</code>/<code>ATMOS_STACK</code>) joins that same network too, so a test-runner step can hit
<code>http://dev-api:80</code> directly.</li>
</ul>
<p>It's best-effort: if the container runtime can't create or join a network, everything still runs —
you just lose the ability to resolve peers by name, and host-published ports keep working exactly
as before.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/container-shared-networking#how-to-use-it" class="hash-link" aria-label="Direct link to How to Use It" title="Direct link to How to Use It" translate="no">​</a></h2>
<p>Nothing to turn on. Bring up two services in the same stack and reference one from the other by its
<code>&lt;stack&gt;-&lt;component&gt;</code> alias:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token key atrule">components</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">container</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">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">image</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> localhost</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain">5001/api</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain">latest</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">run</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">ports</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">          </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> </span><span class="token key atrule">host</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">8080</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">            </span><span class="token key atrule">container</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">80</span><span class="token plain"></span></span><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">worker</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">image</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> localhost</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain">5001/worker</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain">latest</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">run</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">command</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> ./worker </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">api</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">url=http</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">api</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token number" style="color:rgb(247, 140, 108)">80</span></span><br></div></code></pre></div></div>
<div class="language-bash codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-bash codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A"><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos container up api </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-s</span><span class="token plain"> dev</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos container up worker </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"># worker resolves dev-api on the shared network — no host port juggling needed.</span><br></div></code></pre></div></div>
<p>The same alias works from a workflow <code>run</code> step scoped to the same stack:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token key atrule">steps</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> smoke</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">type</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> container</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">action</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> run</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">stack</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> dev</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">with</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">image</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> curlimages/curl</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">command</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> curl </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">f http</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">api</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain">80/health</span></span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/container-shared-networking#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>Try it out with a couple of container components or an emulator in the same stack. Questions or
ideas? Start a thread in <a href="https://github.com/cloudposse/atmos/discussions" target="_blank" rel="noopener noreferrer" class="">GitHub Discussions</a>, or
open an issue in the <a href="https://github.com/cloudposse/atmos/issues" target="_blank" rel="noopener noreferrer" class="">issue tracker</a>.</p>]]></content>
        <author>
            <name>Erik Osterman</name>
            <uri>https://github.com/osterman</uri>
        </author>
        <category label="Feature" term="Feature"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Remote Imports: Automatic GitHub Auth, Failure Warnings, and Caching]]></title>
        <id>https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/remote-import-github-auth-and-caching</id>
        <link href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/remote-import-github-auth-and-caching"/>
        <updated>2026-08-11T12:00:00.000Z</updated>
        <summary type="html"><![CDATA[Centralizing shared configuration in one private Git repository, and reusing it across projects, is not a]]></summary>
        <content type="html"><![CDATA[<p>Centralizing shared configuration in one private Git repository, and reusing it across projects, is not a
new idea. Mergify and Dependabot both support extending a project's configuration from a shared repository.
Doing the same for a general-purpose tool usually means a git submodule or subtree, and both are
cumbersome. Atmos supports this natively: a project's <code>atmos.yaml</code> or stack manifest adds a remote import,
a <code>git::</code> URL that points at the centralized repository, with no submodule or subtree involved.</p>
<p>Resolving that import still had rough edges. Git fetch authentication was separate from a developer's
GitHub CLI session, so <code>gh auth login</code> alone was not enough for a private import. A broken import failed
silently: a tag name with a typo, an unreachable host, or a token without read access all added nothing to
the configuration, with no warning. And a <code>git::</code> import with a subdirectory re-cloned on every single
command, even when nothing had changed.</p>
<p>Atmos already reused a developer's GitHub CLI session for other GitHub operations, such as toolchain
installs. Atmos now reuses that same session for private <code>git::</code> imports too. This applies to both stack
configuration imports and <code>atmos.yaml</code> configuration imports. Atmos also warns you when an import fails.
Atmos also lets you cache imports to avoid unnecessary re-fetching.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/remote-import-github-auth-and-caching#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<ul>
<li class=""><strong>Git fetch authentication was separate from GitHub CLI authentication.</strong> A private <code>git::</code> import used
its own credential chain. This chain did not include the GitHub CLI. A developer who ran only
<code>gh auth login</code> still needed a separate token for private imports to work.</li>
<li class=""><strong>A broken import failed with no warning.</strong> A typo in a <code>?ref=</code> value, an unreachable host, or an
unreadable private repository all produced the same result. The import added nothing to the
configuration. No error appeared. The command exited successfully.</li>
<li class=""><strong>Every command re-cloned a <code>git::</code> import.</strong> A root <code>atmos.yaml</code> import that pointed at a subdirectory
in a Git repository had no cache. A command as simple as checking the current identity re-cloned the
remote repository first.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/remote-import-github-auth-and-caching#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<ul>
<li class="">Private <code>git::</code> imports now fall back to a developer's GitHub CLI session automatically. This covers
config imports, vendoring, and private Terraform module fetches. Atmos already used this fallback for
other GitHub operations. If <code>gh auth login</code> is already done, no other setup is needed.</li>
<li class="">A remote <code>import:</code> entry that fails to resolve now prints a warning by default. The warning names the
import path and the underlying error. The command no longer continues silently with an empty or partial
configuration.</li>
<li class="">Set <code>imports: { ttl: ... }</code> once in <code>atmos.yaml</code> to apply the same expiry policy to every remote import
form. A <code>git::</code> import with a subdirectory then reuses its clone across commands instead of re-cloning
every time. A plain remote URL, or a <code>git::</code> import without a subdirectory, then expires after <code>ttl</code>
instead of being cached forever. The two forms track freshness differently under the hood (a marker
file in the cloned directory for the first, a cache entry for the second), but <code>ttl</code> now governs both.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/remote-import-github-auth-and-caching#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>Sign in once. Private imports then work automatically:</p>
<div class="language-bash codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-bash codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A"><div class="token-line" style="color:#d6deeb"><span class="token plain">gh auth login</span><br></div></code></pre></div></div>
<p>If an import breaks, Atmos reports it immediately:</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">WARN  failed to resolve import path="git::https://github.com/acme/config.git//auth.yaml?ref=v1.2.3" error="..."</span><br></div></code></pre></div></div>
<p>Set a cache TTL to stop re-fetching a stable, pinned <code>git::</code> import on every command:</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">imports</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">ttl</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> 5m</span></span><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">import</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"git::https://github.com/acme/config.git//auth.yaml?ref=v1.2.3"</span></span><br></div></code></pre></div></div>
<p>Leave <code>ttl</code> unset to keep each import form's default: a <code>git::</code> subdirectory import refreshes on every
command, and a plain remote URL is cached forever. Set <code>ttl</code> once to apply the same expiry to every
remote import in the file, of either form.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/remote-import-github-auth-and-caching#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>Did you find another case where a remote import fails silently? Did you find an operation where GitHub
CLI auth does not reach, but should? Open an issue. Include the command and the result you saw.</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[Keep your formatting through atmos scaffold --update]]></title>
        <id>https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/scaffold-merge-driver</id>
        <link href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/scaffold-merge-driver"/>
        <updated>2026-08-11T12:00:00.000Z</updated>
        <summary type="html"><![CDATA[Atmos scaffolds can perform genuinely complex three-way merges of YAML templates: keys can merge]]></summary>
        <content type="html"><![CDATA[<p>Atmos scaffolds can perform genuinely complex three-way merges of YAML templates: keys can merge
intelligently, and comments and local customizations are preserved when changes don't conflict.
That capability comes from parsing YAML into a structured document and re-serializing it—and
structured serialization is lossy by nature. Formatting that isn't part of the data model, like
blank lines separating sections, doesn't survive the round trip. If your team treats that
whitespace as a convention rather than noise, <code>atmos scaffold generate --update</code> (and <code>atmos init --update</code>) used to flatten it every time, whether or not the file had actually changed.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/scaffold-merge-driver#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p><code>--update</code> re-runs a template against an existing project and 3-way merges the result. Scaffold
picks its merge algorithm by file extension: YAML-aware for <code>.yaml</code>/<code>.yml</code>, line-oriented text for
everything else. The YAML-aware path is what makes the complex merges possible in the first
place—but re-encoding the whole document through a YAML parser and serializer means anything the
parser doesn't model, blank lines between top-level blocks being the common case, gets dropped
unconditionally. That's a real cost for files where formatting <em>is</em> a convention—many CI pipeline
definitions use blank lines to visually separate jobs, stages, and other top-level blocks.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/scaffold-merge-driver#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p><code>--merge-driver</code> lets you override which merge algorithm runs, named after git's own merge driver
concept:</p>
<ul>
<li class=""><strong><code>auto</code></strong> (default, unchanged) — YAML-aware for <code>.yaml</code>/<code>.yml</code>, text otherwise.</li>
<li class=""><strong><code>text</code></strong> — forces every file, YAML included, through a line-oriented, diff3-style merge.
Comments, blank lines, and other structural formatting the YAML-aware merger doesn't model
are preserved in non-conflicting regions.</li>
</ul>
<p>Because it's a flag on the <code>--update</code> invocation itself, not a project-wide setting, you're not
choosing one mode for the project's entire lifetime. Most updates can stay on the default <code>auto</code>
merge, and you reach for <code>--merge-driver=text</code> on the specific update that needs it—bundle up a
template's formatting-sensitive changes (a CI pipeline overhaul, say) and pull them in with one
deliberate <code>--merge-driver=text</code> run, rather than running every future update through the coarser
text merger just to protect that one file.</p>
<p>This is a different axis from <code>--merge-strategy</code>, which decides how a genuine conflict resolves
(manual, ours, or theirs) once a merge algorithm has already run. <code>--merge-driver</code> decides which
algorithm runs in the first place.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/scaffold-merge-driver#how-to-use-it" class="hash-link" aria-label="Direct link to How to Use It" title="Direct link to How to Use It" translate="no">​</a></h2>
<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"># Everyday updates: the default auto merge is usually what you want.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos scaffold generate my-template ./my-project </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--update</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"># This update brings in a batch of formatting-sensitive template changes—</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"># override the driver just for this run.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos scaffold generate my-template ./my-project </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--update</span><span class="token plain"> --merge-driver</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">text</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos init </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--update</span><span class="token plain"> --merge-driver</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">text</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/scaffold-merge-driver#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-3036.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/scaffold/generate"><code>atmos scaffold generate</code></a> and
<a class="" href="https://pr-3036.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/init"><code>atmos init</code></a> docs for the full flag reference. 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>Jorrit Elfferich</name>
            <uri>https://github.com/jorrite</uri>
        </author>
        <category label="Feature" term="Feature"/>
    </entry>
</feed>