<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <id>https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog</id>
    <title>atmos Blog</title>
    <updated>2026-08-11T00:00:00.000Z</updated>
    <generator>https://github.com/jpmonette/feed</generator>
    <link rel="alternate" href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog"/>
    <subtitle>atmos Blog</subtitle>
    <icon>https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/img/atmos-logo.png</icon>
    <entry>
        <title type="html"><![CDATA[See Every Atmos Command That Ran in CI, Without Parsing a Single Log]]></title>
        <id>https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/pro-exec-metadata-upload</id>
        <link href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/pro-exec-metadata-upload"/>
        <updated>2026-08-11T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[A pipeline runs a dozen Atmos commands across a dozen jobs. Something looks off — a plan]]></summary>
        <content type="html"><![CDATA[<p>A pipeline runs a dozen Atmos commands across a dozen jobs. Something looks off — a plan
that should have shown changes didn't, a command that used to take seconds now takes
minutes. The only way to find out what actually happened is to open each CI job, scroll
through raw log output, and reconstruct the timeline by hand. There was no automatic
record of what ran, how long it took, or how much it cost.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/pro-exec-metadata-upload#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>CI logs are the system of record for infrastructure changes, but they're not built for
review. Finding "which command ran against which stack, and did it succeed" means
opening job after job and reading output meant for a terminal, not a dashboard. Resource
usage — how long a command actually took, how much memory it needed — was never
captured at all, so slow pipelines were diagnosed by guesswork.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/pro-exec-metadata-upload#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>When Atmos runs in a recognized CI environment with Atmos Pro configured, it now reports
a lightweight execution record for every command automatically — no extra setup beyond
what you already have. The record covers the Atmos version, the command and its exit
code, and how long it took to run.</p>
<p>Most commands report this in the background and never slow anything down. <code>terraform plan</code>, <code>terraform apply</code>, and <code>describe affected</code> wait briefly to confirm the record
made it to Atmos Pro before the command finishes, so a pipeline never reports success for
a run Atmos Pro never saw — and if delivery is slow or fails, the command still
completes; it only logs a warning.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/pro-exec-metadata-upload#how-to-use-it" class="hash-link" aria-label="Direct link to How to Use It" title="Direct link to How to Use It" translate="no">​</a></h2>
<p>There's nothing to turn on. If Atmos Pro is already configured and Atmos is running in
CI, execution records start flowing immediately.</p>
<p>The only knob is how long a critical command (<code>terraform plan</code>, <code>terraform apply</code>,
<code>describe affected</code>) is willing to wait for Atmos Pro to confirm it received the record
before moving on — 10 seconds by default:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token key atrule">settings</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">pro</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">exec</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">sync_timeout_seconds</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)">20</span></span><br></div></code></pre></div></div>
<p>Raise it if your network to Atmos Pro is slow; the default already covers most setups.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/pro-exec-metadata-upload#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>This is the foundation for richer execution history in Atmos Pro — itemized resource
changes from <code>terraform plan</code>/<code>apply</code> are next. Tell us what you'd want to see in an
execution's timeline. Open an issue or start a discussion at
<a href="https://github.com/cloudposse/atmos" target="_blank" rel="noopener noreferrer" class="">github.com/cloudposse/atmos</a>.</p>]]></content>
        <author>
            <name>Igor Rodionov</name>
            <uri>https://github.com/goruha</uri>
        </author>
        <category label="Atmos Pro" term="Atmos Pro"/>
        <category label="Feature" term="Feature"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Automatic Azure Backend Provisioning for Terraform State]]></title>
        <id>https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/azure-backend-provisioning</id>
        <link href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/azure-backend-provisioning"/>
        <updated>2026-08-09T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Bootstrapping Terraform state on Azure has always meant a detour outside Terraform: before you]]></summary>
        <content type="html"><![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-2926.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-2926.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-2926.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-2926.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-2926.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-2926.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>
        <author>
            <name>Andriy Knysh</name>
            <uri>https://github.com/aknysh</uri>
        </author>
        <category label="Feature" term="Feature"/>
        <category label="DX" term="DX"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Keep Installed AI Skills Up to Date]]></title>
        <id>https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/ai-skill-update</id>
        <link href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/ai-skill-update"/>
        <updated>2026-08-07T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Package managers normally tell you when an installed package is out of date and let you refresh]]></summary>
        <content type="html"><![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-2926.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-2926.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-2926.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-2926.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-2926.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>
        <author>
            <name>Erik Osterman</name>
            <uri>https://github.com/osterman</uri>
        </author>
        <category label="Feature" term="Feature"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Browse, Search, and Copy Any Atmos Agent Skill Before You Install It]]></title>
        <id>https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/agent-skills-directory</id>
        <link href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/agent-skills-directory"/>
        <updated>2026-08-05T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Before you install a skill, you want to read what it does. Atmos agent skills did not let you do that. You]]></summary>
        <content type="html"><![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-2926.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-2926.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-2926.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-2926.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-2926.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-2926.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-2926.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-2926.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>
        <author>
            <name>Erik Osterman</name>
            <uri>https://github.com/osterman</uri>
        </author>
        <category label="Feature" term="Feature"/>
        <category label="DX" term="DX"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Injecting Terraform Values into Kustomize Without Hand-Editing Overlays]]></title>
        <id>https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/kustomize-gitops-delivery</id>
        <link href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/kustomize-gitops-delivery"/>
        <updated>2026-08-05T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Kustomize expects the files it consumes to have exact, reserved names. A remote base or]]></summary>
        <content type="html"><![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-2926.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-2926.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-2926.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-2926.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-2926.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>
        <author>
            <name>Erik Osterman</name>
            <uri>https://github.com/osterman</uri>
        </author>
        <category label="Bug Fix" term="Bug Fix"/>
        <category label="Enhancement" term="Enhancement"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Custom Commands and Workflows Are Now a Complete Task Runner Replacement]]></title>
        <id>https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/taskfile-convergence</id>
        <link href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/taskfile-convergence"/>
        <updated>2026-08-05T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[If you've ever tried to move a Taskfile.yml over to Atmos, you've hit the gap had no]]></summary>
        <content type="html"><![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-2926.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-2926.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-2926.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-2926.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-2926.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-2926.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-2926.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-2926.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-2926.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-2926.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/commands/dependencies">dependencies</a>,
<a class="" href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/workflows/steps/inputs"><code>inputs</code></a>, <a class="" href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/workflows/steps/artifacts"><code>artifacts</code></a>,
<a class="" href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/workflows/steps/preconditions"><code>preconditions</code></a>, and <a class="" href="https://pr-2926.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-2926.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-2926.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>
        <author>
            <name>Erik Osterman</name>
            <uri>https://github.com/osterman</uri>
        </author>
        <category label="Feature" term="Feature"/>
        <category label="DX" term="DX"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Toolchain registry adds github_archive and github_content support]]></title>
        <id>https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/toolchain-aqua-archive-and-content</id>
        <link href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/toolchain-aqua-archive-and-content"/>
        <updated>2026-08-05T00:00:00.000Z</updated>
        <summary type="html"><![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.]]></summary>
        <content type="html"><![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-2926.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-2926.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-2926.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-2926.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-2926.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-2926.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>
        <author>
            <name>Erik Osterman</name>
            <uri>https://github.com/osterman</uri>
        </author>
        <category label="Feature" term="Feature"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Azure Interactive Browser Authentication]]></title>
        <id>https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/azure-interactive-auth</id>
        <link href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/azure-interactive-auth"/>
        <updated>2026-08-04T00:00:00.000Z</updated>
        <summary type="html"><![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.]]></summary>
        <content type="html"><![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-2926.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-2926.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-2926.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-2926.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/auth/providers">provider documentation</a> and the <a class="" href="https://pr-2926.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>
        <author>
            <name>Andriy Knysh</name>
            <uri>https://github.com/aknysh</uri>
        </author>
        <category label="Feature" term="Feature"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Populate a Store From Infrastructure You Already Deployed]]></title>
        <id>https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/hooks-on-terraform-output-and-refresh</id>
        <link href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/hooks-on-terraform-output-and-refresh"/>
        <updated>2026-08-04T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Reference architectures live for years. By the time you wire up a store hook, most of what]]></summary>
        <content type="html"><![CDATA[<p>Reference architectures live for years. By the time you wire up a store hook, most of what
it should cover was already deployed — some of it before hooks existed, some of it by a
process outside Atmos entirely. Store hooks only ran after <code>apply</code>. To get an existing VPC ID
or subnet list into a store, you had to force a fresh <code>apply</code>, or fall back to a manual write
with a cloud CLI.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/hooks-on-terraform-output-and-refresh#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>A <code>kind: store</code> hook reads a Terraform output and writes it to a configured store, so other
components can read it back later with <code>!store</code> or <code>!store.get</code>. Before this change, the
supported lifecycle events did not include <code>output</code> or <code>refresh</code>. Nothing fired when you just
wanted to <em>read</em> a value from infrastructure that already exists.</p>
<p>That gap matters most for the infrastructure you're least likely to touch again soon: a
production VPC someone applied by hand two years ago, or a reference architecture deployed
before your organization adopted hooks at all. Backfilling a store from that infrastructure
meant either re-running <code>apply</code> against something that didn't need to change, or writing the
value into the store yourself, outside Atmos.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/hooks-on-terraform-output-and-refresh#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 fires lifecycle hooks around <code>atmos terraform output</code> and <code>atmos terraform refresh</code>, the same way it already does for <code>plan</code>, <code>apply</code>, and <code>test</code>. A <code>kind: store</code> hook
(or a <code>type: store</code> step run through the <code>kind: step</code> bridge) can bind to
<code>after.terraform.output</code> instead of, or alongside, <code>after.terraform.apply</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">hooks</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">backfill</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">events</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token plain">after.terraform.output</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token plain"></span></span><br></div><div class="token-line 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"> store</span></span><br></div><div class="token-line 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"> prod/ssm</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">outputs</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">vpc_id</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> .id</span></span><br></div></code></pre></div></div>
<p>Running <code>atmos terraform output vpc -s prod</code> now reads the current state and writes <code>vpc_id</code>
into the store — no <code>apply</code> required. <code>before</code>/<code>after.terraform.refresh</code> events fire the same
way around <code>atmos terraform refresh</code>, for hooks that care about reconciling state with the
real infrastructure rather than just reading it.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/hooks-on-terraform-output-and-refresh#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>Scope a store hook to <code>after.terraform.output</code> to backfill values from infrastructure that's
already running:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token key atrule">hooks</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">outputs</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">events</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token plain">after.terraform.output</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token plain"></span></span><br></div><div class="token-line 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"> store</span></span><br></div><div class="token-line 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"> prod/ssm</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">outputs</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">vpc_id</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> .id</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">private_subnet_ids</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> .private_subnet_ids</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 terraform output 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>
<p>Keep an existing <code>after.terraform.apply</code> hook untouched, or list both events on the same hook
so it fires on either command:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token key atrule">hooks</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">outputs</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">events</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token plain">after.terraform.apply</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> after.terraform.output</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token plain"></span></span><br></div><div class="token-line 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"> store</span></span><br></div><div class="token-line 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"> prod/ssm</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">outputs</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">vpc_id</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> .id</span></span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/hooks-on-terraform-output-and-refresh#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>Try binding a store hook to <code>after.terraform.output</code> against infrastructure you didn't apply
through Atmos. Tell us what's missing — an aggregate event for <code>--affected</code>/<code>--all</code> output
runs, or another lifecycle command entirely. Open an issue or start a discussion at
<a href="https://github.com/cloudposse/atmos" target="_blank" rel="noopener noreferrer" class="">github.com/cloudposse/atmos</a>.</p>]]></content>
        <author>
            <name>Erik Osterman</name>
            <uri>https://github.com/osterman</uri>
        </author>
        <category label="Feature" term="Feature"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Read, Write, and Delete Store Values from the CLI and Workflows]]></title>
        <id>https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/store-crud-and-workflow-writes</id>
        <link href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/store-crud-and-workflow-writes"/>
        <updated>2026-08-03T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[A build step often creates a value that a different step needs later. Examples are an image tag, a build number, or a deployment marker. In the past, you had only bad ways to pass this value along. You could write it into Terraform state, where it does not belong. You could run a cloud CLI command by hand. You could also build a custom file-based handoff between steps. Atmos already had a fast way to read any value from a configured store. But Atmos had no supported way to write a value into a store. The only exception was one narrow hook. That hook works only with Terraform output. For every other value, you had to leave Atmos to write it.]]></summary>
        <content type="html"><![CDATA[<p>A build step often creates a value that a different step needs later. Examples are an image tag, a build number, or a deployment marker. In the past, you had only bad ways to pass this value along. You could write it into Terraform state, where it does not belong. You could run a cloud CLI command by hand. You could also build a custom file-based handoff between steps. Atmos already had a fast way to read any value from a configured store. But Atmos had no supported way to write a value into a store. The only exception was one narrow hook. That hook works only with Terraform output. For every other value, you had to leave Atmos to write it.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/store-crud-and-workflow-writes#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>Atmos stores support many backends. Examples are AWS SSM, AWS Secrets Manager, HashiCorp Vault, Azure Key Vault, GCP Secret Manager, Redis, Artifactory, 1Password, Keychain, and GitHub Actions. The <code>!store</code> and <code>!store.get</code> YAML functions can read any value from these stores. But Atmos gave you only two ways to write a value into a store. You could declare the value as a formal secret with <code>atmos secret</code>. Or you could use the one existing store hook. That hook only copies a Terraform output into a store after <code>apply</code> runs. Atmos had no supported way to write other values, such as a Docker image tag from a <code>container</code> build step, a build number, or a deployment marker created mid-workflow. To write one of these values, you had to use the AWS CLI, <code>curl</code>, or a custom shell script in the workflow.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/store-crud-and-workflow-writes#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 has a new CLI command group named <code>atmos store</code>. This command group gives you raw CRUD access to any configured store. Atmos also has a new workflow step named <code>type: store</code>. This step writes a value from a workflow, a custom command, or a hook. Neither the CLI nor the step requires you to declare a value first. Both work directly on any backend listed under <code>stores:</code> in <code>atmos.yaml</code>. You can scope a value to a stack and a component. Or you can omit the stack and component to make the value global.</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 store </span><span class="token builtin class-name" style="color:rgb(255, 203, 139)">set</span><span class="token plain"> app-metadata image_tag sha256:abc123 </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--stack</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">prod </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--component</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">ecs-service</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos store get app-metadata image_tag </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--stack</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">prod </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--component</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">ecs-service</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos store list</span><br></div></code></pre></div></div>
<p>The <code>store</code> step closes the loop with the existing read functions. First, a workflow builds an image and pushes it. Next, the workflow writes the resulting tag to a store. Later, a completely separate deploy run reads the tag back with <code>!store</code> or <code>!store.get</code>. This flow needs no shared Terraform state and no custom scripts.</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"> push</span></span><br></div><div class="token-line 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"> push</span></span><br></div><div class="token-line 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"> myapp</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"> .env.GIT_SHA </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" 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 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"> record</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">tag</span></span><br></div><div class="token-line 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"> store</span></span><br></div><div class="token-line 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"> write</span></span><br></div><div class="token-line 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">store</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> app</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">metadata</span></span><br></div><div class="token-line 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"> image_tag</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">value</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"{{ .steps.push.metadata.digest }}"</span><span class="token plain"></span></span><br></div><div class="token-line 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"> prod</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">component</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> ecs</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">service</span></span><br></div></code></pre></div></div>
<p>The <code>store</code> step is a normal registered step type. Because of this, it also runs as a hook through the existing <code>kind: step</code> bridge. You need no extra configuration to run it after <code>terraform apply</code>.</p>
<p>Atmos allows you to write to a <code>secret: true</code> store on purpose. For example, a step can generate a password and write it straight to a secret backend. Both the CLI and the step support this case. But this write is only a shortcut. It is not a replacement for <code>atmos secret</code>. It skips declaration and scope tracking. When a value must be tracked as a formal secret, use <code>secrets.vars</code> and <code>atmos secret set</code> instead.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/store-crud-and-workflow-writes#how-to-use-it" class="hash-link" aria-label="Direct link to How to Use It" title="Direct link to How to Use It" translate="no">​</a></h2>
<p>Set and read a value scoped to a stack and a component:</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 store </span><span class="token builtin class-name" style="color:rgb(255, 203, 139)">set</span><span class="token plain"> app-metadata image_tag sha256:abc123 </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--stack</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">prod </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--component</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">ecs-service</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos store get app-metadata image_tag </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--stack</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">prod </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--component</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">ecs-service </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>
<p>Delete the value. Then list the configured stores:</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 store delete app-metadata image_tag </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--stack</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">prod </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--component</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">ecs-service</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos store list</span><br></div></code></pre></div></div>
<p>Write a value from a workflow step. Then read the value back in stack configuration for a completely different component:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># workflow</span><span class="token plain"></span></span><br></div><div class="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"> record</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">tag</span></span><br></div><div class="token-line 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"> store</span></span><br></div><div class="token-line 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"> write</span></span><br></div><div class="token-line 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">store</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> app</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">metadata</span></span><br></div><div class="token-line 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"> image_tag</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">value</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"{{ .steps.push.metadata.digest }}"</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 comment" style="color:rgb(99, 119, 119);font-style:italic"># stacks/.../ecs-service.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">vars</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">image_tag</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token tag" style="color:rgb(127, 219, 202)">!store</span><span class="token plain"> app</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">metadata prod ecs</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">service image_tag</span></span><br></div></code></pre></div></div>
<p>Both the command group and the step type are experimental for now. We may change them as we get feedback from users.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/store-crud-and-workflow-writes#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 store</code> and the <code>store</code> step in your own build-to-deploy pipeline. Tell us what is missing. Examples are a matching read step, bulk import and export, or another feature. You can open an issue or start a discussion at <a href="https://github.com/cloudposse/atmos" target="_blank" rel="noopener noreferrer" class="">github.com/cloudposse/atmos</a>.</p>]]></content>
        <author>
            <name>Erik Osterman</name>
            <uri>https://github.com/osterman</uri>
        </author>
        <category label="Feature" term="Feature"/>
        <category label="Experimental" term="Experimental"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Use Tags and Labels with Workflows]]></title>
        <id>https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/workflow-tags-and-labels</id>
        <link href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/workflow-tags-and-labels"/>
        <updated>2026-08-03T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Atmos workflows already supported --stack. They now also support --tags and --labels, forwarding those selectors to every nested type: atmos step.]]></summary>
        <content type="html"><![CDATA[<p>Atmos workflows already supported <code>--stack</code>. They now also support <code>--tags</code> and <code>--labels</code>, forwarding those selectors to every nested <code>type: atmos</code> step.</p>
<p>For an introduction to defining and selecting <a class="" href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/tags-and-labels">tags and labels</a>, see the original feature announcement.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/workflow-tags-and-labels#how-to-use-it" class="hash-link" aria-label="Direct link to How to Use It" title="Direct link to How to Use It" translate="no">​</a></h2>
<p>Use tags and labels on their own:</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 workflow deploy </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--tags</span><span class="token plain"> networking </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--labels</span><span class="token plain"> deployment:dev</span><br></div></code></pre></div></div>
<p><code>--stack</code>, <code>--tags</code>, and <code>--labels</code> are all optional selectors. Combine the ones that define the scope you need:</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 workflow deploy </span><span class="token punctuation" style="color:rgb(199, 146, 234)">\</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--stack</span><span class="token plain"> tenant1-ue2-dev </span><span class="token punctuation" style="color:rgb(199, 146, 234)">\</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--tags</span><span class="token plain"> networking </span><span class="token punctuation" style="color:rgb(199, 146, 234)">\</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--labels</span><span class="token plain"> deployment:dev</span><br></div></code></pre></div></div>
<p>Use the same selectors you already use with normal Atmos commands, while keeping the workflow's ordering, dependencies, parallel steps, and matrix steps intact.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/workflow-tags-and-labels#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>Try tags and labels with the workflows you already use for targeted deployments. If a workflow pattern needs a different selection model, open an issue with the command and component scope you want to express.</p>]]></content>
        <author>
            <name>Zack A</name>
            <uri>https://github.com/zack-is-cool</uri>
        </author>
        <category label="Feature" term="Feature"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Script-Friendly Output for atmos toolchain get]]></title>
        <id>https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/toolchain-get-plain-json-output</id>
        <link href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/toolchain-get-plain-json-output"/>
        <updated>2026-07-31T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Pulling a tool's version into a script usually means scraping decorated terminal output. A checkmark here, a]]></summary>
        <content type="html"><![CDATA[<p>Pulling a tool's version into a script usually means scraping decorated terminal output. A checkmark here, a
color code there, maybe a table row — and now the one-liner that used to grab a version string needs a
regex, a <code>head -1</code>, and a <code>2&gt;&amp;1</code> to work around output that was never meant to be parsed.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/toolchain-get-plain-json-output#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>A CI job that needs a tool's configured version — to pass to another action, or write to
<code>GITHUB_OUTPUT</code> — had to reach for something like:</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 assign-left variable" style="color:rgb(214, 222, 235)">version</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token variable" style="color:rgb(214, 222, 235)">$(</span><span class="token variable" style="color:rgb(214, 222, 235)">atmos toolchain get vale-cli/vale </span><span class="token variable operator file-descriptor important" style="color:rgb(127, 219, 202)">2</span><span class="token variable operator" style="color:rgb(127, 219, 202)">&gt;</span><span class="token variable file-descriptor important" style="color:rgb(214, 222, 235)">&amp;1</span><span class="token variable" style="color:rgb(214, 222, 235)"> </span><span class="token variable operator" style="color:rgb(127, 219, 202)">|</span><span class="token variable" style="color:rgb(214, 222, 235)"> </span><span class="token variable function" style="color:rgb(130, 170, 255)">grep</span><span class="token variable" style="color:rgb(214, 222, 235)"> </span><span class="token variable parameter variable" style="color:rgb(214, 222, 235)">-oE</span><span class="token variable" style="color:rgb(214, 222, 235)"> </span><span class="token variable string" style="color:rgb(173, 219, 103)">'[0-9]+\.[0-9]+\.[0-9]+'</span><span class="token variable" style="color:rgb(214, 222, 235)"> </span><span class="token variable operator" style="color:rgb(127, 219, 202)">|</span><span class="token variable" style="color:rgb(214, 222, 235)"> </span><span class="token variable function" style="color:rgb(130, 170, 255)">head</span><span class="token variable" style="color:rgb(214, 222, 235)"> </span><span class="token variable parameter variable" style="color:rgb(214, 222, 235)">-1</span><span class="token variable" style="color:rgb(214, 222, 235)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token builtin class-name" style="color:rgb(255, 203, 139)">echo</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"version=</span><span class="token string variable" style="color:rgb(214, 222, 235)">$version</span><span class="token string" style="color:rgb(173, 219, 103)">"</span><span class="token plain"> </span><span class="token operator" style="color:rgb(127, 219, 202)">&gt;&gt;</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"</span><span class="token string variable" style="color:rgb(214, 222, 235)">$GITHUB_OUTPUT</span><span class="token string" style="color:rgb(173, 219, 103)">"</span><br></div></code></pre></div></div>
<p>That's a lot of shell just to answer "what version is configured?" — a regex to strip a checkmark and
color codes, <code>head -1</code> because the human-readable view can list more than one line, and <code>2&gt;&amp;1</code> because the
output goes to stderr, not stdout.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/toolchain-get-plain-json-output#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 get</code> now supports a <code>--format</code> flag with two script-friendly output modes alongside the
existing human-readable table: <code>plain</code> prints just the bare version string, and <code>json</code> prints structured
output including whether that version is installed.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/toolchain-get-plain-json-output#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>Grab a version with nothing to parse:</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 get vale-cli/vale </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">plain</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token number" style="color:rgb(247, 140, 108)">2.20</span><span class="token plain">.0</span><br></div></code></pre></div></div>
<p>Which collapses the CI snippet above to:</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 assign-left variable" style="color:rgb(214, 222, 235)">version</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token variable" style="color:rgb(214, 222, 235)">$(</span><span class="token variable" style="color:rgb(214, 222, 235)">atmos toolchain get vale-cli/vale </span><span class="token variable parameter variable" style="color:rgb(214, 222, 235)">--format</span><span class="token variable operator" style="color:rgb(127, 219, 202)">=</span><span class="token variable" style="color:rgb(214, 222, 235)">plain</span><span class="token variable" style="color:rgb(214, 222, 235)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token builtin class-name" style="color:rgb(255, 203, 139)">echo</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"version=</span><span class="token string variable" style="color:rgb(214, 222, 235)">$version</span><span class="token string" style="color:rgb(173, 219, 103)">"</span><span class="token plain"> </span><span class="token operator" style="color:rgb(127, 219, 202)">&gt;&gt;</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"</span><span class="token string variable" style="color:rgb(214, 222, 235)">$GITHUB_OUTPUT</span><span class="token string" style="color:rgb(173, 219, 103)">"</span><br></div></code></pre></div></div>
<p>Ask for more than the version string with <code>--format=json</code>:</p>
<div class="language-shell codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-shell codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A"><div class="token-line" style="color:#d6deeb"><span class="token plain">$ atmos toolchain get terraform </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)">"tool"</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)">"hashicorp/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 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.9.8"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span></span><br></div><div class="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)">"installed"</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)">false</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span></span><br></div></code></pre></div></div>
<p><code>--format=plain</code> only makes sense for a single resolved version, so it's rejected when combined with
<code>--all</code> (which lists every available version) — use <code>--format=json</code> there instead, which returns the full
list with each entry's installed and default status.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/toolchain-get-plain-json-output#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>--format=plain</code> or <code>--format=json</code> the next time you're piping a tool version into a script. If you
run into a <code>toolchain</code> command that still only prints decorated, hard-to-parse output, please
<a href="https://github.com/cloudposse/atmos/issues" target="_blank" rel="noopener noreferrer" class="">open an issue</a> so we can add the same script-friendly modes
there too.</p>]]></content>
        <author>
            <name>Erik Osterman</name>
            <uri>https://github.com/osterman</uri>
        </author>
        <category label="Feature" term="Feature"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Apply a Stack and Everything It Depends On]]></title>
        <id>https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/include-dependencies-closure</id>
        <link href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/include-dependencies-closure"/>
        <updated>2026-07-27T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Standing up an environment is rarely one apply. The stack you actually care about sits on top of prerequisites — a network layer in a shared stack, a database a few components down — and something has to run them first, in the right order. In practice that "something" is usually a bash wrapper --include-dependencies and --include-dependents expand any multi-component selection with its dependency closure and execute it in graph order, and the list commands preview exactly what would run.]]></summary>
        <content type="html"><![CDATA[<p>Standing up an environment is rarely one <code>apply</code>. The stack you actually care about sits on top of prerequisites — a network layer in a shared stack, a database a few components down — and something has to run them first, in the right order. In practice that "something" is usually a bash wrapper: a hand-maintained list of stacks, a loop of <code>atmos terraform apply</code> calls, and a prayer that the ordering comments are still true. Atmos now does this natively: <code>--include-dependencies</code> and <code>--include-dependents</code> expand any multi-component selection with its dependency closure and execute it in graph order, and the <code>list</code> commands preview exactly what would run.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/include-dependencies-closure#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>Atmos has always known the dependency graph — <code>dependencies.components</code> declares what each component needs, and bulk operations like <code>atmos terraform apply --all</code> already execute in topological order. But the <em>selection</em> never followed the edges. Selecting a stack with <code>-s dev</code>, or a set of components with <code>--tags</code> or <code>--labels</code>, ran only what matched; prerequisites living in another stack (or without the matching tag) were silently out of scope. Deploying "dev and everything dev needs" meant knowing the prerequisite chain yourself and scripting around Atmos — exactly the kind of glue the tool exists to remove.</p>
<p>The reverse direction had the same gap: after changing a shared component, running everything that <em>depends on</em> it was only possible through <code>--affected</code>, not from an arbitrary selection.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/include-dependencies-closure#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>Every multi-component terraform selection — <code>--all</code>, <code>--components</code>, <code>--query</code>, <code>-s</code>, <code>--tags</code>, <code>--labels</code>, and <code>--affected</code> — now accepts two closure flags:</p>
<ul>
<li class="">The <code>--include-dependencies[=N]</code> flag expands the selection with everything it depends on (its prerequisites), N levels deep. The bare flag means unlimited depth.</li>
<li class="">The <code>--include-dependents[=N]</code> flag expands in the reverse direction: everything that depends on the selection.</li>
</ul>
<p>Selectors choose the <em>seed</em>; the closure flags <em>expand</em> it. Expanded components execute even when they don't match the selectors — a prerequisite doesn't need your <code>env=dev</code> label to be required by something that has it. Execution stays in dependency order (reverse order for <code>destroy</code>), and cross-stack edges are followed: <code>apply --all -s dev --include-dependencies</code> will run a prerequisite in <code>core</code> before the components in <code>dev</code>.</p>
<p>The same flags work on <code>atmos list components</code>, <code>atmos list stacks</code>, and <code>atmos list instances</code>, so you can see the exact set a bulk run would execute before running it.</p>
<p>Scoping stays lazy: Atmos first walks a lightweight structural graph to find the closure, then fully evaluates (templates, YAML functions, authentication) only the stacks the closure actually touches. An unrelated account's unreachable backend still can't break your deploy.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/include-dependencies-closure#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>Apply everything labeled for dev, plus all of its prerequisites, in dependency order:</p>
<div class="language-shell codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-shell codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A"><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos terraform apply </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--all</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--labels</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">env</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">dev --include-dependencies</span><br></div></code></pre></div></div>
<p>Bound the expansion to one dependency level:</p>
<div class="language-shell codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-shell codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A"><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos terraform plan </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--all</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--tags</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">app --include-dependencies</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>Tear down a component and everything that depends on it (dependents are destroyed 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 terraform destroy </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--components</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">vpc </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-s</span><span class="token plain"> dev --include-dependents</span><br></div></code></pre></div></div>
<p>Preview the execution set without running anything:</p>
<div class="language-shell codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-shell codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A"><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos list components </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--labels</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">env</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">dev --include-dependencies</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos list stacks </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--labels</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">env</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">dev --include-dependencies</span><br></div></code></pre></div></div>
<p>A few things to know:</p>
<ul>
<li class="">Using <code>--include-dependencies</code> with <code>destroy</code> also destroys <em>shared</em> prerequisites of your selection — components other stacks may still rely on. Atmos warns when you combine them.</li>
<li class="">Because <code>metadata.tags</code> and <code>metadata.labels</code> now drive scoping decisions <em>before</em> evaluation, they are selectors by design: plain strings, simple templates, and local functions like <code>!env</code>, <code>!git.*</code>, and <code>!include</code> are allowed, but values that require authentication or execution (<code>!terraform.state</code>, <code>!store</code>, <code>!exec</code>, <code>atmos.Component</code>, ...) are rejected with an error. This contract is enforced for every component whenever stacks are enumerated — by <code>describe</code>, <code>list</code>, and bulk terraform commands — even when no selector flag is used and the component is outside the current stack filter, so an existing impure value fails fast rather than surfacing later as a confusing scoping bug. The error names the offending component and stack manifest. Move those values into <code>vars</code> or <code>settings</code> instead — or, if you need time to migrate, set <code>describe.settings.eager_evaluation: true</code> in <code>atmos.yaml</code> to restore the previous full-evaluation behavior (see the <a class="" href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/describe">describe configuration</a> reference).</li>
<li class="">If you already combine <code>--affected --include-dependents</code> with <code>--tags</code> or <code>--labels</code>, note the semantics changed: previously the tag/label filter also removed non-matching dependents from the expanded set; now selectors narrow only the <em>seed</em> and closure members are retained regardless. That is the whole point of closure expansion — but it does mean such runs can now include more components than before.</li>
<li class="">The depth value must be attached with <code>=</code> (for example <code>--include-dependencies=2</code>). On the terraform commands a bare <code>--include-dependencies</code> followed by a separate value is also accepted, so take care that a following positional argument isn't consumed as the depth — Atmos rejects non-numeric values loudly rather than guessing.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/include-dependencies-closure#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 closure flags on your own dependency graph and tell us where the semantics surprise you — especially around <code>destroy</code> ordering and depth bounds. Issues and discussions are open at <a href="https://github.com/cloudposse/atmos" target="_blank" rel="noopener noreferrer" class="">github.com/cloudposse/atmos</a>.</p>]]></content>
        <author>
            <name>Erik Osterman</name>
            <uri>https://github.com/osterman</uri>
        </author>
        <category label="Feature" term="Feature"/>
        <category label="DX" term="DX"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Stack-Wide Metadata Defaults: Set Labels and Tags Once]]></title>
        <id>https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/global-metadata-defaults</id>
        <link href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/global-metadata-defaults"/>
        <updated>2026-07-25T12:00:00.000Z</updated>
        <summary type="html"><![CDATA[Most components in a stack share the same cost center label or the same compliance-scope tag. vars, env, and settings can all be declared once at the stack level and inherited by every component. metadata couldn't — every component had to repeat the same labels/tags, and a metadata: block placed at the top of a stack file was silently ignored.]]></summary>
        <content type="html"><![CDATA[<p>Most components in a stack share the same cost center label or the same compliance-scope tag. <code>vars</code>, <code>env</code>, and <code>settings</code> can all be declared once at the stack level and inherited by every component. <code>metadata</code> couldn't — every component had to repeat the same <code>labels</code>/<code>tags</code>, and a <code>metadata:</code> block placed at the top of a stack file was silently ignored.</p>
<p>Stack manifests can now declare stack-wide metadata defaults that every component inherits, with the component's own <code>metadata:</code> still free to override them.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/global-metadata-defaults#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>Shared metadata meant duplicated metadata.</strong> If every component in a stack carries the same <code>cost-center</code> label or the same compliance tag, that block had to be copy-pasted into every component definition, and kept in sync by hand as components were added.</li>
<li class=""><strong>A stack-level <code>metadata:</code> block looked like it should work, and didn't.</strong> Unlike <code>vars</code>/<code>env</code>/<code>settings</code>, a <code>metadata:</code> key at the root of a stack manifest was accepted but never applied — it silently did nothing, which is worse than a validation error.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/global-metadata-defaults#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>A stack manifest can now declare a stack-wide <code>metadata:</code> default that's deep-merged into every component's own metadata:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockTitle_JJ7b">stacks/orgs/acme/prod/_defaults.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">metadata</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">labels</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">cost-center</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> platform</span></span><br></div></code></pre></div></div>
<p>Only the fields that make sense as shared defaults are allowed here: <code>labels</code>, <code>tags</code>, <code>custom</code>, <code>enabled</code>, <code>locked</code>, and <code>terraform_workspace_pattern</code>. Component-identity fields — <code>component</code>, <code>inherits</code>, <code>type</code>, <code>name</code>, <code>terraform_workspace</code> — stay component-only, and setting one of these at the stack level is now a clear validation error instead of a silent no-op.</p>
<p>Precedence runs lowest to highest: stack-wide default → the component's <code>metadata.inherits</code> base-component chain → the component's own local <code>metadata:</code> block, which always wins:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockTitle_JJ7b">stacks/orgs/acme/prod/network.yaml</div><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token key atrule">components</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">terraform</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">vpc</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">metadata</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">labels</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">          </span><span class="token key atrule">cost-center</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> network</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">team </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># overrides the stack-wide default for this component</span></span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/global-metadata-defaults#how-to-use-it" class="hash-link" aria-label="Direct link to How to Use It" title="Direct link to How to Use It" translate="no">​</a></h2>
<p>Combine a stack-wide default with the <code>!labels</code>/<code>!tags</code> YAML functions (see <a class="" href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/tags-and-labels">Tags and Labels</a>) to feed a shared label set into every component's Terraform variables without repeating it:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockTitle_JJ7b">stacks/orgs/acme/prod/_defaults.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">metadata</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">labels</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">Namespace</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> eg</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">Environment</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> prod</span></span><br></div></code></pre></div></div>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockTitle_JJ7b">stacks/orgs/acme/prod/network.yaml</div><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token key atrule">components</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">terraform</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">vpc</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">vars</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">tags</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token tag" style="color:rgb(127, 219, 202)">!labels</span><span class="token plain">   </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># var.tags (map) &lt;- stack-wide metadata.labels, unless this component overrides them</span></span><br></div></code></pre></div></div>
<p>The same mechanism also covers <code>enabled</code>/<code>locked</code>/<code>custom</code>/<code>terraform_workspace_pattern</code>, for cases like decommissioning an entire legacy stack without editing every component individually:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockTitle_JJ7b">stacks/orgs/acme/legacy/_defaults.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">metadata</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">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)">false</span><span class="token plain"> </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># decommission every component in this stack</span></span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/global-metadata-defaults#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>Stack-wide metadata covers the fields that behave like shared defaults today. If there's another <code>metadata</code> field you'd want to set once for a whole stack, open an issue with your use case.</p>]]></content>
        <author>
            <name>Erik Osterman</name>
            <uri>https://github.com/osterman</uri>
        </author>
        <category label="Feature" term="Feature"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Split One Logical Stack Across Focused Manifests]]></title>
        <id>https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/parent-scoped-multi-file-stacks</id>
        <link href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/parent-scoped-multi-file-stacks"/>
        <updated>2026-07-25T12:00:00.000Z</updated>
        <summary type="html"><![CDATA[Large stacks eventually turn into a shared bottleneck. Network, platform, and]]></summary>
        <content type="html"><![CDATA[<p>Large stacks eventually turn into a shared bottleneck. Network, platform, and
application owners all need to contribute components, but putting every change
in one manifest makes reviews noisy and parent-level configuration easy to
accidentally share.</p>
<p>Atmos now lets multiple top-level manifests represent one logical stack while
keeping each manifest's components and parent scope independent.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/parent-scoped-multi-file-stacks#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>Teams often organize shared catalog imports and component instances by who owns
them. Before this change, splitting one logical environment across parent
manifests meant commands treated those files as separate stacks, or required a
single large manifest that mixed unrelated scope and ownership.</p>
<p>That made it difficult to divide ownership without also changing how teams
named, discovered, and operated the stack.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/parent-scoped-multi-file-stacks#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>Atmos recognizes parent manifests with the same stack identity as one logical
stack for discovery and component selection. Each manifest still resolves its
own imports, globals, and component configuration, so values from one parent
do not leak into another.</p>
<p>Within that logical stack:</p>
<ul>
<li class="">Distinct components from every parent appear together in stack discovery.</li>
<li class="">Equivalent duplicate components choose a stable, lexical canonical source.</li>
<li class="">Conflicting duplicate components remain errors with the parent manifests
identified in the diagnostic.</li>
<li class="">Inheritance stays self-contained: a base must be defined inline or explicitly
imported by the parent that uses it.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/parent-scoped-multi-file-stacks#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>Give the related parent manifests the same stack identity through <code>name</code>,
<code>name_template</code>, or <code>name_pattern</code>. For example, two manifests can use the same
template-derived environment and stage:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># stacks/catalog/shared.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">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">chatops-base</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">metadata</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">component</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> mock</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">vars</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">notifications_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>
<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"># stacks/parents/01-network.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">vars</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">environment</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">stage</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> shared</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain" style="display:inline-block"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain"></span><span class="token key atrule">components</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">terraform</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">dns-primary</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">metadata</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">component</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> mock</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 comment" style="color:rgb(99, 119, 119);font-style:italic"># stacks/parents/02-platform.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">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"> catalog/shared</span></span><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">vars</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">environment</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">stage</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> shared</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain" style="display:inline-block"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain"></span><span class="token key atrule">components</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">terraform</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">chatops</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">metadata</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">component</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> mock</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">inherits</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="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"> chatops</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">base</span></span><br></div></code></pre></div></div>
<p>With a matching stack name configuration, <code>atmos describe stacks</code> reports one
logical stack, while <code>atmos describe component chatops -s dev-shared</code> retains
the platform parent's scope and resolves its base through the platform
manifest's explicit catalog import. A component defined only by the network
parent is discoverable in the logical stack, but is not an implicit inheritance
dependency of the platform parent.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/parent-scoped-multi-file-stacks#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>Try splitting a large logical stack along your team's ownership boundaries. If
you encounter an import, inheritance, or duplicate-resolution case that is not
clear, please <a href="https://github.com/cloudposse/atmos/issues" target="_blank" rel="noopener noreferrer" class="">open an issue</a> with
a minimal stack example.</p>]]></content>
        <author>
            <name>Erik Osterman</name>
            <uri>https://github.com/osterman</uri>
        </author>
        <category label="Feature" term="Feature"/>
        <category label="Enhancement" term="Enhancement"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Terraform state migrations with tfmigrate]]></title>
        <id>https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/terraform-tfmigrate</id>
        <link href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/terraform-tfmigrate"/>
        <updated>2026-07-24T12:00:00.000Z</updated>
        <summary type="html"><![CDATA[Refactoring Terraform code leaves state behind. Rename a resource, or move it between root modules, and every plan shows a destroy-and-recreate for infrastructure that never changed. You can fix this by hand with terraform state mv, but that command only fixes one workspace at a time. It is easy to get wrong, and no one can review it before it runs.]]></summary>
        <content type="html"><![CDATA[<p>Refactoring Terraform code leaves state behind. Rename a resource, or move it between root modules, and every plan shows a destroy-and-recreate for infrastructure that never changed. You can fix this by hand with <code>terraform state mv</code>, but that command only fixes one workspace at a time. It is easy to get wrong, and no one can review it before it runs.</p>
<p><a href="https://github.com/minamijoyo/tfmigrate" target="_blank" rel="noopener noreferrer" class=""><code>tfmigrate</code></a> turns these state changes into migration files that you store under version control. Atmos runs these files for you — manually from the CLI, or automatically from Terraform lifecycle hooks — in the same component context as <code>atmos terraform plan</code> and <code>apply</code>.</p>
<div class="language-shell codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-shell codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A"><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos terraform migrate plan s3-bucket </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-s</span><span class="token plain"> plat-ue2-dev</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos terraform migrate apply s3-bucket </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-s</span><span class="token plain"> plat-ue2-dev</span><br></div></code></pre></div></div>
<div class="window_X9dN"><div class="titlebar_DN7h"><span class="dots_R2sg" aria-hidden="true"><i></i><i></i><i></i></span><span class="title_Dael">atmos terraform migrate</span></div><pre class="screen__b5c noPreWrap_ImkX screenLoading_abuO"><span> </span></pre><div class="controls_eyLV"><button type="button" class="playButton_kD9r" aria-label="Pause cast"><svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 24 24" aria-hidden="true" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M6 5H8V19H6V5ZM16 5H18V19H16V5Z"></path></svg></button><input aria-label="Cast position" type="range" min="0" max="0" step="0.01" value="0"><span>00:00.0<!-- --> / <!-- -->00:00.0</span></div></div>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="what-changed">What Changed<a href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/terraform-tfmigrate#what-changed" class="hash-link" aria-label="Direct link to What Changed" title="Direct link to What Changed" translate="no">​</a></h2>
<p>The new <code>atmos terraform migrate</code> command family adds:</p>
<ul>
<li class=""><code>atmos terraform migrate plan</code> to preview a migration.</li>
<li class=""><code>atmos terraform migrate apply</code> to apply a migration.</li>
<li class=""><code>atmos terraform migrate list</code> to inspect per-component hook and history context.</li>
<li class=""><code>kind: tfmigrate</code> hooks for running migrations from Terraform lifecycle events.</li>
<li class="">Zero-config history storage that reuses the component's Terraform backend.</li>
</ul>
<p>Before <code>tfmigrate</code> runs, Atmos performs the normal Terraform component setup.
This includes auth identity resolution, source provisioning, workdir
provisioning, generated backend and varfiles, Terraform init, and workspace
selection.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="dynamic-hooks">Dynamic Hooks<a href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/terraform-tfmigrate#dynamic-hooks" class="hash-link" aria-label="Direct link to Dynamic Hooks" title="Direct link to Dynamic Hooks" translate="no">​</a></h2>
<p><code>kind: tfmigrate</code> hooks default to <code>mode: dynamic</code>, so automation follows the
Terraform operation:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token key atrule">hooks</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">state-migration</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">events</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="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"> before.terraform.plan</span></span><br></div><div class="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"> before.terraform.apply</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">kind</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> tfmigrate</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">mode</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> dynamic</span></span><br></div></code></pre></div></div>
<p><code>before.terraform.plan</code> runs <code>tfmigrate plan</code>. <code>before.terraform.apply</code> and
<code>before.terraform.deploy</code> run <code>tfmigrate apply</code>. Use static <code>mode: plan</code> or
<code>mode: apply</code> when a hook must always run one action.</p>
<p>Hooks run through Atmos, so they use the same identity as the Terraform
operation. If the Terraform command or component selects an Atmos auth
identity, the migration gets that same authenticated environment.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="recovering-from-skipped-releases">Recovering From Skipped Releases<a href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/terraform-tfmigrate#recovering-from-skipped-releases" class="hash-link" aria-label="Direct link to Recovering From Skipped Releases" title="Direct link to Recovering From Skipped Releases" translate="no">​</a></h2>
<p>Provider removals are where this bites hardest. When a component release drops
a provider configuration, every workspace that skips the intermediate release
gets stuck. The state still holds resources from the removed provider, and
Terraform refuses to plan:</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">Error: Provider configuration not present</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">To work with random_pet.legacy (orphan) its original provider configuration</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">at provider["registry.opentofu.org/hashicorp/random"].legacy is required,</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">but it has been removed.</span><br></div></code></pre></div></div>
<p>Until now, the only fix was manual, and per workspace: restore a temporary
provider override, apply, then delete the override again. Ship a migration
alongside the release instead. The hook prunes the stale state entries before
Terraform loads provider configurations, so workspaces can jump straight to
the newest release:</p>
<div class="language-hcl codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-hcl 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">migration </span><span class="token string" style="color:rgb(173, 219, 103)">"state"</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"drop_legacy_provider_state"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span></span><br></div><div class="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)">actions</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 punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token string" style="color:rgb(173, 219, 103)">"rm random_pet.legacy"</span><span class="token plain">,</span></span><br></div><div class="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><br></div><div class="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>Note: <code>state rm</code> abandons the remote object. It does not destroy it. This is
usually what you want for provider-cleanup migrations. If you need to destroy
the object, destroy it before you upgrade, or temporarily restore the
provider configuration.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="history-mode">History Mode<a href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/terraform-tfmigrate#history-mode" class="hash-link" aria-label="Direct link to History Mode" title="Direct link to History Mode" translate="no">​</a></h2>
<p>For idempotent migrations in automation, use <code>tfmigrate</code> history mode:</p>
<div class="language-shell codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-shell codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A"><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos terraform migrate apply s3-bucket </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-s</span><span class="token plain"> plat-ue2-dev</span><br></div></code></pre></div></div>
<p>History mode needs no configuration by default. Atmos looks for a custom
<code>tfmigrate</code> config in four places: the hook's <code>config</code> field, the
<code>--tfmigrate-config</code> / <code>ATMOS_TFMIGRATE_CONFIG</code> flag or environment variable,
the <code>TFMIGRATE_CONFIG</code> environment variable, and a <code>.tfmigrate.hcl</code> file in
the component. If none of these exist, Atmos generates a config on the fly.</p>
<p>The generated config stores migration history in the component's own
Terraform backend. For an S3 or GCS backend, Atmos reuses the same bucket as
the state. It stores history under a key namespaced by stack, component, and
workspace, and it inherits the region, role ARN, and endpoint. For a local
backend, Atmos stores the history file beside the state file.</p>
<p>Atmos records every applied migration and never reruns it. You don't need to
set anything up.</p>
<p>To take control, provide your own config. Drop a <code>.tfmigrate.hcl</code> file in the
component, set the hook's <code>config</code> field, or pass <code>--tfmigrate-config</code> /
<code>ATMOS_TFMIGRATE_CONFIG</code>. Atmos exports stack, component, and
workspace-scoped history variables, and copies the supported Terraform
backend settings. Your custom config can then reuse the same bucket and
identity setup:</p>
<div class="language-hcl codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-hcl 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 keyword" style="color:rgb(127, 219, 202)">tfmigrate</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span></span><br></div><div class="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)">migration_dir</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 string" style="color:rgb(173, 219, 103)">"./tfmigrate"</span><span class="token plain"></span></span><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 keyword" style="color:rgb(127, 219, 202)">history</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    storage </span><span class="token string" style="color:rgb(173, 219, 103)">"s3"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span></span><br></div><div class="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)">bucket</span><span class="token plain">   </span><span class="token punctuation" style="color:rgb(199, 146, 234)">=</span><span class="token plain"> env.ATMOS_TFMIGRATE_HISTORY_BUCKET</span></span><br></div><div class="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)">key</span><span class="token plain">      </span><span class="token punctuation" style="color:rgb(199, 146, 234)">=</span><span class="token plain"> env.ATMOS_TFMIGRATE_HISTORY_KEY</span></span><br></div><div class="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)">region</span><span class="token plain">   </span><span class="token punctuation" style="color:rgb(199, 146, 234)">=</span><span class="token plain"> env.ATMOS_TFMIGRATE_HISTORY_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 plain">      </span><span class="token property" style="color:rgb(128, 203, 196)">role_arn</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">=</span><span class="token plain"> env.ATMOS_TFMIGRATE_HISTORY_ROLE_ARN</span></span><br></div><div class="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><br></div><div class="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><br></div><div class="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>The default history key is:</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">tfmigrate/&lt;stack&gt;/&lt;component&gt;/&lt;workspace&gt;/history.json</span><br></div></code></pre></div></div>
<p>That keeps multiple Atmos component instances from colliding when they share a
Terraform backend bucket.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="important-limitation">Important Limitation<a href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/terraform-tfmigrate#important-limitation" class="hash-link" aria-label="Direct link to Important Limitation" title="Direct link to Important Limitation" translate="no">​</a></h2>
<p>Single-file <code>tfmigrate apply path.hcl</code> is not idempotent by itself. A rerun
can fail if a state address already moved or was removed. Prefer history mode
instead. When the component's backend is S3 or GCS, the generated default
gives you durable storage automatically. With a purely local backend, make
sure the local history file survives between runs — for example, have your CI
workflow persist it.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="learn-more">Learn More<a href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/terraform-tfmigrate#learn-more" class="hash-link" aria-label="Direct link to Learn More" title="Direct link to Learn More" translate="no">​</a></h2>
<ul>
<li class=""><a class="" href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/terraform/migrate"><code>atmos terraform migrate</code></a></li>
<li class=""><a class="" href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/stacks/hooks">Hooks</a></li>
<li class=""><a class="" href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/components/terraform">Terraform Component Configuration</a></li>
</ul>]]></content>
        <author>
            <name>Erik Osterman</name>
            <uri>https://github.com/osterman</uri>
        </author>
        <category label="Feature" term="Feature"/>
        <category label="DX" term="DX"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Native Pull Requests for Vendored Component Updates]]></title>
        <id>https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/component-updater-pull-requests</id>
        <link href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/component-updater-pull-requests"/>
        <updated>2026-07-21T12:00:00.000Z</updated>
        <summary type="html"><![CDATA[Keeping vendored components current across dozens of repositories doesn't scale as a manual habit.]]></summary>
        <content type="html"><![CDATA[<p>Keeping vendored components current across dozens of repositories doesn't scale as a manual habit.
Someone has to notice a new upstream release, edit the right <code>version:</code> field without breaking a
comment or a template, then commit, push, and open a pull request. That has to happen for every
component, on some kind of schedule, forever. Most teams either let it slip until something forces
an update, or bolt on a third-party GitHub Action just to automate the commit-and-PR part.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/component-updater-pull-requests#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>The <code>atmos vendor update</code> command already finds and writes newer versions locally. Turning that
into a reviewable pull request meant scripting Git branch/commit/push logic and a GitHub API client
yourself, or reaching for an external action with its own permissions model, its own config format,
and its own release cadence to track.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/component-updater-pull-requests#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>The <code>--pull-request</code> flag does the whole cycle natively: discover available updates, write them
with the same format-preserving editor <code>vendor update</code> already uses, create or reuse a branch,
commit, push, and open or update a pull request — through a provider-neutral Git registry (GitHub
today; GitLab and Bitbucket can register without any command changes).</p>
<div class="language-shell codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-shell codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A"><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos vendor update --pull-request</span><br></div></code></pre></div></div>
<p>Nothing happens unless there's actually an update: no updates means no branch, no commit, no push,
no PR. Atmos fetches the base branch but never writes to it. It reuses an existing feature branch
for the same scope and pushes it fast-forward only — repeated runs update the same PR instead of
piling up duplicates.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/component-updater-pull-requests#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>Scope updates to a named group instead of updating everything at once:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token key atrule">vendor</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">update</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">groups</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">platform</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">include</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)">"terraform/vpc"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"terraform/eks/*"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">exclude</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token string" style="color:rgb(173, 219, 103)">"terraform/eks/legacy"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">ci</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">pull_request</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">branch_prefix</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> atmos/component</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">updater</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">title</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"chore(components): update {{ .scope.name }}"</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">labels</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token plain">component</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">update</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span></span><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 vendor update </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--group</span><span class="token plain"> platform --pull-request</span><br></div></code></pre></div></div>
<p>For a scheduled run, the official container image is all a workflow needs — no third-party action
performs the update, commit, push, or PR creation:</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">on</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">schedule</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 class="token key atrule">cron</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)">"17 3 * * 1"</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">permissions</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">contents</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> write</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">pull-requests</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> write</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain"></span><span class="token key atrule">jobs</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">update</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">runs-on</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> ubuntu</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">latest</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">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">image</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> ghcr.io/cloudposse/atmos</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"> vars.ATMOS_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"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">steps</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> </span><span class="token key atrule">uses</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> actions/checkout@v6</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> </span><span class="token key atrule">run</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> atmos vendor update </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">pull</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">request</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><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"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> </span><span class="token key atrule">GITHUB_TOKEN</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"> secrets.GITHUB_TOKEN </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 class="token punctuation" style="color:rgb(199, 146, 234)">}</span></span><br></div></code></pre></div></div>
<p>Set <code>execution.mode: worktree</code> when you'd rather the whole discover-branch-commit-push cycle ran in
an isolated checkout instead of the workflow's own working tree — useful if other steps in the same
job depend on an unmodified checkout while the update runs. In GitHub Actions, every run also
appends a summary showing scope, counts, and the resulting PR link, independent of whether an
update was found.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="triggering-downstream-workflows">Triggering Downstream Workflows<a href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/component-updater-pull-requests#triggering-downstream-workflows" class="hash-link" aria-label="Direct link to Triggering Downstream Workflows" title="Direct link to Triggering Downstream Workflows" translate="no">​</a></h2>
<p>The example above uses the default <code>GITHUB_TOKEN</code>. This token is fine for opening the PR, but
GitHub deliberately excludes its own default Actions token from re-triggering <code>on: pull_request</code>/
<code>on: push</code> workflows. As a result, a plan/validate workflow that's supposed to run against the new
PR won't fire.</p>
<p>Pair the Component Updater with the
<a class="" href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/auth#github-sts-atmos-pro"><code>github/sts</code></a> auth integration to get a token that
does trigger downstream Actions — a just-in-time GitHub App installation token, minted through
<a class="" href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/atmos-pro-github-sts">Atmos Pro STS</a> and exported as <code>ATMOS_PRO_GITHUB_TOKEN</code>. The
<code>--pull-request</code> flag already prefers this token over <code>GITHUB_TOKEN</code>:</p>
<div class="language-shell codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-shell codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A"><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos 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"> github-sts -- atmos vendor update --pull-request</span><br></div></code></pre></div></div>
<p>No other flags or config changes are required. <code>atmos auth exec</code> mints and exports the token for
the wrapped command's environment. The Component Updater's GitHub client picks it up automatically.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/component-updater-pull-requests#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>Questions about scopes, groups, or CI publishing are welcome in the
<a href="https://github.com/cloudposse/atmos" target="_blank" rel="noopener noreferrer" class="">Atmos GitHub repository</a> and the community Slack.</p>]]></content>
        <author>
            <name>Erik Osterman</name>
            <uri>https://github.com/osterman</uri>
        </author>
        <category label="Feature" term="Feature"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Verify Vendored Files Never Silently Drift]]></title>
        <id>https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/vendor-lock-verify</id>
        <link href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/vendor-lock-verify"/>
        <updated>2026-07-21T12:00:00.000Z</updated>
        <summary type="html"><![CDATA[Vendoring pulls external code into your own repository so it's reviewable, diffable, and not]]></summary>
        <content type="html"><![CDATA[<p>Vendoring pulls external code into your own repository so it's reviewable, diffable, and not
subject to an upstream registry going away. But once those files land on disk, nothing has watched
them since. A teammate edits a vendored file directly to work around a bug. A pull can interrupt
partway through. CI reuses a runner's disk across jobs. Every one of these leaves your checkout
silently out of sync with what Atmos actually vendored. The first sign of trouble is usually a
broken <code>terraform plan</code> weeks later — not the moment the drift happened.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/vendor-lock-verify#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>The <code>atmos vendor pull</code> command always re-fetches everything, every time, whether or not anything
actually changed. That makes it slow to lean on as a drift check, so most teams just don't run it that
way — they trust the checkout and find out otherwise the hard way. There was also no way to answer
"does what's on disk still match what was vendored" without a network round trip, and no way to
choose how loudly a stale checkout should complain before Atmos quietly re-fetches it.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/vendor-lock-verify#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>Every <code>atmos vendor pull</code> now records a <code>vendor.lock.yaml</code> receipt for each vendored source: its
declared origin, a resolved identity, and a checksum for every file it wrote. That receipt is what
<code>atmos vendor verify</code> checks against, with zero network access:</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 verify</span><br></div></code></pre></div></div>
<div class="language-text codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-text codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A"><div class="token-line" style="color:#d6deeb"><span class="token plain">COMPONENT  PATH                              REASON</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">vpc        components/terraform/vpc/main.tf  checksum mismatch</span><br></div></code></pre></div></div>
<p>It exits non-zero the moment anything doesn't match — a missing file or a modified one — so it
drops straight into a CI gate. Add <code>--component &lt;name&gt;</code> to scope the check, or <code>--format json</code> for
machine-readable output.</p>
<p>You also get to choose how a drifted checkout behaves on the next <code>atmos vendor pull</code>, instead of
always silently re-fetching:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token key atrule">vendor</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">lock</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">enforcement</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> warn </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># silent | warn | strict</span></span><br></div></code></pre></div></div>
<ul>
<li class="">The <code>silent</code> mode re-fetches with no reporting — the behavior every <code>vendor pull</code> had before this
existed.</li>
<li class="">The <code>warn</code> mode (the default) re-fetches and prints one line naming what drifted and why.</li>
<li class="">The <code>strict</code> mode refuses to run at all until you pass <code>--refresh-lock</code>, so an unreviewed local
edit can never get silently overwritten — or silently kept — without someone noticing.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/vendor-lock-verify#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>Gate CI on drift the same way you'd gate on any other check:</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 verify </span><span class="token operator" style="color:rgb(127, 219, 202)">||</span><span class="token plain"> </span><span class="token builtin class-name" style="color:rgb(255, 203, 139)">exit</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">1</span><br></div></code></pre></div></div>
<p>Override enforcement for a single invocation without touching <code>atmos.yaml</code>:</p>
<div class="language-shell codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-shell codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A"><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos vendor pull --lock-enforcement</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">strict</span><br></div></code></pre></div></div>
<p>And when a source genuinely needs to move — not just recover from drift — <code>version:</code> can now be a
semver range instead of only an exact pin:</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">sources</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="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">component</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> vpc</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">source</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> github.com/cloudposse/terraform</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">aws</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">vpc.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">version</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.0.0"</span></span><br></div></code></pre></div></div>
<p>The first <code>atmos vendor pull</code> resolves that range to a concrete tag and locks it there — every
later pull reuses the locked version with no network call at all, until an explicit
<code>atmos vendor update</code> or <code>--refresh-lock</code> re-resolves it. An exact pin like <code>version: v1.5.0</code>
behaves exactly as it always has: the manifest itself remains the single source of truth for what
gets fetched.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/vendor-lock-verify#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>Questions about lock enforcement, <code>vendor verify</code>, or version ranges are welcome in the
<a href="https://github.com/cloudposse/atmos" target="_blank" rel="noopener noreferrer" class="">Atmos GitHub repository</a> and the community Slack.</p>]]></content>
        <author>
            <name>Erik Osterman</name>
            <uri>https://github.com/osterman</uri>
        </author>
        <category label="Feature" term="Feature"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Remote Build Caching for Container Builds]]></title>
        <id>https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/container-buildx-cache-and-driver</id>
        <link href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/container-buildx-cache-and-driver"/>
        <updated>2026-07-20T12:00:00.000Z</updated>
        <summary type="html"><![CDATA[Container image builds get slower as a Dockerfile grows, and CI runners rarely keep a warm]]></summary>
        <content type="html"><![CDATA[<p>Container image builds get slower as a Dockerfile grows, and CI runners rarely keep a warm
local cache between runs. Teams work around this with a handful of <code>docker/setup-buildx-action</code>
and <code>docker/build-push-action</code> steps that provision a builder and wire up a remote cache — glue
that lives outside the rest of the pipeline and has to be reproduced in every workflow that builds
an image.</p>
<p>The native <code>container</code> build step can now provision that builder and cache directly, so a build's
caching strategy lives next to the rest of its configuration instead of in separate Actions.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/container-buildx-cache-and-driver#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>A <code>docker buildx build</code> that starts cold rebuilds every layer, even when nothing meaningful
changed. Reusing a remote cache and a purpose-built builder solves this, but doing it by hand
means composing several pieces: creating a builder with the right driver, pointing it at a
registry-backed cache, and keeping all of that in sync with the rest of the build step.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/container-buildx-cache-and-driver#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p><code>action: build</code> now accepts <code>driver</code> and <code>cache</code>:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> build</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">type</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> container</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">action</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> build</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">provider</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> docker</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">with</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">engine</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> buildx</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">context</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> .</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">dockerfile</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> Dockerfile</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">tags</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> registry.example.com/app</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain">latest</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain" style="display:inline-block"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">driver</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> docker</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">container   </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># shorthand — just the driver</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain" style="display:inline-block"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">cache</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">from</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> </span><span class="token key atrule">type</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> registry</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">          </span><span class="token key atrule">ref</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> registry.example.com/app</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain">buildcache</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">to</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> </span><span class="token key atrule">type</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> registry</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">          </span><span class="token key atrule">ref</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> registry.example.com/app</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain">buildcache</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">          </span><span class="token key atrule">mode</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> max</span></span><br></div></code></pre></div></div>
<p>Atmos creates the named builder if it doesn't already exist and reuses it on later runs, so the
builder's own cache persists across builds on the same host instead of starting cold every time.
<code>driver</code> also accepts a full form when you need driver-specific options, such as pointing Buildx
at a mirrored BuildKit image to avoid Docker Hub rate limits:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token key atrule">with</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">driver</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> atmos</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">provider</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> docker</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">container</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">opts</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">image</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> mirror.gcr.io/moby/buildkit</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain">buildx</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">stable</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token number" style="color:rgb(247, 140, 108)">1</span></span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/container-buildx-cache-and-driver#how-to-use-it" class="hash-link" aria-label="Direct link to How to Use It" title="Direct link to How to Use It" translate="no">​</a></h2>
<p>Add <code>driver</code> and <code>cache</code> under an existing <code>action: build</code> step wherever you use
<code>engine: buildx</code>. If you build with <code>bake</code> instead, keep <code>cache-from</code>/<code>cache-to</code> in the bake file
itself — Bake already supports them natively — and use <code>driver</code> for builder selection either way.</p>
<p>See the <a class="" href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/workflows/steps/type/container#driver"><code>container</code> step documentation</a> for the full
field reference, including the three ways to avoid Docker Hub rate limits.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/container-buildx-cache-and-driver#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>Try <code>driver</code> and <code>cache</code> in a build step and share feedback through
<a href="https://github.com/cloudposse/atmos/issues" target="_blank" rel="noopener noreferrer" class="">GitHub issues</a>.</p>]]></content>
        <author>
            <name>Erik Osterman</name>
            <uri>https://github.com/osterman</uri>
        </author>
        <category label="Feature" term="Feature"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Validate Only What Changed]]></title>
        <id>https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/affected-validation</id>
        <link href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/affected-validation"/>
        <updated>2026-07-18T12:00:00.000Z</updated>
        <summary type="html"><![CDATA[Large repositories often have validation rules that are useful but expensive or]]></summary>
        <content type="html"><![CDATA[<p>Large repositories often have validation rules that are useful but expensive or
noisy to run across every file on every pull request. That makes it tempting to
skip validation exactly when a focused signal would be most helpful.</p>
<p>Atmos can now validate the files affected by a change, so pull requests get
actionable feedback without rechecking unrelated project inputs.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/affected-validation#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>Configuration schema checks, stack validation, formatting rules, and workflow
linting protect different parts of a project. Running every check over an entire
repository can obscure the result that matters to the change under review.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/affected-validation#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>Add <code>--affected</code> to the project-wide validator or to an individual validator.
Atmos compares the current worktree with the Git merge-base, including local
uncommitted and untracked files. In GitHub Actions, it reads the pull request
base SHA automatically.</p>
<div class="language-shell codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-shell codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A"><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos validate </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--affected</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--format</span><span class="token plain"> rich</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos validate config </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--affected</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--base</span><span class="token plain"> origin/main</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos config validate </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--affected</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--base</span><span class="token plain"> origin/main</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos validate stacks </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--affected</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--base</span><span class="token plain"> origin/main</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos stack validate </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--affected</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--base</span><span class="token plain"> origin/main</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos validate editorconfig </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--affected</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--base</span><span class="token plain"> origin/main</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos validate ci </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--affected</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--base</span><span class="token plain"> origin/main</span><br></div></code></pre></div></div>
<p>Schema and EditorConfig checks validate changed inputs directly. Changes to a
schema or rule configuration expand validation to the relevant full set. Stack
validation runs whenever stack or Atmos configuration inputs change, preserving
import and duplicate-component checks. Workflow validation sends only changed
workflows to actionlint unless its configuration changes.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/affected-validation#how-to-use-it" class="hash-link" aria-label="Direct link to How to Use It" title="Direct link to How to Use It" translate="no">​</a></h2>
<p>Use the new <code>Validation (affected)</code> GitHub Actions job as a model for a project
workflow. Check out enough Git history for the merge-base, then run the command
with rich output:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> </span><span class="token key atrule">uses</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> actions/checkout@v6</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">with</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">fetch-depth</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> </span><span class="token key atrule">run</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> atmos validate </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">affected </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">format rich</span></span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-2926.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/affected-validation#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>Try affected validation in your pull request workflow and share feedback through
<a href="https://github.com/cloudposse/atmos/issues" target="_blank" rel="noopener noreferrer" class="">GitHub issues</a>.</p>]]></content>
        <author>
            <name>Erik Osterman</name>
            <uri>https://github.com/osterman</uri>
        </author>
        <category label="Feature" term="Feature"/>
        <category label="DX" term="DX"/>
    </entry>
</feed>