<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>atmos Blog</title>
        <link>https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog</link>
        <description>atmos Blog</description>
        <lastBuildDate>Mon, 24 Aug 2026 12:00:00 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <item>
            <title><![CDATA[Atmos binaries now build with Go's FIPS 140-3 crypto module by default]]></title>
            <link>https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/fips-140-mode</link>
            <guid>https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/fips-140-mode</guid>
            <pubDate>Mon, 24 Aug 2026 12:00:00 GMT</pubDate>
            <description><![CDATA[Federal agencies, financial institutions, and healthcare organizations are often required to run]]></description>
            <content:encoded><![CDATA[<p>Federal agencies, financial institutions, and healthcare organizations are often required to run
only cryptography that's been validated against FIPS 140, the U.S. government's standard for
approved algorithms and key sizes. For a command-line tool built on a general-purpose language
runtime, meeting that bar has traditionally meant compiling against a separate validated crypto
library, or simply hoping the runtime's own TLS and encryption code happens to stick to approved
algorithms.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-2957.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-2957.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-2957.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-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/fips-140-mode#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>Have feedback on this, or a compliance requirement it doesn't yet cover? <a href="https://github.com/cloudposse/atmos/issues" target="_blank" rel="noopener noreferrer" class="">Open an
issue</a> or join the conversation in the <a href="https://cloudposse.com/slack" target="_blank" rel="noopener noreferrer" class="">Cloud Posse
community Slack</a>.</p>]]></content:encoded>
            <category>Security</category>
        </item>
        <item>
            <title><![CDATA[Container Build Paths Depended on Where You Ran Atmos From]]></title>
            <link>https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/container-component-base-path</link>
            <guid>https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/container-component-base-path</guid>
            <pubDate>Fri, 21 Aug 2026 12:00:00 GMT</pubDate>
            <description><![CDATA[A container component's build.context and dockerfile looked like ordinary relative paths, but]]></description>
            <content:encoded><![CDATA[<p>A container component's <code>build.context</code> and <code>dockerfile</code> looked like ordinary relative paths, but
they weren't resolved against anything in particular — they resolved against whatever directory
your shell happened to be in the moment you ran <code>atmos container build</code>. Run it from the repo root
and it worked. Run it from a subdirectory, a CI job with a different working directory, or a
script that changes directories first, and the build silently picked up the wrong Dockerfile or
found nothing at all. Setting <code>components.container.base_path</code> didn't help — that option was
accepted but quietly ignored.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-2957.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-2957.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-2957.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-2957.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-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/container-component-base-path#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>Try it out with an existing container component or a fresh one. Questions or ideas? Start a thread
in <a href="https://github.com/cloudposse/atmos/discussions" target="_blank" rel="noopener noreferrer" class="">GitHub Discussions</a>, or open an issue in the
<a href="https://github.com/cloudposse/atmos/issues" target="_blank" rel="noopener noreferrer" class="">issue tracker</a>.</p>]]></content:encoded>
            <category>Bug Fix</category>
            <category>Breaking Change</category>
        </item>
        <item>
            <title><![CDATA[Keep version fields in JSON files in sync without a template]]></title>
            <link>https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/version-tracker-json-manager</link>
            <guid>https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/version-tracker-json-manager</guid>
            <pubDate>Thu, 20 Aug 2026 12:00:00 GMT</pubDate>
            <description><![CDATA[Plain JSON has no comment syntax, so there's nowhere to put an annotation telling a tool which]]></description>
            <content:encoded><![CDATA[<p>Plain JSON has no comment syntax, so there's nowhere to put an annotation telling a tool which
field carries a managed version. Rewriting the whole file from a parsed structure works, but it
reflows formatting, reorders keys, and turns a one-line diff into a noisy one. Neither option was
a good fit for keeping a <code>version</code> field in a <code>package.json</code>, plugin manifest, or marketplace
listing in sync with a locked dependency.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-2957.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-2957.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-2957.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-2957.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-2957.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-2957.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/version/files#updating-json-files">Version Files</a> docs for the full
<code>path</code>/<code>from</code> syntax, including array indexing and escaping keys that contain literal dots. Have
feedback on this feature? <a href="https://github.com/cloudposse/atmos/issues" target="_blank" rel="noopener noreferrer" class="">Open an issue</a> or join the
conversation in the <a href="https://cloudposse.com/slack" target="_blank" rel="noopener noreferrer" class="">Cloud Posse community Slack</a>.</p>]]></content:encoded>
            <category>Feature</category>
        </item>
        <item>
            <title><![CDATA[Pick configuration profiles interactively with a bare --profile]]></title>
            <link>https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/interactive-profile-selection</link>
            <guid>https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/interactive-profile-selection</guid>
            <pubDate>Tue, 18 Aug 2026 12:00:00 GMT</pubDate>
            <description><![CDATA[Naming things from memory is one of the more tedious parts of a CLI workflow. You know you want]]></description>
            <content:encoded><![CDATA[<p>Naming things from memory is one of the more tedious parts of a CLI workflow. You know you want
to switch configuration contexts before running a command, but you don't always remember every
profile name your team has defined, especially on a project you don't touch daily. Until now,
<code>--profile</code> required you to type that name exactly, or go check <code>atmos profile list</code> first and
copy it over.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-2957.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-2957.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-2957.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-2957.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-2957.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/profiles#interactive-selection">Profiles</a> docs for the full behavior,
including profile discovery order and merge precedence. Have feedback on this feature? <a href="https://github.com/cloudposse/atmos/issues" target="_blank" rel="noopener noreferrer" class="">Open an
issue</a> or join the conversation in the <a href="https://cloudposse.com/slack" target="_blank" rel="noopener noreferrer" class="">Cloud Posse
community Slack</a>.</p>]]></content:encoded>
            <category>Feature</category>
        </item>
        <item>
            <title><![CDATA[A Typo in a Container Step's `with:` Block Used to Just... Do Nothing]]></title>
            <link>https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/container-config-validation-and-workdir-path-encoding</link>
            <guid>https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/container-config-validation-and-workdir-path-encoding</guid>
            <pubDate>Mon, 17 Aug 2026 12:00:00 GMT</pubDate>
            <description><![CDATA[You add platforms: [linux/amd64] to a container build step, run it, and nothing happens]]></description>
            <content:encoded><![CDATA[<p>You add <code>platforms: [linux/amd64]</code> to a container build step, run it, and nothing happens
differently. No error, no warning — the field is just gone, like it was never written. You spend
ten minutes checking your YAML indentation before realizing the field name was never real to
begin with.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-2957.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-2957.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-2957.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-2957.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-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/container-config-validation-and-workdir-path-encoding#also-in-this-release-workdir-path-encoding" class="hash-link" aria-label="Direct link to Also in This Release: Workdir Path Encoding" title="Direct link to Also in This Release: Workdir Path Encoding" translate="no">​</a></h2>
<p>Separately, the internal <code>.workdir/</code> directory Atmos uses for JIT component provisioning now
encodes component and stack names more carefully, to guarantee two differently named components
(e.g. one named <code>app/local</code> and another named <code>app-local</code>) can never accidentally resolve to the
same on-disk directory and share files or state.</p>
<p>This changes the on-disk directory name for any component whose name contains a literal <code>-</code>,
<code>/</code>, or <code>\</code>. Atmos migrates a workdir it finds at the old location automatically the next time
that component is provisioned, so this should be transparent for most setups.</p>]]></content:encoded>
            <category>Bug Fix</category>
            <category>Breaking Change</category>
        </item>
        <item>
            <title><![CDATA[GKE Kubeconfig Authentication: Native kubectl and Helm Access Without gcloud]]></title>
            <link>https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/gke-kubeconfig-authentication</link>
            <guid>https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/gke-kubeconfig-authentication</guid>
            <pubDate>Fri, 14 Aug 2026 12:00:00 GMT</pubDate>
            <description><![CDATA[Using an Atmos-managed GCP identity with GKE used to stop one step short of the cluster. The]]></description>
            <content:encoded><![CDATA[<p>Using an Atmos-managed GCP identity with GKE used to stop one step short of the cluster. The
identity could authenticate Terraform and other GCP clients, but operators still needed <code>gcloud</code>
or <code>gke-gcloud-auth-plugin</code> to discover the cluster, write kubeconfig, and refresh Kubernetes
credentials. Atmos now handles that complete path itself.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-2957.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-2957.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-2957.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-2957.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-2957.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-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/gke-kubeconfig-authentication#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>Try the integration with your GCP identity chain and GKE clusters. Share feedback in the
<a href="https://cloudposse.com/slack" target="_blank" rel="noopener noreferrer" class="">Cloud Posse community</a> or open an issue on
<a href="https://github.com/cloudposse/atmos/issues" target="_blank" rel="noopener noreferrer" class="">GitHub</a>.</p>]]></content:encoded>
            <category>Feature</category>
        </item>
        <item>
            <title><![CDATA[Generate one file per selection with matrix]]></title>
            <link>https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/scaffold-matrix</link>
            <guid>https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/scaffold-matrix</guid>
            <pubDate>Fri, 14 Aug 2026 12:00:00 GMT</pubDate>
            <description><![CDATA[Every file a scaffold template declares renders at most once. when: can skip a file, but it]]></description>
            <content:encoded><![CDATA[<p>Every file a scaffold template declares renders at most once. <code>when:</code> can skip a file, but it
can never multiply one. You could work around that by authoring every combination up front and
letting <code>when:</code> prune down to what applies — but that only works if every combination is
knowable in advance. It breaks down for environments picked interactively from a longer list, or
names typed in by hand that no template author could have enumerated ahead of time. Until now,
that meant hand-rolling files outside the template, or maintaining a pile of near-duplicate ones
inside it.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-2957.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-2957.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-2957.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-2957.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-2957.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-2957.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-2957.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/scaffold/generate"><code>atmos scaffold generate</code></a> docs for the full reference,
or <a href="https://github.com/cloudposse/atmos/issues" target="_blank" rel="noopener noreferrer" class="">open an issue</a> with feedback.</p>]]></content:encoded>
            <category>Feature</category>
        </item>
        <item>
            <title><![CDATA[Containers, Emulators, and Run Steps Now Resolve Each Other by Name]]></title>
            <link>https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/container-shared-networking</link>
            <guid>https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/container-shared-networking</guid>
            <pubDate>Fri, 14 Aug 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Bring up two containers in the same environment and the first thing you hit is that they can't]]></description>
            <content:encoded><![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-2957.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-2957.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-2957.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-2957.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-2957.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:encoded>
            <category>Feature</category>
        </item>
        <item>
            <title><![CDATA[Remote Imports: Automatic GitHub Auth, Failure Warnings, and Caching]]></title>
            <link>https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/remote-import-github-auth-and-caching</link>
            <guid>https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/remote-import-github-auth-and-caching</guid>
            <pubDate>Tue, 11 Aug 2026 12:00:00 GMT</pubDate>
            <description><![CDATA[Centralizing shared configuration in one private Git repository, and reusing it across projects, is not a]]></description>
            <content:encoded><![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-2957.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-2957.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-2957.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-2957.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:encoded>
            <category>Enhancement</category>
            <category>DX</category>
        </item>
        <item>
            <title><![CDATA[Keep your formatting through atmos scaffold --update]]></title>
            <link>https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/scaffold-merge-driver</link>
            <guid>https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/scaffold-merge-driver</guid>
            <pubDate>Tue, 11 Aug 2026 12:00:00 GMT</pubDate>
            <description><![CDATA[Atmos scaffolds can perform genuinely complex three-way merges of YAML templates: keys can merge]]></description>
            <content:encoded><![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-2957.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-2957.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-2957.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-2957.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-2957.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/scaffold/generate"><code>atmos scaffold generate</code></a> and
<a class="" href="https://pr-2957.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:encoded>
            <category>Feature</category>
        </item>
        <item>
            <title><![CDATA[Select Vendored Components by Stack, Label, or Tag]]></title>
            <link>https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/vendor-stack-flag</link>
            <guid>https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/vendor-stack-flag</guid>
            <pubDate>Tue, 11 Aug 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[A CI job deploying the dev stack shouldn't need to vendor every component in the repository --]]></description>
            <content:encoded><![CDATA[<p>A CI job deploying the dev stack shouldn't need to vendor every component in the repository --
just the ones dev actually uses. Production deploys have the same problem in reverse: pulling in
components that belong to other environments wastes time and widens what that job can touch.
Selecting the right subset meant either hand-listing every component with repeated <code>--component</code>
flags or reaching for <code>--everything</code> and pulling in components the job has nothing to do with.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/vendor-stack-flag#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>Scoping a vendor pull to "just what this stack needs" is a selection CI reaches for on every
deploy, not an occasional convenience. Without it, the choice was between hand-listing every
component or vendoring the entire repository. Neither scales, and neither composes: picking
components by tag, by name, and by the stack they belong to used to be three separate, mutually
exclusive modes rather than filters that could work together.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/vendor-stack-flag#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p><code>atmos vendor pull</code> now accepts <code>--stack</code> and <code>--labels</code> selectors, and <code>--tags</code> composes with
either of them (or with <code>--component</code>) as an independent, narrowing filter -- across <code>pull</code>,
<code>diff</code>, <code>clean</code>, <code>update</code>, and <code>verify</code> alike:</p>
<ul>
<li class=""><code>--stack</code> vendors every component declared in that stack that has its own <code>component.yaml</code>.</li>
<li class=""><code>--labels</code> filters that eligible stack component set by each component's stack
<code>metadata.labels</code>.</li>
<li class=""><code>--tags</code> narrows whichever set <code>--stack</code>/<code>--labels</code> (or <code>--component</code>) resolved, down to
components whose declared source tags match.</li>
</ul>
<p>Combining selectors that don't overlap now fails with a clear error instead of silently matching
nothing or falling back to a different set than you asked for.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/vendor-stack-flag#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"># Vendor each stack component that has a component.yaml</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos vendor pull </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--stack</span><span class="token plain"> plat-ue2-dev</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Select by stack metadata.labels instead of stack name</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos vendor pull </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--labels</span><span class="token plain"> </span><span class="token assign-left variable" style="color:rgb(214, 222, 235)">tier</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token number" style="color:rgb(247, 140, 108)">1</span><span class="token plain">,cost-center:platform</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"># Narrow a stack selection further by declared tag</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos vendor pull </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--stack</span><span class="token plain"> plat-ue2-dev </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--tags</span><span class="token plain"> networking</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"># Preview instead of pulling</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos vendor pull </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--stack</span><span class="token plain"> plat-ue2-dev --dry-run</span><br></div></code></pre></div></div>
<p>The same selectors work on the other vendor subcommands:</p>
<div class="language-shell codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-shell codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A"><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos vendor </span><span class="token function" style="color:rgb(130, 170, 255)">diff</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--stack</span><span class="token plain"> plat-ue2-dev </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--tags</span><span class="token plain"> networking</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos vendor update </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--labels</span><span class="token plain"> </span><span class="token assign-left variable" style="color:rgb(214, 222, 235)">tier</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token number" style="color:rgb(247, 140, 108)">1</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--check</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos vendor clean </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--stack</span><span class="token plain"> plat-ue2-dev</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos vendor verify </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--labels</span><span class="token plain"> </span><span class="token assign-left variable" style="color:rgb(214, 222, 235)">tier</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token number" style="color:rgb(247, 140, 108)">1</span><br></div></code></pre></div></div>
<p>For <code>atmos vendor pull</code>, <code>--stack</code>/<code>--labels</code> install each matched component from its own
<code>component.yaml</code>, bypassing <code>vendor.yaml</code> entirely -- components without one are skipped, and if
every matched component lacks a <code>component.yaml</code> the command succeeds having pulled nothing. It
only fails with the shared selector's "no components matched" error when <code>--stack</code>/<code>--labels</code>
itself resolves to no stack, or when <code>--tags</code> narrows an already non-empty selection down to zero.
<code>--component</code> still selects a single, explicitly named component and isn't combined with
<code>--stack</code>/<code>--labels</code>, but composes with <code>--tags</code> the same way they do. <code>diff</code>, <code>update</code>, <code>clean</code>,
and <code>verify</code> use the same selectors to resolve component names, but retain their own
manifest-resolution rules (<code>vendor.yaml</code> first, falling back to <code>component.yaml</code>).</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/vendor-stack-flag#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 or ideas for vendor improvements? Join our <a href="https://slack.cloudposse.com/" target="_blank" rel="noopener noreferrer" class="">Slack community</a> or open an issue on <a href="https://github.com/cloudposse/atmos/issues" target="_blank" rel="noopener noreferrer" class="">GitHub</a>.</p>]]></content:encoded>
            <category>Feature</category>
        </item>
        <item>
            <title><![CDATA[Automatic Azure Backend Provisioning for Terraform State]]></title>
            <link>https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/azure-backend-provisioning</link>
            <guid>https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/azure-backend-provisioning</guid>
            <pubDate>Sun, 09 Aug 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Bootstrapping Terraform state on Azure has always meant a detour outside Terraform: before you]]></description>
            <content:encoded><![CDATA[<p>Bootstrapping Terraform state on Azure has always meant a detour outside Terraform: before you
can run a single <code>plan</code>, you have to hand-create a resource group, a storage account (with the
right TLS, public-access, and auth settings), and a blob container — by portal, <code>az</code> script, or a
one-off Terraform component you cold-start and then migrate. AWS users have had one-line automatic
backend provisioning for a while. Azure users had a checklist. Not anymore.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/azure-backend-provisioning#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>Atmos could already generate <code>backend.tf.json</code> for an <code>azurerm</code> backend and read its state
in-process — but it couldn't <em>create</em> the backend. Turn on backend auto-provisioning against an
<code>azurerm</code> backend and nothing happened; it silently skipped, because provisioning only knew how
to make S3 buckets. So every new subscription hit the same chicken-and-egg: you need remote state
to run Terraform, but you need something <em>other</em> than Terraform to create that remote state first.</p>
<p>The workaround was a bespoke storage-account component that runs on local state, then migrates its
own state into the account it just created. It works, but it's ceremony every team re-invents — and
it's exactly the friction AWS users don't have.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/azure-backend-provisioning#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 provisions <code>azurerm</code> backends automatically, the same way it does for S3. Point a
component at an <code>azurerm</code> backend, enable provisioning, and Atmos creates what's missing — the
resource group, the storage account, and the container — with secure defaults, before
<code>terraform init</code> runs.</p>
<p>Everything is created with opinionated, hardcoded best practices:</p>
<ul>
<li class=""><strong>TLS 1.2 minimum</strong> and <strong>HTTPS-only</strong> traffic</li>
<li class=""><strong>Public blob access blocked</strong>; the state container is <strong>private</strong></li>
<li class=""><strong>Blob versioning enabled</strong> — the direct analog of S3 versioning, so every state write is recoverable</li>
<li class=""><strong>Soft delete</strong> (blob + container) with 30-day retention as a safety net</li>
<li class=""><strong>Entra ID hardening</strong>: when your backend sets <code>use_azuread_auth: true</code>, the storage account is
created with shared-key access disabled — no account keys to leak</li>
</ul>
<p>And one thing Atmos deliberately does <strong>not</strong> create: a lock table. On Azure, state locking is
built into Blob Storage — the <code>azurerm</code> backend takes an exclusive <strong>blob lease</strong> on the state
blob during each operation, so concurrent runs are serialized with no extra resource. (On AWS that
role is played by a DynamoDB table or native S3 lockfiles; on Azure there's simply nothing to
provision.)</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/azure-backend-provisioning#how-to-use-it" class="hash-link" aria-label="Direct link to How to Use It" title="Direct link to How to Use It" translate="no">​</a></h2>
<p>Add <code>provision.backend.enabled: true</code> to a component that uses an <code>azurerm</code> backend:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token key atrule">components</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">terraform</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">vpc</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">auth</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">providers</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">          </span><span class="token key atrule">azure</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line 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"> azure/interactive</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">            </span><span class="token key atrule">identity</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> platform</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain" 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">backend_type</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> azurerm</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">backend</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">resource_group_name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> rg</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">tfstate</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">cus</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">storage_account_name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> stexampletfstateplatformcus</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">container_name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> tfstate</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">key</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> vpc.terraform.tfstate</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">use_azuread_auth</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token boolean important" style="color:rgb(255, 88, 116)">true</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain" style="display:inline-block"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">provision</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">backend</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">          </span><span class="token key atrule">enabled</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token boolean important" style="color:rgb(255, 88, 116)">true</span></span><br></div></code></pre></div></div>
<p>Then run Terraform as usual:</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">atmos terraform apply vpc </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-s</span><span class="token plain"> platform-cus</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"># Backend resource group, storage account, and container are created if missing, then init/apply proceed.</span><br></div></code></pre></div></div>
<p>That's it. Atmos checks whether the backend is fully provisioned, creates only what's missing, and
continues. It's idempotent — safe to leave enabled and safe to re-run.</p>
<p>A few things worth knowing:</p>
<ul>
<li class=""><strong>You don't put <code>location</code> in the backend block.</strong> It isn't a valid <code>azurerm</code> backend argument,
so Atmos takes the region from your active Azure identity — or, if the resource group already
exists, from the group itself. Pre-create the resource group and you don't need to configure a
location at all.</li>
<li class=""><strong>Subscription</strong> comes from <code>backend.subscription_id</code> if set, otherwise from your active Azure
identity.</li>
<li class=""><strong>It composes with inheritance.</strong> Enable provisioning once at the org or environment level and
override per component — on in dev/qa, off in prod where state storage is module-managed.</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_cA1_" id="managing-the-backend-explicitly">Managing the backend explicitly<a href="https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/azure-backend-provisioning#managing-the-backend-explicitly" class="hash-link" aria-label="Direct link to Managing the backend explicitly" title="Direct link to Managing the backend explicitly" translate="no">​</a></h3>
<p>The same lifecycle commands that work for S3 now work for <code>azurerm</code>:</p>
<div class="language-bash codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-bash codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A"><div class="token-line" style="color:#d6deeb"><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Create the backend explicitly (e.g. in a CI bootstrap stage)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos terraform backend create vpc </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-s</span><span class="token plain"> platform-cus</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"># Tear it down (deletes the storage account and all state in it — resource group is preserved)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos terraform backend delete vpc </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-s</span><span class="token plain"> platform-cus </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--force</span><br></div></code></pre></div></div>
<p>Deletion always requires <code>--force</code>, and it removes the storage account (and therefore every state
file in it, just as deleting an S3 bucket does), while leaving the resource group in place.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="not-for-production-as-is">Not for Production As-Is<a href="https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/azure-backend-provisioning#not-for-production-as-is" class="hash-link" aria-label="Direct link to Not for Production As-Is" title="Direct link to Not for Production As-Is" translate="no">​</a></h2>
<p>Like the S3 provisioner, this is built for fast, secure bootstrapping — dev, test, CI, and
cold-starts — not to replace a production-grade module. It doesn't set up customer-managed keys,
private endpoints, network ACLs, geo/zone redundancy, or lifecycle policies. When you're ready to
harden, import the resource group, storage account, and container into a managed module (such as
<code>Azure/avm-res-storage-storageaccount</code>) and keep using the same backend — no state migration
needed, because the account keeps its name and contents. You can even leave provisioning enabled;
Atmos detects the resources exist and skips.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/azure-backend-provisioning#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>Give it a try on your Azure subscriptions and let us know how it goes. Questions or ideas? Start a
thread in <a href="https://github.com/cloudposse/atmos/discussions" target="_blank" rel="noopener noreferrer" class="">GitHub Discussions</a>, or open an issue
in the <a href="https://github.com/cloudposse/atmos/issues" target="_blank" rel="noopener noreferrer" class="">issue tracker</a>.</p>]]></content:encoded>
            <category>Feature</category>
            <category>DX</category>
        </item>
        <item>
            <title><![CDATA[Keep Installed AI Skills Up to Date]]></title>
            <link>https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/ai-skill-update</link>
            <guid>https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/ai-skill-update</guid>
            <pubDate>Fri, 07 Aug 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Package managers normally tell you when an installed package is out of date and let you refresh]]></description>
            <content:encoded><![CDATA[<p>Package managers normally tell you when an installed package is out of date and let you refresh
just that one. Installed AI skills did not work that way: <code>atmos ai skill install</code> copies a
bundled skill's content once, and upgrading the <code>atmos</code> binary afterward never touches that
already-installed copy, even when the new release ships updated skill content.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/ai-skill-update#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>Official Atmos skills (<code>atmos-terraform</code>, <code>atmos-stacks</code>, and the rest of the catalog) are
embedded directly in the <code>atmos</code> binary. Installing one by name copies its <code>SKILL.md</code> and
supporting files to <code>~/.atmos/skills/</code> at that point in time. If a later <code>atmos</code> release bundles
an improved version of that skill, nothing tells you, and nothing refreshes your local copy — the
only way to pick it up was <code>atmos ai skill install &lt;name&gt; --force</code>, applied on faith, one skill at
a time, with no way to check first whether anything had actually changed.</p>
<p><code>atmos ai skill list --detailed</code> already surfaced an "update available" hint when an installed
skill's version drifted from the catalog. There was no command that acted on it.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/ai-skill-update#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p><code>atmos ai skill update</code> closes that gap. It compares each installed bundled skill's recorded
version against the catalog embedded in the running binary and reinstalls only the ones that are
actually outdated — skills already at the current version are left untouched.</p>
<p>Run it with no arguments to refresh every installed bundled skill that has an update available (a
single confirmation, not one per skill), or name one skill to update just that one. Skills that
are already current report "already up to date" and nothing is rewritten, so it's safe to run
<code>atmos ai skill update</code> repeatedly, including as a habit after every <code>atmos</code> upgrade.</p>
<p>An outdated skill is reinstalled the same way <code>atmos ai skill install &lt;name&gt; --force</code> would
install it, so <code>--client</code>, <code>--scope</code>, <code>--global</code>, <code>--all-clients</code>, and <code>--path</code> all work exactly as
they do on <code>install</code>.</p>
<p>Skills installed from a GitHub repository aren't covered yet — there's no cheap way to check
whether a git-sourced skill's upstream has moved without re-fetching it. Run
<code>atmos ai skill install &lt;source&gt; --force</code> to refresh one of those manually.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/ai-skill-update#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"># Update a single bundled skill if a newer version is available.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos ai skill update atmos-terraform</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"># Update every installed bundled skill that has an update available.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos ai skill update</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"># Skip the confirmation prompt (for automation).</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos ai skill update </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--yes</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"># Update and redistribute to a specific AI client.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos ai skill update atmos-terraform </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--client</span><span class="token plain"> vscode</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/ai-skill-update#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>Read the <a class="" href="https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/ai/skill"><code>atmos ai skill</code></a> documentation for the full command reference.
To share feedback or request an improvement, <a href="https://github.com/cloudposse/atmos/issues" target="_blank" rel="noopener noreferrer" class="">open an issue</a>.</p>]]></content:encoded>
            <category>Feature</category>
        </item>
        <item>
            <title><![CDATA[Smarter Type Handling for `atmos config set` and `atmos stack set`]]></title>
            <link>https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/config-stack-type-inference</link>
            <guid>https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/config-stack-type-inference</guid>
            <pubDate>Thu, 06 Aug 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Editing a config value from the command line is supposed to be the easy path. Type `atmos stack set]]></description>
            <content:encoded><![CDATA[<p>Editing a config value from the command line is supposed to be the easy path. Type <code>atmos stack set vars.replicas 5</code>, expect a <code>5</code>, move on. Except a value like that used to come back out the other side as the
string <code>"5"</code> unless you remembered to pass <code>--type=int</code> — and for <code>atmos stack set</code> specifically, that was
true every single time, no matter what was already there. A <code>true</code> became <code>"true"</code>. A number stayed a number
only if you told the CLI so yourself.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/config-stack-type-inference#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p><code>atmos config set</code> already tried to guess a value's type from the Atmos config schema, but only for fields
the schema knows about — everything else, including the free-form <code>vars</code> and <code>settings</code> sections most people
actually edit, fell back to a plain string with no warning. <code>atmos stack set</code> didn't even have that: it always
wrote a string unless you passed <code>--type</code> explicitly, since component variables have no fixed schema to infer
from in the first place.</p>
<p>On top of that, editing a value that came from an imported catalog file — the normal way Atmos stacks are
organized, defaults in one file, per-environment overrides in another — could fail outright with an error that
pointed at the wrong manifest, leaving no clue where the real value actually lived.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/config-stack-type-inference#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p><code>--type</code> now defaults to <code>auto</code> on both commands, and <code>auto</code> tries harder before it gives up. <code>config set</code>
checks the Atmos config schema first, then the type of the value already at that path. <code>stack set</code> checks the
component's own declared Terraform variable type for <code>vars.*</code> paths first — Atmos already parses
<code>variables.tf</code> while resolving the component, so this costs nothing extra — then the existing value. If the
declared type disagrees with what's already stored (a number saved as a quoted string, say), Atmos retypes it
and tells you so, instead of leaving the mismatch in place.</p>
<p>Only after all of that does either command fall back to the value's own shape: <code>5</code> infers as an int, <code>true</code>
infers as a bool, <code>3.14</code> infers as a float. A value doesn't get silently downgraded to a quoted string just
because nothing else had an opinion on it anymore — that fallback (with a warning) is now reserved for values
that genuinely don't look like anything but a string.</p>
<p>Editing values that live only in an imported catalog file is also fixed: <code>atmos stack set</code>, <code>get</code>, <code>delete</code>,
and <code>list</code> now correctly resolve to the file that actually defines the value, instead of misattributing it to
whichever stack manifest happened to import it.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/config-stack-type-inference#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"># vars.replicas is already 1 (an int) in the manifest -- auto keeps it an int.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos stack </span><span class="token builtin class-name" style="color:rgb(255, 203, 139)">set</span><span class="token plain"> vars.replicas </span><span class="token number" style="color:rgb(247, 140, 108)">5</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-s</span><span class="token plain"> plat-ue2-prod </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-c</span><span class="token plain"> vpc</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"># If variables.tf declares vars.quota as a number, auto uses that -- and retypes an</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"># existing value that disagrees, e.g. one stored as a quoted string.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos stack </span><span class="token builtin class-name" style="color:rgb(255, 203, 139)">set</span><span class="token plain"> vars.quota </span><span class="token number" style="color:rgb(247, 140, 108)">10</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-s</span><span class="token plain"> plat-ue2-prod </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-c</span><span class="token plain"> vpc</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"># A brand-new vars.new_flag with nothing existing to infer from now infers straight</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"># from the value's shape: "true" is written as a bool, not the string "true".</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos stack </span><span class="token builtin class-name" style="color:rgb(255, 203, 139)">set</span><span class="token plain"> vars.new_flag </span><span class="token boolean" style="color:rgb(255, 88, 116)">true</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-s</span><span class="token plain"> plat-ue2-prod </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-c</span><span class="token plain"> vpc</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"># Works even when the value is only defined in an imported catalog file.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos stack </span><span class="token builtin class-name" style="color:rgb(255, 203, 139)">set</span><span class="token plain"> vars.region us-west-2 </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-s</span><span class="token plain"> plat-ue2-prod </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-c</span><span class="token plain"> vpc</span><br></div></code></pre></div></div>
<p><code>--type</code> still accepts <code>string</code>, <code>int</code>, <code>bool</code>, <code>float</code>, <code>null</code>, or <code>yaml</code> explicitly whenever you want to
skip inference entirely.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/config-stack-type-inference#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>Run into a case where inference guesses wrong, or a value that still won't resolve? Open an issue on
<a href="https://github.com/cloudposse/atmos" target="_blank" rel="noopener noreferrer" class="">GitHub</a> — this is exactly the kind of day-to-day CLI friction we want
to keep sanding down.</p>]]></content:encoded>
            <category>Enhancement</category>
            <category>Bug Fix</category>
        </item>
        <item>
            <title><![CDATA[atmos toolchain update: Move a Pinned Tool Forward Safely]]></title>
            <link>https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/toolchain-update-command</link>
            <guid>https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/toolchain-update-command</guid>
            <pubDate>Thu, 06 Aug 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Pinning a CLI tool to an exact version is good practice — until it's time to move forward. Then it means]]></description>
            <content:encoded><![CDATA[<p>Pinning a CLI tool to an exact version is good practice — until it's time to move forward. Then it means
opening <code>.tool-versions</code> by hand, going to check the tool's release page, picking a version, and editing the
line yourself. Get it wrong and you're stuck rerunning install commands to find out.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/toolchain-update-command#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>A tool declared in <code>.tool-versions</code> stays exactly where you pinned it, on purpose — that's what makes it
reproducible. But "pinned" shouldn't mean "stuck." When a new release ships, moving a tool forward has always
meant editing the file by hand: look up the tool's latest release yourself, write the new version string
into <code>.tool-versions</code>, then reinstall and hope you copied it correctly. There was no single command that
answered "what's newer, and can I have it?"</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/toolchain-update-command#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p><code>atmos toolchain update</code> resolves each tool's newest available version and moves the pin forward for you,
then installs it. Run it with no arguments to update everything in <code>.tool-versions</code>, or name specific tools
to update just those. Tools pinned to a PR, commit SHA, or git ref are left alone — those pins are meant to
stay exact, so <code>update</code> skips them with an explanation instead of silently doing nothing.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/toolchain-update-command#how-to-use-it" class="hash-link" aria-label="Direct link to How to Use It" title="Direct link to How to Use It" translate="no">​</a></h2>
<p>Update everything:</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 update</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">✓ terraform: </span><span class="token number" style="color:rgb(247, 140, 108)">1.9</span><span class="token plain">.8 -</span><span class="token operator" style="color:rgb(127, 219, 202)">&gt;</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">1.11</span><span class="token plain">.4</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">✓ jq: up to </span><span class="token function" style="color:rgb(130, 170, 255)">date</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token number" style="color:rgb(247, 140, 108)">1.8</span><span class="token plain">.2</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">Updated </span><span class="token number" style="color:rgb(247, 140, 108)">1</span><span class="token plain"> tool</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">s</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain">, </span><span class="token number" style="color:rgb(247, 140, 108)">1</span><span class="token plain"> up to </span><span class="token function" style="color:rgb(130, 170, 255)">date</span><br></div></code></pre></div></div>
<p>Update one tool, or preview first:</p>
<div class="language-shell codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-shell codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A"><div class="token-line" style="color:#d6deeb"><span class="token plain">$ atmos toolchain update terraform --dry-run</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">terraform: </span><span class="token number" style="color:rgb(247, 140, 108)">1.9</span><span class="token plain">.8 -</span><span class="token operator" style="color:rgb(127, 219, 202)">&gt;</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">1.11</span><span class="token plain">.4 </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">dry-run</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">Would update </span><span class="token number" style="color:rgb(247, 140, 108)">1</span><span class="token plain"> tool</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">s</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><br></div></code></pre></div></div>
<p>Tools are updated concurrently, with the same <code>--max-concurrency</code> control <code>atmos toolchain install</code> already
supports.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/toolchain-update-command#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>Try <code>atmos toolchain update</code> the next time a pinned tool falls behind. If you run into a tool whose update
doesn't behave the way you'd expect, please
<a href="https://github.com/cloudposse/atmos/issues" target="_blank" rel="noopener noreferrer" class="">open an issue</a>.</p>]]></content:encoded>
            <category>Feature</category>
            <category>DX</category>
        </item>
        <item>
            <title><![CDATA[Browse, Search, and Copy Any Atmos Agent Skill Before You Install It]]></title>
            <link>https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/agent-skills-directory</link>
            <guid>https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/agent-skills-directory</guid>
            <pubDate>Wed, 05 Aug 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Before you install a skill, you want to read what it does. Atmos agent skills did not let you do that. You]]></description>
            <content:encoded><![CDATA[<p>Before you install a skill, you want to read what it does. Atmos agent skills did not let you do that. You
had to install a skill first to read its full instructions. Or you had to find its file in the Atmos
repository on GitHub. An AI agent had the same problem. No page listed every skill with its full content. No
single URL let an agent fetch a skill's content on its own.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/agent-skills-directory#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-2957.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/ai/skill"><code>atmos ai skill list</code></a> command already listed every official skill, showing
each skill's name, source, and install status. Add <code>--detailed</code>, and it also showed a one-line description.
But no view showed a skill's full instructions -- the actual content that teaches the AI its domain
knowledge.</p>
<p>To read that content, you had two options. Install the skill first. Or open the Atmos repository on GitHub
and find the right <code>SKILL.md</code> file. Neither option let you compare skills quickly. Neither option gave an AI
agent a direct way to fetch and read a skill's content on its own.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/agent-skills-directory#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>The <a class="" href="https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/ai/skills">Agent Skills Directory</a> lists every skill with its full content. Open the directory. Search
by name, description, or category. Click a skill to read its complete instructions -- no install step
required. Add a new skill to the Atmos repository, and it appears in the directory automatically.</p>
<p>Each skill's page also has a raw Markdown version. Add <code>.md</code> to the page's URL. This is the same convention
the rest of the Atmos docs site uses. An AI agent can fetch this URL directly and read the skill's content.</p>
<p>Each skill's page also has a "Copy as Markdown" button. Use it to copy the skill's full content. Paste it
into a chat session, or review it, before you install anything.</p>
<p>The <code>atmos ai skill list</code> command also gained a <code>--format</code> flag and a Category column, so the same
categorization shown in the directory is available from the CLI.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/agent-skills-directory#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>Browse and search the directory at <a class="" href="https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/ai/skills">atmos.tools/ai/skills</a>. Or fetch a skill's content directly:</p>
<div class="language-shell codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-shell codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A"><div class="token-line" style="color:#d6deeb"><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Raw Markdown for one skill - readable by a human, fetchable by an agent</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)">skill_name</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">atmos-ai</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token function" style="color:rgb(130, 170, 255)">curl</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"https://atmos.tools/ai/skills/</span><span class="token string variable" style="color:rgb(214, 222, 235)">${skill_name}</span><span class="token string" style="color:rgb(173, 219, 103)">.md"</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"># Table view, now with a Category column</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos ai skill list</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"># Machine-readable output for scripting</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos ai skill list </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><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos ai skill list </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">yaml</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/agent-skills-directory#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-2957.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/ai/skill">Agent Skills</a> guide to learn how skills are structured. It also explains
how to contribute one. Share skill ideas and contributions in the
<a href="https://github.com/cloudposse/atmos" target="_blank" rel="noopener noreferrer" class="">Atmos community</a>.</p>]]></content:encoded>
            <category>Feature</category>
            <category>DX</category>
        </item>
        <item>
            <title><![CDATA[Injecting Terraform Values into Kustomize Without Hand-Editing Overlays]]></title>
            <link>https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/kustomize-gitops-delivery</link>
            <guid>https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/kustomize-gitops-delivery</guid>
            <pubDate>Wed, 05 Aug 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Kustomize expects the files it consumes to have exact, reserved names. A remote base or]]></description>
            <content:encoded><![CDATA[<p>Kustomize expects the files it consumes to have exact, reserved names. A remote base or
component can only be included if the location it points to contains a file with one of a
handful of recognized names (<code>kustomization.yaml</code> is the common one) — that's not
configurable on Kustomize's side. So when a value only Terraform knows — a security group
ID, a Route53 zone ID, an ARN — needs to land inside a Kustomize-managed GitOps repo, teams
are usually stuck hand-editing the overlay after every apply, or routing the value through a
separate tool just to produce one correctly-named file.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/kustomize-gitops-delivery#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>Delivering rendered Kubernetes manifests to a Git deployment repository (the source Argo CD
or Flux reconciles) always wrote them as a directory — one generated file per manifest, no
way to land a single file under an exact, caller-chosen name. That's a fine default for a
directory of standalone resources, but it can't produce <code>kustomization.yaml</code>, so it couldn't
support this pattern at all. Separately, Kustomize's own <code>Kustomization</code> and <code>Component</code>
config objects don't have a <code>metadata.name</code> in the real Kustomize schema — they're local
input to the <code>kustomize</code> build tool, not Kubernetes API resources — but Atmos's manifest
validator required one anyway, rejecting perfectly valid Kustomize files.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/kustomize-gitops-delivery#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>A git provision target's <code>path</code> can now be an exact single-file destination, not just a
directory. Set <code>split: false</code> to merge every rendered manifest into one file written at that
path; leave it unset and Atmos infers the right mode from whether the path looks like a
manifest filename (<code>.yaml</code>, <code>.yml</code>, or <code>.json</code>). Every existing configuration keeps its
current directory behavior unchanged.</p>
<p>Atmos also now recognizes Kustomize's own <code>Kustomization</code> and <code>Component</code> kinds and no
longer requires a <code>metadata.name</code> on them — matching Kustomize's own validation, not an
opinion Atmos invented. For anything else, a new <code>validate: false</code> component setting opts
out of Atmos's structural checks entirely.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/kustomize-gitops-delivery#how-to-use-it" class="hash-link" aria-label="Direct link to How to Use It" title="Direct link to How to Use It" translate="no">​</a></h2>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token key atrule">components</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">kubernetes</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">cert-manager-patch</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">provision</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">targets</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">          </span><span class="token key atrule">deployment-repo</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line 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"> git</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">            </span><span class="token key atrule">repository</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> deployments</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">            </span><span class="token key atrule">path</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"kustomize/overlays/{{ .vars.environment }}/kustomization.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">commit</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">              </span><span class="token key atrule">message</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)">"Render manifests for {{ .vars.environment }}"</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">manifests</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="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">apiVersion</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> kustomize.config.k8s.io/v1alpha1</span></span><br></div><div class="token-line 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"> Component</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">          </span><span class="token key atrule">patches</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="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">target</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line 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"> ClusterIssuer</span></span><br></div><div class="token-line 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"> letsencrypt</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">dns</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">              </span><span class="token key atrule">patch</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 scalar string" style="color:rgb(173, 219, 103)"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token scalar string" style="color:rgb(173, 219, 103)">                - op: add</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token scalar string" style="color:rgb(173, 219, 103)">                  path: /spec/acme/solvers</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token scalar string" style="color:rgb(173, 219, 103)">                  value:</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token scalar string" style="color:rgb(173, 219, 103)">                    - dns01:</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token scalar string" style="color:rgb(173, 219, 103)">                        route53:</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token scalar string" style="color:rgb(173, 219, 103)">                          region: "{{ .vars.aws_region }}"</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token scalar string" style="color:rgb(173, 219, 103)">                          hostedZoneID: "{{ atmos.Resolve \"!terraform.state route53 public_zone_id\" }}"</span></span><br></div></code></pre></div></div>
<div class="language-shell codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-shell codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A"><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos kubernetes deploy cert-manager-patch </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-s</span><span class="token plain"> plat-ue2-dev </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--target</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">deployment-repo</span><br></div></code></pre></div></div>
<p>No <code>split</code> is set here — the path ends in <code>kustomization.yaml</code>, so Atmos writes it as a
single file automatically. No <code>metadata.name</code> is needed on the <code>Component</code> object either.
The real Kustomize overlay then includes the generated file as a remote component, so the
Terraform-derived value flows through on every deploy without anyone touching the overlay by
hand. See <a class="" href="https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/stacks/components/kubernetes#generating-a-kustomize-component-for-gitops">Generating a Kustomize component for GitOps</a>
for the full walkthrough.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/kustomize-gitops-delivery#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>Try delivering a Kustomize component or patch through a git provision target in your own
GitOps repo. Tell us what's missing — pull-request publishing for the git target, support
for other Kustomize-only object kinds, or something else — by opening an issue at
<a href="https://github.com/cloudposse/atmos" target="_blank" rel="noopener noreferrer" class="">github.com/cloudposse/atmos</a>.</p>]]></content:encoded>
            <category>Bug Fix</category>
            <category>Enhancement</category>
        </item>
        <item>
            <title><![CDATA[Custom Commands and Workflows Are Now a Complete Task Runner Replacement]]></title>
            <link>https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/taskfile-convergence</link>
            <guid>https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/taskfile-convergence</guid>
            <pubDate>Wed, 05 Aug 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[If you've ever tried to move a Taskfile.yml over to Atmos, you've hit the gap had no]]></description>
            <content:encoded><![CDATA[<p>If you've ever tried to move a <code>Taskfile.yml</code> over to Atmos, you've hit the gap: <code>deps:</code> had no
clean equivalent in custom commands, <code>sources:</code>/<code>generates:</code> up-to-date checking didn't exist at
all, and a failed lint step stopped your whole release pipeline even when you just wanted to see
every check's result. So teams ended up running two tools side by side — go-task for the parts
Atmos couldn't do, Atmos for everything else — instead of one.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/taskfile-convergence#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>Atmos workflows and custom commands already covered most of what a task runner needs: steps,
templating, conditionals, parallel execution. But a handful of real gaps kept people from fully
retiring go-task:</p>
<ul>
<li class=""><strong>No dependency ordering between named commands or workflows.</strong> You could make steps <em>within</em>
one command run in parallel, but you couldn't say "run <code>build</code> before <code>test</code> and <code>lint</code>, and
don't run <code>build</code> twice just because two things depend on it."</li>
<li class=""><strong>No up-to-date checking.</strong> go-task's <code>sources:</code>/<code>generates:</code> skip a task when nothing has
changed. Atmos had nothing like it — every step ran every time, even a slow compile step whose
inputs hadn't changed since the last successful run.</li>
<li class=""><strong>No continue-on-error.</strong> A single failing step stopped everything downstream, even for
steps — like a linter — where you'd rather collect every result and report at the end.</li>
<li class=""><strong>No precondition shortcut.</strong> Skipping an install step when a tool is already on <code>PATH</code> meant
hand-rolling a shell check.</li>
<li class=""><strong>Custom commands couldn't use <code>parallel</code>/<code>matrix</code> at all.</strong> The migration guide's own suggested
workaround — wrap dependents in a <code>parallel</code> step with <code>needs:</code> — silently failed on custom
commands; it only worked in workflows.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/taskfile-convergence#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>Custom commands and workflows now cover all of it, using the same <code>when:</code>/CEL condition engine and
scheduler Atmos already had — no second, bespoke mechanism bolted on.</p>
<h3 class="anchor anchorTargetStickyNavbar_cA1_" id="dependencies-between-commands-and-workflows">Dependencies between commands and workflows<a href="https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/taskfile-convergence#dependencies-between-commands-and-workflows" class="hash-link" aria-label="Direct link to Dependencies between commands and workflows" title="Direct link to Dependencies between commands and workflows" translate="no">​</a></h3>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token key atrule">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"> build</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">steps</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 punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token plain"></span></span><br></div><div class="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"> test</span></span><br></div><div class="token-line 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">commands</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">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">steps</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 punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token plain"></span></span><br></div><div class="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"> lint</span></span><br></div><div class="token-line 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">commands</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">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">steps</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 punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token plain"></span></span><br></div><div class="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"> release</span></span><br></div><div class="token-line 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">commands</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">test</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> lint</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token plain"></span></span><br></div><div class="token-line 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 class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token punctuation" style="color:rgb(199, 146, 234)">...</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span></span><br></div></code></pre></div></div>
<p><code>build</code> is declared as a dependency of both <code>test</code> and <code>lint</code>, but it only runs once — the graph
dedups identical dependency invocations automatically. Dependencies run concurrently by default.
Need the same command with different inputs? Parameterize 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">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">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"> build</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">flags</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> </span><span class="token key atrule">env</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"></span></span><br></div><div class="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"> build</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">flags</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> </span><span class="token key atrule">env</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><br></div></code></pre></div></div>
<p>Both invocations run — different parameters mean different graph nodes. Workflows get the same
<code>dependencies.workflows</code>, including cross-file references via <code>file:</code>.</p>
<h3 class="anchor anchorTargetStickyNavbar_cA1_" id="skip-steps-that-are-already-up-to-date">Skip steps that are already up to date<a href="https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/taskfile-convergence#skip-steps-that-are-already-up-to-date" class="hash-link" aria-label="Direct link to Skip steps that are already up to date" title="Direct link to Skip steps that are already up to date" translate="no">​</a></h3>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token key atrule">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"> compile</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">inputs</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">sources</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token string" style="color:rgb(173, 219, 103)">"cmd/**/*.go"</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)">"go.sum"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">artifacts</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line 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 class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token string" style="color:rgb(173, 219, 103)">"bin/handler"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token plain"></span></span><br></div><div class="token-line 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"> go build </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">o bin/handler ./cmd/handler</span></span><br></div></code></pre></div></div>
<p>No extra configuration needed — declaring <code>inputs</code>/<code>artifacts</code> alone means "skip this step unless
<code>sources</code> changed since the last successful run." Run it twice in a row and the second run skips
entirely. Power users can reference the underlying facts directly (<code>checksum.changed</code>,
<code>timestamp.changed</code>, or the raw per-file <code>sources</code>/<code>artifacts</code> records) for custom logic.</p>
<h3 class="anchor anchorTargetStickyNavbar_cA1_" id="skip-a-step-when-a-tool-is-already-installed">Skip a step when a tool is already installed<a href="https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/taskfile-convergence#skip-a-step-when-a-tool-is-already-installed" class="hash-link" aria-label="Direct link to Skip a step when a tool is already installed" title="Direct link to Skip a step when a tool is already installed" translate="no">​</a></h3>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token key atrule">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"> install</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">stringer</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">preconditions</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">tools</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token string" style="color:rgb(173, 219, 103)">"stringer"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token plain"></span></span><br></div><div class="token-line 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"> go install golang.org/x/tools/cmd/stringer@latest</span></span><br></div></code></pre></div></div>
<p>Resolved via Go's <code>exec.LookPath</code> — no shell, so it works identically on Linux, macOS, and
Windows.</p>
<h3 class="anchor anchorTargetStickyNavbar_cA1_" id="continue-past-a-failing-step">Continue past a failing step<a href="https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/taskfile-convergence#continue-past-a-failing-step" class="hash-link" aria-label="Direct link to Continue past a failing step" title="Direct link to Continue past a failing step" translate="no">​</a></h3>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token key atrule">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"> golangci</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">lint 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">continue</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> always</span></span><br></div><div class="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"> 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">command</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> terraform apply vpc </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">auto</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">approve</span></span><br></div></code></pre></div></div>
<p><code>continue: always</code> mirrors GitHub Actions' <code>continue-on-error</code>: the step's own failure is still
visible, later steps still run, and the overall exit status is unaffected.</p>
<h3 class="anchor anchorTargetStickyNavbar_cA1_" id="parallelmatrix-now-works-in-custom-commands"><code>parallel</code>/<code>matrix</code> now works in custom commands<a href="https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/taskfile-convergence#parallelmatrix-now-works-in-custom-commands" class="hash-link" aria-label="Direct link to parallelmatrix-now-works-in-custom-commands" title="Direct link to parallelmatrix-now-works-in-custom-commands" translate="no">​</a></h3>
<p>The exact recipe that used to only work in workflows now works identically in custom 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">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"> release</span></span><br></div><div class="token-line 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"> parallel</span></span><br></div><div class="token-line 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">name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> test</span></span><br></div><div class="token-line 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"> go test ./</span><span class="token punctuation" style="color:rgb(199, 146, 234)">...</span><span class="token plain"></span></span><br></div><div class="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"> lint</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">            </span><span class="token key atrule">needs</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">test</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token plain"></span></span><br></div><div class="token-line 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"> golangci</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">lint run ./</span><span class="token punctuation" style="color:rgb(199, 146, 234)">...</span></span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="also-shipped">Also Shipped<a href="https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/taskfile-convergence#also-shipped" class="hash-link" aria-label="Direct link to Also Shipped" title="Direct link to Also Shipped" translate="no">​</a></h2>
<p>A handful of smaller gaps closed alongside the above:</p>
<ul>
<li class=""><strong><code>platforms</code> via <code>when:</code></strong> — <code>when: "os == 'darwin'"</code> instead of a dedicated field, reusing
facts already available everywhere else <code>when:</code> is.</li>
<li class=""><strong>Native command aliases</strong> — <code>aliases: [dep, d]</code> on a custom command, registered in-process,
distinct from the top-level subprocess-redirect <code>aliases:</code> config.</li>
<li class=""><strong><code>internal: true</code></strong> — hide a command from <code>atmos help</code>/<code>atmos list</code> while leaving it fully
invocable, for commands meant only to be run as someone else's dependency.</li>
<li class=""><strong><code>values:</code></strong> on flags and arguments — restrict a flag to a fixed set of choices, with static
validation and an interactive picker when a required value is missing.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/taskfile-convergence#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>All of this is available today in custom commands and workflows — no flags to enable, no config
migration required. See <a class="" href="https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/commands/dependencies">dependencies</a>,
<a class="" href="https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/workflows/steps/inputs"><code>inputs</code></a>, <a class="" href="https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/workflows/steps/artifacts"><code>artifacts</code></a>,
<a class="" href="https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/workflows/steps/preconditions"><code>preconditions</code></a>, and <a class="" href="https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/workflows/steps/continue"><code>continue</code></a> for
the full field references, or the <a class="" href="https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/reference/alternatives">Alternatives</a> page for how Atmos
compares to go-task more broadly.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/taskfile-convergence#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're still running go-task alongside Atmos for one of these reasons, we'd like to hear about
it — open a discussion on <a href="https://github.com/cloudposse/atmos/discussions" target="_blank" rel="noopener noreferrer" class="">GitHub Discussions</a> and
tell us what's still missing.</p>]]></content:encoded>
            <category>Feature</category>
            <category>DX</category>
        </item>
        <item>
            <title><![CDATA[Toolchain registry adds github_archive and github_content support]]></title>
            <link>https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/toolchain-aqua-archive-and-content</link>
            <guid>https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/toolchain-aqua-archive-and-content</guid>
            <pubDate>Wed, 05 Aug 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Atmos's Aqua-compatible toolchain registry now understands two more package types: githubarchive and githubcontent. Tools that ship as a source tarball (like adr-tools and tfenv) or as a single raw file in a repo (like kubens and kubectx) can now be installed through atmos toolchain install without any registry workarounds.]]></description>
            <content:encoded><![CDATA[<p>Atmos's Aqua-compatible toolchain registry now understands two more package types: <code>github_archive</code> and <code>github_content</code>. Tools that ship as a source tarball (like <code>adr-tools</code> and <code>tfenv</code>) or as a single raw file in a repo (like <code>kubens</code> and <code>kubectx</code>) can now be installed through <code>atmos toolchain install</code> without any registry workarounds.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="what-changed">What Changed<a href="https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/toolchain-aqua-archive-and-content#what-changed" class="hash-link" aria-label="Direct link to What Changed" title="Direct link to What Changed" translate="no">​</a></h2>
<p>Aqua's registry defines several package types for downloading tools. Atmos previously supported only two:</p>
<ul>
<li class=""><code>github_release</code> — assets attached to a GitHub Release</li>
<li class=""><code>http</code> — arbitrary HTTP(S) URLs</li>
</ul>
<p>Two more are now supported:</p>
<ul>
<li class=""><code>github_archive</code> — the auto-generated source tarball produced by GitHub for any tag, downloaded from <code>github.com/{owner}/{repo}/archive/refs/tags/{version}.tar.gz</code>. Always <code>.tar.gz</code>, regardless of the <code>format</code> field.</li>
<li class=""><code>github_content</code> — a single file from a GitHub repo at a tag, downloaded from <code>raw.githubusercontent.com/{owner}/{repo}/{version}/{path}</code>. The required <code>path</code> field points to the file inside the repo.</li>
</ul>
<p>Both implementations match upstream <code>aquaproj/aqua</code> exactly. For <code>github_archive</code>, the <code>asset</code>, <code>url</code>, <code>format</code>, and <code>format_overrides</code> fields are intentionally ignored (Aqua hardcodes <code>tar.gz</code> and the URL pattern). For <code>github_content</code>, the same fields are ignored — only <code>repo_owner</code>, <code>repo_name</code>, and <code>path</code> are used.</p>
<p>Before this release, any Aqua registry entry using either type failed with <code>unsupported tool type: ...</code>. Those entries now resolve correctly.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/toolchain-aqua-archive-and-content#how-to-use-it" class="hash-link" aria-label="Direct link to How to Use It" title="Direct link to How to Use It" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_cA1_" id="github_archive">github_archive<a href="https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/toolchain-aqua-archive-and-content#github_archive" class="hash-link" aria-label="Direct link to github_archive" title="Direct link to github_archive" translate="no">​</a></h3>
<p>For a tool that ships its binary as a script inside its source tree — such as <code>adr-tools</code>:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token key atrule">packages</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> </span><span class="token key atrule">type</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> github_archive</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">repo_owner</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> npryce</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">repo_name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> adr</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">tools</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">files</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> adr</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">src</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> adr</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">tools</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain">trimV .Version</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain">/src/adr</span></span><br></div></code></pre></div></div>
<p>The <code>{{trimV .Version}}</code> template expands to match GitHub's archive root directory (e.g., <code>adr-tools-3.0.0/</code> for version <code>v3.0.0</code>), so <code>files[].src</code> points to the file inside the extracted archive.</p>
<h3 class="anchor anchorTargetStickyNavbar_cA1_" id="github_content">github_content<a href="https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/toolchain-aqua-archive-and-content#github_content" class="hash-link" aria-label="Direct link to github_content" title="Direct link to github_content" translate="no">​</a></h3>
<p>For a tool that ships as a single raw file in a repo — such as <code>kubens</code> from <code>ahmetb/kubectx</code>:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token key atrule">packages</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> </span><span class="token key atrule">type</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> github_content</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">repo_owner</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> ahmetb</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">repo_name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> kubectx</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">path</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> kubens</span></span><br></div></code></pre></div></div>
<p>The download URL becomes <code>https://raw.githubusercontent.com/ahmetb/kubectx/{version}/kubens</code>. No archive extraction is involved — the file is downloaded directly.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="why-this-matters">Why This Matters<a href="https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/toolchain-aqua-archive-and-content#why-this-matters" class="hash-link" aria-label="Direct link to Why This Matters" title="Direct link to Why This Matters" translate="no">​</a></h2>
<p>Aqua's upstream registry has hundreds of entries that use these two types — <code>tfenv</code>, <code>tgswitch</code>, <code>adr-tools</code>, <code>kubectx</code>, <code>kubens</code>, and many one-binary shell-script projects. Until now, those entries were dead in Atmos. Adding these two package types unblocks all of them without registry-level changes: pull the Aqua registry entry as-is and it just works.</p>
<p>The Aqua-compatible build/install types (<code>go_install</code>, <code>go_build_install</code>, <code>cargo</code>) remain unsupported — they require invoking a language toolchain at install time rather than downloading an artifact, which is a different installation model. A follow-up issue tracks that work.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/toolchain-aqua-archive-and-content#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>Atmos is open source on <a href="https://github.com/cloudposse/atmos" target="_blank" rel="noopener noreferrer" class="">GitHub</a>. File issues or open PRs if you hit any tools the registry can't resolve.</p>]]></content:encoded>
            <category>Feature</category>
        </item>
        <item>
            <title><![CDATA[Azure Interactive Browser Authentication]]></title>
            <link>https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/azure-interactive-auth</link>
            <guid>https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/azure-interactive-auth</guid>
            <pubDate>Tue, 04 Aug 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Atmos now supports the azure/interactive provider — the same interactive browser login az login uses (authorization code + PKCE on a localhost redirect). One command, atmos auth login, opens your browser, signs you in, and sets up everything Terraform and the az CLI need.]]></description>
            <content:encoded><![CDATA[<p>Atmos now supports the <code>azure/interactive</code> provider — the same interactive browser login <code>az login</code> uses (authorization code + PKCE on a localhost redirect). One command, <code>atmos auth login</code>, opens your browser, signs you in, and sets up everything Terraform and the <code>az</code> CLI need.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="why-this-matters">Why This Matters<a href="https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/azure-interactive-auth#why-this-matters" class="hash-link" aria-label="Direct link to Why This Matters" title="Direct link to Why This Matters" translate="no">​</a></h2>
<p><strong>Device code is getting blocked</strong>: Microsoft-managed Conditional Access policies now block the device code flow in many tenants (error <code>AADSTS530035</code>), so <code>azure/device-code</code> fails there. The interactive browser flow carries full Conditional Access context, so it keeps working.</p>
<p><strong>One command instead of two</strong>: <code>azure/cli</code> requires a pre-existing <code>az login</code> session. With <code>azure/interactive</code>, <code>atmos auth login</code> is the only command you run.</p>
<p><strong>Silent repeat logins</strong>: Atmos tries silent acquisition from the persisted MSAL cache first. Refresh tokens make repeat logins silent — no browser after the first sign-in.</p>
<p><strong>Drop-in for az login</strong>: Atmos writes the Azure CLI-compatible cache files (MSAL token cache and <code>azureProfile.json</code>), so after <code>atmos auth login</code> the <code>az</code> CLI works without ever running <code>az login</code>. Guest/B2B users are handled correctly using the real MSAL home account ID.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/azure-interactive-auth#how-to-use-it" class="hash-link" aria-label="Direct link to How to Use It" title="Direct link to How to Use It" translate="no">​</a></h2>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token key atrule">auth</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">providers</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">azure-browser</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">kind</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> azure/interactive</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">spec</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">tenant_id</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"12345678-1234-1234-1234-123456789012"</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">subscription_id</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"87654321-4321-4321-4321-210987654321"</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">location</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> eastus</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain" style="display:inline-block"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">identities</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">azure-dev</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">default</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token boolean important" style="color:rgb(255, 88, 116)">true</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">kind</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> azure/subscription</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">via</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">provider</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> azure</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">browser</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">principal</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">subscription_id</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"87654321-4321-4321-4321-210987654321"</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">location</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> eastus</span></span><br></div></code></pre></div></div>
<p>Then authenticate:</p>
<div class="language-shell codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-shell codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A"><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos auth login</span><br></div></code></pre></div></div>
<p>Atmos opens your default browser for sign-in (with MFA if configured), acquires Management, Graph, and Key Vault tokens, and caches them for azurerm, azuread, and azapi. Chain identities via <code>azure/subscription</code> exactly like the other Azure providers.</p>
<p>The spec shape is identical to <code>azure/device-code</code>: <code>tenant_id</code> (required), plus optional <code>subscription_id</code>, <code>location</code>, <code>client_id</code> (defaults to the Azure CLI public client), and <code>cloud_environment</code> (<code>public</code>, <code>usgovernment</code>, or <code>china</code>).</p>
<p>The flow requires an interactive terminal and a browser. For headless environments and CI/CD, keep using <code>azure/oidc</code>; where a browser can't be opened (e.g., SSH sessions), <code>azure/device-code</code> remains available.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/azure-interactive-auth#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<ul>
<li class="">Read the <a class="" href="https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/auth/providers">provider documentation</a> and the <a class="" href="https://pr-2957.atmos-docs.ue2.dev.plat.cloudposse.org/tutorials/azure-authentication">Azure Authentication tutorial</a></li>
<li class="">Report issues on <a href="https://github.com/cloudposse/atmos/issues" target="_blank" rel="noopener noreferrer" class="">GitHub</a></li>
</ul>]]></content:encoded>
            <category>Feature</category>
        </item>
    </channel>
</rss>