<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <id>https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog</id>
    <title>atmos Blog</title>
    <updated>2026-10-20T00:00:00.000Z</updated>
    <generator>https://github.com/jpmonette/feed</generator>
    <link rel="alternate" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog"/>
    <subtitle>atmos Blog</subtitle>
    <icon>https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/img/atmos-logo.png</icon>
    <entry>
        <title type="html"><![CDATA[Experimental Gomplate Function Support]]></title>
        <id>https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/gomplate-experimental-functions</id>
        <link href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/gomplate-experimental-functions"/>
        <updated>2026-10-20T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Gomplate's experimental functions are now available in Atmos stack manifests.]]></summary>
        <content type="html"><![CDATA[<p>Gomplate's experimental functions are now available in Atmos stack manifests.
Network calculations can be expressed in stack templates, reducing hardcoded CIDRs and IP
addresses across environments.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/gomplate-experimental-functions#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>net.CIDRSubnets</code> and <code>net.CIDRHost</code> functions calculate subnet CIDRs and host IP addresses
from each environment's parent CIDR, reducing hardcoded addresses across stacks. Both functions require
Gomplate's experimental mode, but Atmos previously provided no option to enable it in stack
templates.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/gomplate-experimental-functions#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>The Gomplate configuration now includes an <a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/templates#settings"><code>experimental</code> option</a>
for enabling experimental functions in stack templates. It defaults to <code>false</code> and can be set
globally or overridden per stack.</p>
<p>Import templates use the global value from <code>atmos.yaml</code>. The option does not apply to document
generation or scaffold templates.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/gomplate-experimental-functions#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>Enable experimental Gomplate functions in your project configuration:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockTitle_JJ7b">atmos.yaml</div><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token key atrule">templates</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">settings</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">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 class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">gomplate</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">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 class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">experimental</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token boolean important" style="color:rgb(255, 88, 116)">true</span></span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_cA1_" id="calculate-subnet-cidrs-and-host-ip-addresses">Calculate Subnet CIDRs and Host IP Addresses<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/gomplate-experimental-functions#calculate-subnet-cidrs-and-host-ip-addresses" class="hash-link" aria-label="Direct link to Calculate Subnet CIDRs and Host IP Addresses" title="Direct link to Calculate Subnet CIDRs and Host IP Addresses" translate="no">​</a></h3>
<p>The following stack derives subnet CIDRs and a host IP address from one parent CIDR. It assumes
a Terraform component named <code>network</code> with <code>cidr_block</code>, <code>subnet_cidrs</code>, and <code>service_ip</code> inputs:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockTitle_JJ7b">stacks/deploy/dev.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">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">stage</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" 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">network</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line 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">cidr_block</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)">"10.42.0.0/16"</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">subnet_cidrs</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">          </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"{{ index (net.CIDRSubnets 2 .vars.cidr_block) 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 string" style="color:rgb(173, 219, 103)">"{{ index (net.CIDRSubnets 2 .vars.cidr_block) 1 }}"</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">service_ip</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"{{ net.CIDRHost 10 (index (net.CIDRSubnets 2 .vars.cidr_block) 1) }}"</span></span><br></div></code></pre></div></div>
<p>The call to <code>net.CIDRSubnets 2</code> adds two prefix bits, splitting the <code>/16</code> into four <code>/18</code> subnets.
The zero-based <code>index</code> calls select the first two subnets. <code>net.CIDRHost 10</code> calculates the address
at offset 10 in the second subnet. The network inputs resolve to:</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">cidr_block</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> 10.42.0.0/16</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain"></span><span class="token key atrule">subnet_cidrs</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="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"> 10.42.0.0/18</span></span><br></div><div class="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"> 10.42.64.0/18</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain"></span><span class="token key atrule">service_ip</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> 10.42.64.10</span></span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_cA1_" id="override-per-stack">Override per Stack<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/gomplate-experimental-functions#override-per-stack" class="hash-link" aria-label="Direct link to Override per Stack" title="Direct link to Override per Stack" translate="no">​</a></h3>
<p>To disable experimental functions for a stack while keeping them enabled globally:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockTitle_JJ7b">Stack manifest</div><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token key atrule">settings</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">templates</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">settings</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">gomplate</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">experimental</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token boolean important" style="color:rgb(255, 88, 116)">false</span></span><br></div></code></pre></div></div>
<p>Stacks inherit the global value when this option is omitted. An explicit <code>false</code> disables
experimental functions for that stack, even when they are enabled globally.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/gomplate-experimental-functions#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>For questions or feedback, please open a <a href="https://github.com/cloudposse/atmos/issues" target="_blank" rel="noopener noreferrer" class="">GitHub issue</a>.</p>]]></content>
        <author>
            <name>hashfunc</name>
            <uri>https://github.com/hashfunc</uri>
        </author>
        <category label="Enhancement" term="Enhancement"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Try Runnable Examples Directly from the Documentation]]></title>
        <id>https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/try-runnable-examples</id>
        <link href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/try-runnable-examples"/>
        <updated>2026-10-20T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Reading about a feature should lead directly to trying it. Finding its example directory,]]></summary>
        <content type="html"><![CDATA[<p>Reading about a feature should lead directly to trying it. Finding its example directory,
installing Atmos, and assembling the first commands adds unnecessary work. Changelog posts
with runnable examples, command documentation, and individual example pages now include a quick start
with installation instructions and copyable commands.</p>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="try-it-out">Try it out<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/try-runnable-examples#try-it-out" class="hash-link" aria-label="Direct link to Try it out" title="Direct link to Try it out" translate="no">​</a></h2>
<div class="example_jMgJ"><div class="theme-tabs-container tabs-container tabList_oBn1"><ul role="tablist" aria-orientation="horizontal" class="tabs"><li role="tab" tabindex="-1" aria-selected="false" class="tabs__item tabItem_A3p1">Install Atmos</li><li role="tab" tabindex="0" aria-selected="true" class="tabs__item tabItem_A3p1 tabs__item--active">Try the example</li></ul><div class="margin-top--md"><div role="tabpanel" class="tabItem_gg6W" hidden=""><div class="install-widget install-widget--docs"><div class="install-widget__content"><div class="install-widget__select-wrapper"><span class="install-widget__label">Quick Install</span><select class="install-widget__select" aria-label="Installation method"><option value="0" selected="">Quick Install</option><option value="1">macOS</option><option value="2">Windows</option><option value="3">Docker</option></select><svg class="install-widget__chevron" width="12" height="8" viewBox="0 0 12 8" fill="none"><path d="M1 1.5L6 6.5L11 1.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path></svg></div><div class="install-widget__command"><code class="install-widget__code"><span class="install-widget__command-curl">curl -fsSL</span> <span class="install-widget__command-url">https://atmos.tools/install.sh</span> | <span class="install-widget__command-bash">bash</span></code></div><button class="install-widget__copy" type="button" aria-label="Copy installation command" title="Copy to clipboard"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="5" y="5" width="9" height="9" rx="1" stroke="currentColor" stroke-width="1.5"></rect><path d="M3 11V3C3 2.44772 3.44772 2 4 2H11" stroke="currentColor" stroke-width="1.5"></path></svg></button></div></div><div class="links_ZD8T"><a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/install">Installation guide →</a><a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/examples/policies">Explore the example →</a></div></div><div role="tabpanel" class="tabItem_gg6W"><p>Copy the example into a new directory and make it your 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 init examples/policies</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)">cd</span><span class="token plain"> policies</span><br></div></code></pre></div></div><p>Validate the local policy bundle and run its offline fixtures. No Terraform installation or cloud
credentials are required:</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 policy check</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos policy </span><span class="token builtin class-name" style="color:rgb(255, 203, 139)">test</span><span class="token plain"> tests/cases.json</span><br></div></code></pre></div></div><div class="links_ZD8T"><a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/examples/policies">Explore the example →</a><a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/init#examples-and-source-directories">Initialization and repository settings</a></div></div></div></div></div>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-it-works">How it works<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/try-runnable-examples#how-it-works" class="hash-link" aria-label="Direct link to How it works" title="Direct link to How it works" translate="no">​</a></h2>
<p>Each quick start opens on the example tab, with copyable commands to initialize a complete project
and try the feature. The <strong>Install Atmos</strong> tab is there when you need it. Related examples share
one installation tab and have their own named tabs.</p>
<h3 class="anchor anchorTargetStickyNavbar_cA1_" id="policy-validation-output">Policy validation output<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/try-runnable-examples#policy-validation-output" class="hash-link" aria-label="Direct link to Policy validation output" title="Direct link to Policy validation output" translate="no">​</a></h3>
<p>The <a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/policy#check">policy check command</a> now shows a readable summary on stderr.
<strong>Scripts consuming its previous JSON output must use <code>atmos policy check --format json</code></strong>, which
preserves the <code>valid</code>, <code>rules</code>, and <code>hooks</code> fields on stdout.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/try-runnable-examples#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>Tell us which examples would help you in <a href="https://github.com/cloudposse/atmos/discussions" target="_blank" rel="noopener noreferrer" class="">GitHub Discussions</a>.</p>]]></content>
        <author>
            <name>Erik Osterman</name>
            <uri>https://github.com/osterman</uri>
        </author>
        <category label="Documentation" term="Documentation"/>
        <category label="Enhancement" term="Enhancement"/>
        <category label="DX" term="DX"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[CLI-config imports you can require, scope, and trust]]></title>
        <id>https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/cli-config-import-dx</id>
        <link href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/cli-config-import-dx"/>
        <updated>2026-10-19T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Sharing one team's CLI configuration across many repositories is a common setup: keep developer-tooling]]></summary>
        <content type="html"><![CDATA[<p>Sharing one team's CLI configuration across many repositories is a common setup: keep developer-tooling
config (AI assistants, MCP servers, toolchain pins) in a single source-of-truth repo, and have every other
repo pull it in with a remote import so it is edited in one place. It works - until you try to adopt it
safely. A fragment that quietly fails to load leaves its settings out with nothing but a warning. There is no
way to say "this one must load." A tooling fragment meant for your laptop gets resolved by an automated
<code>apply</code> holding deploy credentials. And an import pinned to a branch silently absorbs the upstream repo's
edits on every run.</p>
<!-- -->
<div><div class="window_X9dN"><div class="titlebar_DN7h"><span class="dots_R2sg" aria-hidden="true"><i></i><i></i><i></i></span><span class="title_Dael">atmos describe config imports</span></div><pre class="screen__b5c noPreWrap_ImkX screenLoading_abuO"><span> </span></pre><div class="controls_eyLV" data-cast-controls="true"><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 class="time_lEbH">00:00.0<!-- --> / <!-- -->00:00.0</span></div></div><div class="castActions_M13G"><div class="container_zGFV"><div class="group_ncGU" role="group" aria-label="Share this demo"><button type="button" class="primary_hpkh" title="Copy a link to this demo" aria-live="polite"><svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" class="icon_P_nE" aria-hidden="true" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><circle cx="18" cy="5" r="3"></circle><circle cx="6" cy="12" r="3"></circle><circle cx="18" cy="19" r="3"></circle><line x1="8.59" y1="13.51" x2="15.42" y2="17.49"></line><line x1="15.41" y1="6.51" x2="8.59" y2="10.49"></line></svg><span>Share</span></button><button type="button" class="caret_pPxC" aria-expanded="false" aria-label="More share options" title="More share options"><svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" class="icon_P_nE" aria-hidden="true" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><polyline points="6 9 12 15 18 9"></polyline></svg></button></div></div><div class="container_EXko"><button type="button" class="trigger_WxG7" aria-expanded="false" aria-label="Download cast"><svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" class="icon_LbC3" aria-hidden="true" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline points="7 10 12 15 17 10"></polyline><line x1="12" y1="15" x2="12" y2="3"></line></svg><span>Download</span><svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" class="icon_LbC3" aria-hidden="true" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><polyline points="6 9 12 15 18 9"></polyline></svg></button></div></div></div>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/cli-config-import-dx#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>Top-level CLI-config imports - the <code>import:</code> list in <code>atmos.yaml</code> and the auto-discovered <code>.atmos.d</code>
fragments - were a plain list of strings, and every entry was implicitly optional. If an import could not be
resolved or merged, Atmos logged a warning and kept going. That is the right default for a nice-to-have
overlay, but it is exactly wrong for a fragment that constrains behavior - for example, a read-only tool
allowlist that limits what the Atmos MCP server is permitted to do. A silent failure there leaves the tool
running without its guardrail.</p>
<p>The string-only model also left no room to express intent: no way to mark an import required, no way to scope
an import to workstations versus CI, and no signal when a remote import was pinned to a mutable ref. The usual
workaround for the CI problem was to keep the fragment out of the committed config entirely - gitignored
behind a <code>*.yaml.example</code> template that nobody could actually use.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/cli-config-import-dx#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>Each entry in the <a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/imports"><code>import:</code></a> list now accepts an object form alongside the
familiar string form, bringing CLI-config imports toward parity with the object model that
<a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/stacks/imports">stack-manifest imports</a> already have. The two forms mix freely, and string entries behave
exactly as before.</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockTitle_JJ7b">atmos.yaml</div><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token key atrule">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 comment" style="color:rgb(99, 119, 119);font-style:italic"># String form: OPTIONAL (fail open) - a failed import is warned and skipped. Unchanged.</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"configs.d/base-settings.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" style="display:inline-block"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Object form: REQUIRED by default (fail closed) - a failed import aborts the load.</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> </span><span class="token key atrule">path</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"git::https://github.com/acme/shared-config.git//.atmos.d/mcp.yaml?ref=v1.2.3"</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">skip_if_missing</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token boolean important" style="color:rgb(255, 88, 116)">false</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain" style="display:inline-block"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># Conditional: resolve on workstations, skip in CI.</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> </span><span class="token key atrule">path</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"configs.d/local-tooling.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">when</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> local</span></span><br></div></code></pre></div></div>
<p>This closes four gaps at once:</p>
<ul>
<li class=""><strong><a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/imports#optional-vs-required-imports">Optional vs required</a>.</strong> A string entry stays
optional (warn and skip). An object entry is required by default - a failed resolve or merge aborts
configuration loading. Set <code>skip_if_missing: true</code> to opt an object entry back into warn-and-skip. Make the
fragment that matters fail closed, so a missing or malformed guardrail stops the run instead of silently
disappearing.</li>
<li class=""><strong><a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/imports#conditional-imports">Conditional loading</a>.</strong> A per-import <code>when: local</code> or
<code>when: ci</code> condition decides whether the import is resolved at all. Developer-tooling config stays committed
and active for developers while auto-skipping in CI, so an automated <code>apply</code> never resolves a cross-repo
remote import - no gitignore/<code>.example</code> workaround required. For anything beyond local-vs-CI, <code>when</code> also
accepts a CEL expression - authored as a quoted <code>"!cel ..."</code> string - that can read the process environment
through the <code>env</code> map, so an import can be gated on any variable you set.</li>
<li class=""><strong><a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/mcp">Optional MCP servers</a>.</strong> A server in a shared <code>mcp.servers</code> config can set
<code>optional: true</code>. When its <code>identity</code> cannot be resolved in the active auth context - for example a
central-logging reader that only some repos define - Atmos skips that server with a warning instead of
failing the others.</li>
<li class=""><strong><a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/imports#pin-remote-imports">Pin warnings</a>.</strong> Atmos now warns when a <code>git::</code> import is
pinned to a mutable ref (a branch, or no <code>?ref=</code> at all), recommending a commit SHA or version tag - the
config-import analogue of catching an unpinned GitHub Action at author time.</li>
</ul>
<p>Everything here is additive. String entries, servers without <code>optional</code>, and unpinned imports all behave
exactly as they did before - the pin check is a warning, not an error.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/cli-config-import-dx#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>Mark a security-bearing fragment required, and scope a developer-tooling fragment to local:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockTitle_JJ7b">.atmos.d/shared.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">import</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> </span><span class="token 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)">"git::https://github.com/acme/shared-config.git//.atmos.d/mcp.yaml?ref=v1.2.3"</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">skip_if_missing</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"># must load, or the run stops</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> </span><span class="token key atrule">path</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"git::https://github.com/acme/shared-config.git//.atmos.d/ai.yaml?ref=v1.2.3"</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">when</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> local                              </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># workstations only</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> </span><span class="token key atrule">path</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"configs.d/prod-overrides.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">when</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'!cel env.DEPLOY_ENV == "prod"'</span><span class="token plain">    </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># dynamic: only when DEPLOY_ENV=prod</span></span><br></div></code></pre></div></div>
<p>Share one MCP config across repos that do not all define the same identities:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockTitle_JJ7b">atmos.yaml</div><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token key atrule">mcp</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">servers</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">central-logs</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line 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"> uvx</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">args</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)">"awslabs.cloudwatch-mcp-server@latest"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token plain"></span></span><br></div><div class="token-line 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"> </span><span class="token string" style="color:rgb(173, 219, 103)">"central-logging"</span><span class="token plain">   </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># defined only in some consumer repos</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">optional</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 class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># skip with a warning where unavailable</span></span><br></div></code></pre></div></div>
<p>A runnable walkthrough lives in the <a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/examples/cli-config-imports"><code>cli-config-imports</code> example</a>, including
how to see conditional loading differ between a workstation and CI, and how a required import fails closed.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="try-it-out">Try it out<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/cli-config-import-dx#try-it-out" class="hash-link" aria-label="Direct link to Try it out" title="Direct link to Try it out" translate="no">​</a></h2>
<div class="example_jMgJ"><div class="theme-tabs-container tabs-container tabList_oBn1"><ul role="tablist" aria-orientation="horizontal" class="tabs"><li role="tab" tabindex="-1" aria-selected="false" class="tabs__item tabItem_A3p1">Install Atmos</li><li role="tab" tabindex="0" aria-selected="true" class="tabs__item tabItem_A3p1 tabs__item--active">Try the example</li></ul><div class="margin-top--md"><div role="tabpanel" class="tabItem_gg6W" hidden=""><div class="install-widget install-widget--docs"><div class="install-widget__content"><div class="install-widget__select-wrapper"><span class="install-widget__label">Quick Install</span><select class="install-widget__select" aria-label="Installation method"><option value="0" selected="">Quick Install</option><option value="1">macOS</option><option value="2">Windows</option><option value="3">Docker</option></select><svg class="install-widget__chevron" width="12" height="8" viewBox="0 0 12 8" fill="none"><path d="M1 1.5L6 6.5L11 1.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path></svg></div><div class="install-widget__command"><code class="install-widget__code"><span class="install-widget__command-curl">curl -fsSL</span> <span class="install-widget__command-url">https://atmos.tools/install.sh</span> | <span class="install-widget__command-bash">bash</span></code></div><button class="install-widget__copy" type="button" aria-label="Copy installation command" title="Copy to clipboard"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="5" y="5" width="9" height="9" rx="1" stroke="currentColor" stroke-width="1.5"></rect><path d="M3 11V3C3 2.44772 3.44772 2 4 2H11" stroke="currentColor" stroke-width="1.5"></path></svg></button></div></div><div class="links_ZD8T"><a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/install">Installation guide →</a><a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/examples/cli-config-imports">Explore the example →</a></div></div><div role="tabpanel" class="tabItem_gg6W"><p>Copy the example into a new directory and make it your 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 init examples/cli-config-imports</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)">cd</span><span class="token plain"> cli-config-imports</span><br></div></code></pre></div></div><p>Inspect the configuration assembled from the example's imports.</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 describe config </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--format</span><span class="token plain"> yaml</span><br></div></code></pre></div></div><div class="links_ZD8T"><a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/examples/cli-config-imports">Explore the example →</a><a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/init#examples-and-source-directories">Initialization and repository settings</a></div></div></div></div></div>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/cli-config-import-dx#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>This landed from <a href="https://github.com/cloudposse/atmos/issues/3430" target="_blank" rel="noopener noreferrer" class="">issue #3430</a>. If you share CLI config
across repositories, try the object form and let us know what else should reach parity with stack imports -
open an issue or start a discussion on <a href="https://github.com/cloudposse/atmos" target="_blank" rel="noopener noreferrer" class="">GitHub</a>.</p>]]></content>
        <author>
            <name>Andriy Knysh</name>
            <uri>https://github.com/aknysh</uri>
        </author>
        <category label="Feature" term="Feature"/>
        <category label="DX" term="DX"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Custom Authentication Providers with Native Plugins]]></title>
        <id>https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/native-auth-plugins</id>
        <link href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/native-auth-plugins"/>
        <updated>2026-10-19T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Organizations with their own identity provider or credential broker need to connect that login flow to their infrastructure commands. Native Atmos plugins let teams implement the provider in Go, distribute a compiled release using any OCI registry, and use it through the same authentication commands as built-in providers.]]></summary>
        <content type="html"><![CDATA[<p>Organizations with their own identity provider or credential broker need to connect that login flow to their infrastructure commands. Native Atmos plugins let teams implement the provider in Go, distribute a compiled release using any OCI registry, and use it through the same authentication commands as built-in providers.</p>
<!-- -->
<div><div class="window_X9dN"><div class="titlebar_DN7h"><span class="dots_R2sg" aria-hidden="true"><i></i><i></i><i></i></span><span class="title_Dael">Native OIDC plugin: create, publish, install, verify</span></div><pre class="screen__b5c noPreWrap_ImkX screenLoading_abuO"><span> </span></pre><div class="controls_eyLV" data-cast-controls="true"><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 class="time_lEbH">00:00.0<!-- --> / <!-- -->00:00.0</span></div></div><div class="castActions_M13G"><div class="container_zGFV"><div class="group_ncGU" role="group" aria-label="Share this demo"><button type="button" class="primary_hpkh" title="Copy a link to this demo" aria-live="polite"><svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" class="icon_P_nE" aria-hidden="true" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><circle cx="18" cy="5" r="3"></circle><circle cx="6" cy="12" r="3"></circle><circle cx="18" cy="19" r="3"></circle><line x1="8.59" y1="13.51" x2="15.42" y2="17.49"></line><line x1="15.41" y1="6.51" x2="8.59" y2="10.49"></line></svg><span>Share</span></button><button type="button" class="caret_pPxC" aria-expanded="false" aria-label="More share options" title="More share options"><svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" class="icon_P_nE" aria-hidden="true" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><polyline points="6 9 12 15 18 9"></polyline></svg></button></div></div><div class="container_EXko"><button type="button" class="trigger_WxG7" aria-expanded="false" aria-label="Download cast"><svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" class="icon_LbC3" aria-hidden="true" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline points="7 10 12 15 17 10"></polyline><line x1="12" y1="15" x2="12" y2="3"></line></svg><span>Download</span><svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" class="icon_LbC3" aria-hidden="true" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><polyline points="6 9 12 15 18 9"></polyline></svg></button></div></div></div>
<p>The recording creates and builds the Go starter, validates its exported capabilities, publishes it to an ephemeral local OCI registry, then lists the configured discovery source, demonstrates explicit JSON output, searches for and installs the release, and inspects the installed plugin. It runs the installed command and repeats the OIDC conformance suite against the downloaded executable, then searches the cached index after stopping the registry. Authentication uses local mock issuer and credential broker endpoints; it does not contact a customer's identity provider or publish to an external registry.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/native-auth-plugins#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>Custom authentication usually includes more than obtaining a token: browser interaction, verification, credential exchange, secure caching, refresh, and logout all need to work together. A team should be able to own its provider-specific behavior while continuing to use Atmos identities and credential chains.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/native-auth-plugins#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>The experimental <a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/plugin/usage">plugin commands</a> provide scaffolding, testing, OCI distribution, explicit installation, and locked restoration. The Go OIDC starter includes browser login with PKCE, verified tokens, an access-token exchange for temporary AWS credentials, cached reuse, refresh, and logout. Its broker identity can feed a built-in AWS assume-role identity.</p>
<p>The generated <a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/plugin/test">conformance suite</a> runs against local mock endpoints. Live integration steps are explicit and separate, so a passing mock test is never presented as evidence that a customer's issuer has been validated.</p>
<p><a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/policies/plugins">Plugin policies</a> let organizations restrict registries and approve specific packages using CEL or Starlark. The same rules apply to installation and cached activation, alongside signature and trusted publisher requirements.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/native-auth-plugins#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>Start with the <a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/plugin/create">plugin scaffold</a>, <a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/plugin/build">build it</a>, and run its fixtures:</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 plugin create ./corporate-oidc </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--kind</span><span class="token plain"> acme/oidc </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--module</span><span class="token plain"> example.com/acme/oidc </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--defaults</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)">cd</span><span class="token plain"> corporate-oidc</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos build</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos </span><span class="token builtin class-name" style="color:rgb(255, 203, 139)">test</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos dev registry up</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos push</span><br></div></code></pre></div></div>
<p>The scaffold includes these custom commands in <code>atmos.yaml</code>, plus a local OCI emulator and repository discovery configuration. Search builds and caches an
index from repository metadata; plugin releases publish independently. Optional catalogs provide
curated snapshots for larger collections and can be scoped to products or teams. Local pushes require Docker but no registry credentials. Stop the ephemeral registry with
<code>atmos dev registry down</code>. Use <code>atmos push --to &lt;repository&gt;</code> for a remote destination; configure
its identity and run <code>atmos auth login --identity publisher</code> when authentication is required.</p>
<p>Follow the generated README to register a native application with your issuer and configure the broker contract. To try the build in a consumer project, point the package at the plugin directory with <code>path</code> in a <a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/profiles">profile</a> of your own. Any profile name works, and the committed configuration and lock keep describing the release:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockTitle_JJ7b">profiles/my-local-build/atmos.yaml</div><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token key atrule">plugins</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><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 key atrule">corporate</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line 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"> /absolute/path/to/corporate</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">oidc</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 </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--profile</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">my-local-build plugin run corporate --</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--profile</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">my-local-build auth login </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--identity</span><span class="token plain"> broker</span><br></div></code></pre></div></div>
<p>A package with <code>path</code> runs the directory in place: nothing is fetched, locked, or checked for a signature, and Atmos warns each time it starts the plugin. Rebuild and the next command runs the new executable, with no reinstall. Without the profile, the same project uses the release. The <a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/tutorials/plugin-development">plugin development tutorial</a> covers the whole loop, including policy for local builds.</p>
<p>For distribution, <a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/plugin/pack">pack</a> and <a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/plugin/publish">publish</a> prebuilt executables to an OCI registry. Declared packages install automatically when a command needs one of their exports, such as an authentication provider. First use outside CI creates a missing lock entry; CI refuses to, so commit the consumer's package declaration and lockfile. Later uses restore that exact digest without selecting upgrades. Verified cached packages require no registry access.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/native-auth-plugins#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>Try the <a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/plugin/usage#create-a-working-oidc-plugin">OIDC walkthrough</a> with a dedicated test application and broker. Native auth providers, auth identities, and command exports are the first supported capabilities; additional Atmos primitives and scripting runtimes remain future work.</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[Step Templates Now Honor Your Configured Delimiters]]></title>
        <id>https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/step-templates-honor-delimiters</id>
        <link href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/step-templates-honor-delimiters"/>
        <updated>2026-10-19T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[The templates.settings.delimiters setting changes the delimiters that Atmos]]></summary>
        <content type="html"><![CDATA[<p>The <a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/templates#configure-templating"><code>templates.settings.delimiters</code></a> setting changes the delimiters that Atmos
templates use, but it only ever reached stack manifests. Workflow, custom command, and lifecycle hook steps kept
parsing <code>{{ }}</code> no matter what you configured. A project that moved to <code>[[ ]]</code> to keep Go-template-looking text such
as a <code>docker inspect --format '{{.State.Status}}'</code> argument out of the template engine still had to mark each of
those step fields <code>!literal</code>, or fail with a template error.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/step-templates-honor-delimiters#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>Configure custom delimiters once:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockTitle_JJ7b">atmos.yaml</div><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token key atrule">templates</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">settings</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">delimiters</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)">"[["</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"]]"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span></span><br></div></code></pre></div></div>
<p>Stack manifests then render <code>[[ .vars.stage ]]</code>. A step in a <a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/workflows">workflow</a>, a
<a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/commands/steps">custom command</a>, or a <a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/stacks/hooks">lifecycle hook</a> ignored the setting and
still rendered <code>{{ .steps.first.value }}</code>. One project could therefore have two template syntaxes depending on where
a value was written.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/step-templates-honor-delimiters#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>Step templates now use the configured delimiters. With the configuration above:</p>
<ul>
<li class=""><code>[[ .steps.first.value ]]</code> renders in a step field.</li>
<li class=""><code>{{ .steps.first.value }}</code> stays literal text, so shell commands and scripts can contain it unchanged.</li>
</ul>
<p>This covers the template fields of every step in workflows, custom commands, and lifecycle hooks, including the
children of <code>parallel</code> and <code>matrix</code> steps and the multi-pass rendering that protects flag values from being rendered a
second time.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/step-templates-honor-delimiters#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>A custom command using the configured delimiters:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockTitle_JJ7b">atmos.yaml</div><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token key atrule">templates</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">settings</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">delimiters</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)">"[["</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"]]"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token plain"></span></span><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">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"> show</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">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"> first</span></span><br></div><div class="token-line 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"> 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"> echo first</span></span><br></div><div class="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"> </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)">          echo "got [[ .steps.first.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)">          docker inspect --format '{{.State.Status}}' my-container</span></span><br></div></code></pre></div></div>
<p>The second step prints <code>got first</code> and passes <code>{{.State.Status}}</code> to Docker as written.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="compatibility">Compatibility<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/step-templates-honor-delimiters#compatibility" class="hash-link" aria-label="Direct link to Compatibility" title="Direct link to Compatibility" translate="no">​</a></h2>
<p>This change is selected by your <a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/edition#behavior-changes">edition</a>, as of <code>2026-10-19</code>:</p>
<ul>
<li class=""><strong>Before:</strong> workflow, custom command, and hook step templates always used <code>{{ }}</code>, even when
<code>templates.settings.delimiters</code> was set.</li>
<li class=""><strong>After:</strong> step templates use <code>templates.settings.delimiters</code>. Without that setting, or with the default
<code>["{{", "}}"]</code>, nothing changes.</li>
</ul>
<p>The new behavior applies to unpinned projects and to projects pinned to <code>2026-10-19</code> or later. To keep the previous
behavior, pin an edition before the transition:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockTitle_JJ7b">atmos.yaml</div><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A"><div class="token-line" style="color:#d6deeb"><span class="token key atrule">edition</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)">"2026-10-18"</span><br></div></code></pre></div></div>
<p>Projects with custom delimiters that write <code>{{ }}</code> in step fields need one of two changes when they adopt the new
behavior: rewrite those fields with the configured delimiters, or keep the earlier pin. Run
<a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/describe/edition"><code>atmos describe edition</code></a> to see every behavior an edition pin selects.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/step-templates-honor-delimiters#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>Try custom delimiters in one workflow and share what you find in
<a href="https://github.com/cloudposse/atmos/discussions" target="_blank" rel="noopener noreferrer" class="">GitHub Discussions</a>.</p>]]></content>
        <author>
            <name>Erik Osterman</name>
            <uri>https://github.com/osterman</uri>
        </author>
        <category label="Enhancement" term="Enhancement"/>
        <category label="Breaking Change" term="Breaking Change"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Control How Long a Cast Segment Plays]]></title>
        <id>https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/cast-playback-duration</id>
        <link href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/cast-playback-duration"/>
        <updated>2026-10-18T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[A deployment can take thirty seconds to finish even when a demo only needs four]]></summary>
        <content type="html"><![CDATA[<p>A deployment can take thirty seconds to finish even when a demo only needs four
seconds to show its progress. Speeding up the entire recording also rushes the
commands and the pauses that help viewers follow along. Atmos now supports
<a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/steps/type/cast#set-a-segments-playback-duration">playback groups</a> to set the
recorded duration of just the steps you choose.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/cast-playback-duration#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>Real infrastructure demos include time spent waiting for providers and services.
Those waits belong in the execution, but they can dominate a short recording.
Removing frames loses the progress that explains what happened.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/cast-playback-duration#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>A playback group preserves every captured event and scales its timestamps to fit
an exact duration. Typing and reading pauses outside the group retain their
original timing. The command still runs normally, with real timeouts and live
output during recording.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/cast-playback-duration#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>Inside a cast session, wrap Enter and the completion wait in a group:</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">type</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">text</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> atmos terraform deploy </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">stack dev </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">all</span></span><br></div><div class="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"> playback</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">duration</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> 4s</span></span><br></div><div class="token-line 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"> 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 key atrule">key</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> enter</span></span><br></div><div class="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"> wait</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">regex</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)">'(?s)Apply .*completed.*&gt; '</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">timeout</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> 90s</span></span><br></div><div class="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"> pause</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">duration</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> 3s</span></span><br></div></code></pre></div></div>
<p>The four seconds begin before Enter and end when the completion wait matches.
The following three-second pause gives viewers time to read the result at the
returned prompt. Elapsed times printed by the command still show the actual
execution time; they are part of the preserved output.</p>
<p>The duration must be positive. Shorter segments stretch to fit, and playback
groups cannot nest. Groups also work around ordinary steps in a
<a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/steps/type/cast">steps-mode cast</a>.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/cast-playback-duration#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-3459.atmos-docs.ue2.dev.plat.cloudposse.org/steps/type/cast">cast documentation</a> for recording options, and share
feedback in <a href="https://github.com/cloudposse/atmos/discussions" target="_blank" rel="noopener noreferrer" class="">GitHub Discussions</a>.</p>]]></content>
        <author>
            <name>Erik Osterman</name>
            <uri>https://github.com/osterman</uri>
        </author>
        <category label="Feature" term="Feature"/>
        <category label="DX" term="DX"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Failed Commands and Policy Denials as CI Annotations]]></title>
        <id>https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/ci-failure-annotations</id>
        <link href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/ci-failure-annotations"/>
        <updated>2026-10-17T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[A CI job fails, and the run page says only "Process completed with exit code 1." To learn why, you open the job,]]></summary>
        <content type="html"><![CDATA[<p>A CI job fails, and the run page says only "Process completed with exit code 1." To learn why, you open the job,
scroll through the log, and hunt for the one error that matters. When the failure is a policy denial, the rule that
blocked the run and the reason its author wrote are in that log too, out of sight of the person reviewing the pull
request. Atmos now reports a failed command as a CI annotation, so the reason appears on the run page.</p>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/ci-failure-annotations#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>A failed job hides its cause. CI providers show a step's exit status at a glance, but the explanation stays in the
log. That costs a reviewer a click and a search on every failure. For <a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/policies">policy</a> denials it is worse: the
policy author's guidance, such as "EIPs cannot be destroyed; use <code>prevent_destroy</code> instead," is only useful if
someone reads it.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/ci-failure-annotations#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>When a command fails in CI, Atmos reports the failure through the CI provider's annotation support:</p>
<ul>
<li class=""><strong>Policy denials</strong> produce one annotation per rule that denied the run. The title names the rule, and the message
is the rule's <code>reason</code> as plain text, or "Denied by <code>&lt;rule&gt;</code>." when the rule has none.</li>
<li class=""><strong>Any other failure</strong> produces one annotation from the error's title, message, and explanation.</li>
<li class=""><strong>Location</strong>: when Atmos knows the file and line where the cause is defined, the annotation is anchored there.</li>
<li class=""><strong>Scripts</strong>: a nested Atmos command that fails inside a script reports its own failure once. The script that
called it does not repeat it.</li>
</ul>
<p>On GitHub Actions, these are <code>::error</code> workflow commands, which appear in the run's annotations:</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 title=Policy protect-prod/guard denied execution::Production components cannot be changed from this workstation.</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-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/ci-failure-annotations#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>Failure annotations follow the same switches as other <a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/ci#failure-annotations">CI annotations</a>:</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">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">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 class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">annotations</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line 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 class="token plain">   </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># default when ci.enabled is true</span></span><br></div></code></pre></div></div>
<p>A <a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/policies/admission#block-a-command">command policy</a> is evaluated before <code>atmos.yaml</code> loads. A denial at that point
is annotated whenever a CI provider is detected, because an annotation is the only CI signal it can produce.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="try-it-out">Try it out<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/ci-failure-annotations#try-it-out" class="hash-link" aria-label="Direct link to Try it out" title="Direct link to Try it out" translate="no">​</a></h2>
<div class="example_jMgJ"><div class="theme-tabs-container tabs-container tabList_oBn1"><ul role="tablist" aria-orientation="horizontal" class="tabs"><li role="tab" tabindex="-1" aria-selected="false" class="tabs__item tabItem_A3p1">Install Atmos</li><li role="tab" tabindex="0" aria-selected="true" class="tabs__item tabItem_A3p1 tabs__item--active">Try the example</li></ul><div class="margin-top--md"><div role="tabpanel" class="tabItem_gg6W" hidden=""><div class="install-widget install-widget--docs"><div class="install-widget__content"><div class="install-widget__select-wrapper"><span class="install-widget__label">Quick Install</span><select class="install-widget__select" aria-label="Installation method"><option value="0" selected="">Quick Install</option><option value="1">macOS</option><option value="2">Windows</option><option value="3">Docker</option></select><svg class="install-widget__chevron" width="12" height="8" viewBox="0 0 12 8" fill="none"><path d="M1 1.5L6 6.5L11 1.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path></svg></div><div class="install-widget__command"><code class="install-widget__code"><span class="install-widget__command-curl">curl -fsSL</span> <span class="install-widget__command-url">https://atmos.tools/install.sh</span> | <span class="install-widget__command-bash">bash</span></code></div><button class="install-widget__copy" type="button" aria-label="Copy installation command" title="Copy to clipboard"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="5" y="5" width="9" height="9" rx="1" stroke="currentColor" stroke-width="1.5"></rect><path d="M3 11V3C3 2.44772 3.44772 2 4 2H11" stroke="currentColor" stroke-width="1.5"></path></svg></button></div></div><div class="links_ZD8T"><a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/install">Installation guide →</a><a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/examples/policies">Explore the example →</a></div></div><div role="tabpanel" class="tabItem_gg6W"><p>Copy the example into a new directory and make it your 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 init examples/policies</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)">cd</span><span class="token plain"> policies</span><br></div></code></pre></div></div><p>Only Atmos is required. Validate the rule and run its offline fixtures, then follow the README to compare an allowed command with an intentional denial.</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 policy check</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos policy list</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos policy </span><span class="token builtin class-name" style="color:rgb(255, 203, 139)">test</span><span class="token plain"> tests/cases.json</span><br></div></code></pre></div></div><div class="links_ZD8T"><a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/examples/policies">Explore the example →</a><a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/init#examples-and-source-directories">Initialization and repository settings</a></div></div></div></div></div>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/ci-failure-annotations#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>Enable CI annotations in one workflow, trigger a policy denial, and share feedback in
<a href="https://github.com/cloudposse/atmos/discussions" target="_blank" rel="noopener noreferrer" class="">GitHub Discussions</a>.</p>]]></content>
        <author>
            <name>Erik Osterman</name>
            <uri>https://github.com/osterman</uri>
        </author>
        <category label="Enhancement" term="Enhancement"/>
        <category label="DX" term="DX"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Custom Terraform Formatting in README Templates]]></title>
        <id>https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/custom-terraform-readme-formatting</id>
        <link href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/custom-terraform-readme-formatting"/>
        <updated>2026-10-17T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Preformatted Terraform tables make it difficult to group variables or reproduce]]></summary>
        <content type="html"><![CDATA[<p>Preformatted Terraform tables make it difficult to group variables or reproduce
an existing README design. <a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/docs/generate#custom-terraform-formatting">Atmos README templates</a>
can now access native Terraform objects through a <code>terraform</code> function, so you
can render definition lists, badges, and collapsible sections yourself.</p>
<p>Previously, templates received Terraform documentation as an already-formatted
<code>terraform_docs</code> string. The new function provides the parsed module directly,
including methods such as <code>.GetValue</code> and <code>.Type.Raw</code> and source positions.</p>
<p>Enable Terraform documentation and select your template:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockTitle_JJ7b">atmos.yaml</div><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token key atrule">docs</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">generate</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">readme</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">base-dir</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> .</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">template</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)">"./README.md.gomplate"</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">output</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)">"./README.md"</span><span class="token plain"></span></span><br></div><div class="token-line 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">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 class="token plain"></span></span><br></div><div class="token-line 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"> .</span></span><br></div></code></pre></div></div>
<p>Then choose how to present the data:</p>
<div class="language-gotemplate codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockTitle_JJ7b">README.md.gomplate</div><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-gotemplate 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">{{ with terraform }}</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">## Optional Variables</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">{{ range .OptionalInputs }}</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">### `{{ .Name }}`</span></span><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">{{ .Description.Raw }}</span></span><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">Type: `{{ .Type.Raw }}`</span></span><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">Default: `{{ .GetValue }}`</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">{{ end }}</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">{{ end }}</span></span><br></div></code></pre></div></div>
<p>Run <code>atmos docs generate readme</code> to render it. The <code>with</code> guard also handles
disabled Terraform generation or a missing configured source directory.
Existing templates can continue using <code>terraform_docs</code>. Its visibility,
<code>hide_empty</code>, and <code>indent_level</code> settings now work for unpinned projects and
editions on or after <code>2026-10-17</code>; earlier edition pins preserve the previous
formatter behavior. The native objects remain available regardless of these settings.</p>
<p>Atmos 1.232.0 and earlier cannot parse the new function, even inside a guard.
Upgrade the repository's Atmos version before adopting a native template.</p>
<p>See <a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/docs/generate#custom-terraform-formatting">Custom Terraform formatting</a>
for the available objects and a complete example adapted from Cloud Posse's
component README design.</p>]]></content>
        <author>
            <name>Erik Osterman</name>
            <uri>https://github.com/osterman</uri>
        </author>
        <category label="Enhancement" term="Enhancement"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Store Planfiles in a Different Cloud Than Your Component]]></title>
        <id>https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/planfile-store-identity</id>
        <link href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/planfile-store-identity"/>
        <updated>2026-10-16T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Plan in one stage, apply in another: that is the whole point of saving a Terraform planfile between CI]]></summary>
        <content type="html"><![CDATA[<p>Plan in one stage, apply in another: that is the whole point of saving a Terraform planfile between CI
steps. But the place that holds the plan and the infrastructure the plan describes do not have to live in
the same cloud. A component can authenticate to Azure or GCP while its planfiles belong in an S3 bucket the
platform team already runs. That split is normal in multi-cloud pipelines, and until now it quietly did not
work: the planfile store borrowed whatever identity the component authenticated with, so an Azure component
trying to upload to S3 failed to produce AWS credentials at all.</p>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/planfile-store-identity#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>Atmos can store a Terraform planfile after <code>plan</code> and verify it before <code>deploy</code>, so the plan you reviewed is
the plan you apply. The store that holds it is configured per project under
<code>components.terraform.planfiles.stores</code>.</p>
<p>The catch was authentication. When a component authenticated with a non-AWS identity, the S3 planfile store
inherited that same identity and then tried to resolve AWS credentials from it. A <code>azure/subscription</code>
identity authenticates just fine, but it produces no AWS auth context, so the upload failed:</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">failed to upload planfile: failed to load AWS configuration:</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">failed to resolve AWS auth context for identity "azure-plan":</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">auth context not available for identity</span><br></div></code></pre></div></div>
<p>The shape of the problem is general: there was no way to say "authenticate the component one way, but
authenticate the planfile store another way." The two were locked together. (The same mismatch will apply in
reverse once non-AWS planfile backends land; today the S3 store is the one that trips on it.)</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/planfile-store-identity#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>Planfile stores now take an optional <code>identity</code> field, naming the <a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/auth">Atmos Auth
identity</a> the store authenticates with, independent of the component's identity. It
works like the <a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/stores"><code>identity</code> field on general Atmos stores</a> you may already use.</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">planfiles</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line 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"> s3</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">stores</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">s3</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line 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"> aws/s3</span></span><br></div><div class="token-line 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"> aws</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">backend    </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># store authenticates with this identity</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">          </span><span class="token key atrule">options</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">            </span><span class="token key atrule">bucket</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> my</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">terraform</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">planfiles</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">            </span><span class="token key atrule">region</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> us</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">east</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>
<p>The component keeps using its own identity for the Terraform run, while the store uses <code>aws-backend</code> only for
upload and download. The store identity isn't limited to ambient credentials: for the S3 store, any
AWS-capable identity - <code>aws/assume-role</code>, <code>aws/permission-set</code>, and the like - is resolved through the same
Atmos Auth chain, not merely passed through from the runner environment.</p>
<p>When <code>identity</code> is omitted, the store inherits the component's identity exactly as before, so existing
single-cloud projects need no changes.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/planfile-store-identity#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>Define the two identities in <code>auth.identities</code> - one the component uses, one the store uses - and point the
store at the second:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token key atrule">auth</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">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-plan</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain">                    </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># the component's default identity (non-AWS)</span><span class="token plain"></span></span><br></div><div class="token-line 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">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 comment" style="color:rgb(99, 119, 119);font-style:italic"># ...</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">aws-backend</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain">                   </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># AWS identity, used only by the planfile store</span><span class="token plain"></span></span><br></div><div class="token-line 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"> aws/assume</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">role</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># ...</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain" 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">planfiles</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line 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"> s3</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">stores</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">s3</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line 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"> aws/s3</span></span><br></div><div class="token-line 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"> aws</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">backend</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">          </span><span class="token key atrule">options</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">            </span><span class="token key atrule">bucket</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> my</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">terraform</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">planfiles</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">            </span><span class="token key atrule">region</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> us</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">east</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>
<p>See the <a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/ci/planfile-storage">Store Identity documentation</a> for the full configuration
reference, and the <a href="https://github.com/cloudposse/atmos/tree/main/examples/planfile-store-identity" target="_blank" rel="noopener noreferrer" class="">per-store identity example</a>
for a complete, working project.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="try-it-out">Try it out<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/planfile-store-identity#try-it-out" class="hash-link" aria-label="Direct link to Try it out" title="Direct link to Try it out" translate="no">​</a></h2>
<div class="example_jMgJ"><div class="theme-tabs-container tabs-container tabList_oBn1"><ul role="tablist" aria-orientation="horizontal" class="tabs"><li role="tab" tabindex="-1" aria-selected="false" class="tabs__item tabItem_A3p1">Install Atmos</li><li role="tab" tabindex="0" aria-selected="true" class="tabs__item tabItem_A3p1 tabs__item--active">Try the example</li></ul><div class="margin-top--md"><div role="tabpanel" class="tabItem_gg6W" hidden=""><div class="install-widget install-widget--docs"><div class="install-widget__content"><div class="install-widget__select-wrapper"><span class="install-widget__label">Quick Install</span><select class="install-widget__select" aria-label="Installation method"><option value="0" selected="">Quick Install</option><option value="1">macOS</option><option value="2">Windows</option><option value="3">Docker</option></select><svg class="install-widget__chevron" width="12" height="8" viewBox="0 0 12 8" fill="none"><path d="M1 1.5L6 6.5L11 1.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path></svg></div><div class="install-widget__command"><code class="install-widget__code"><span class="install-widget__command-curl">curl -fsSL</span> <span class="install-widget__command-url">https://atmos.tools/install.sh</span> | <span class="install-widget__command-bash">bash</span></code></div><button class="install-widget__copy" type="button" aria-label="Copy installation command" title="Copy to clipboard"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="5" y="5" width="9" height="9" rx="1" stroke="currentColor" stroke-width="1.5"></rect><path d="M3 11V3C3 2.44772 3.44772 2 4 2H11" stroke="currentColor" stroke-width="1.5"></path></svg></button></div></div><div class="links_ZD8T"><a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/install">Installation guide →</a><a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/examples/planfile-store-identity">Explore the example →</a></div></div><div role="tabpanel" class="tabItem_gg6W"><p>Copy the example into a new directory and make it your 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 init examples/planfile-store-identity</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)">cd</span><span class="token plain"> planfile-store-identity</span><br></div></code></pre></div></div><p>Validate the sample configuration locally. Replace the sample identities and store names before using it with cloud services.</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 stacks</span><br></div></code></pre></div></div><div class="links_ZD8T"><a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/examples/planfile-store-identity">Explore the example →</a><a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/init#examples-and-source-directories">Initialization and repository settings</a></div></div></div></div></div>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/planfile-store-identity#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>This shipped from a real multi-cloud setup where the plan-then-deploy workflow crossed a credential boundary.
If your pipeline spans clouds in ways this does not yet cover, open an issue or a discussion on
<a href="https://github.com/cloudposse/atmos" target="_blank" rel="noopener noreferrer" class="">GitHub</a> - the planfile store and the broader auth system keep growing
from exactly these cases.</p>]]></content>
        <author>
            <name>Andriy Knysh</name>
            <uri>https://github.com/aknysh</uri>
        </author>
        <category label="Feature" term="Feature"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Control Preview Environments with CI Review Labels]]></title>
        <id>https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/ci-labels</id>
        <link href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/ci-labels"/>
        <updated>2026-10-15T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Enabling preview environments from a pull request label often requires workflow scripts to fetch labels and pass flags into stack configuration. The new !ci.labels YAML function lets you express that decision directly in your stacks.]]></summary>
        <content type="html"><![CDATA[<p>Enabling preview environments from a pull request label often requires workflow scripts to fetch labels and pass flags into stack configuration. The new <a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/functions/yaml/ci.labels"><code>!ci.labels</code></a> YAML function lets you express that decision directly in your stacks.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/ci-labels#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>A label such as <code>preview</code> should be enough to enable preview behavior and select the affected components that participate. Keeping that decision in workflow scripts duplicates configuration and separates it from the components it controls.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/ci-labels#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>The <code>!ci.labels</code> function reads live labels on the current CI review. GitHub Actions is the first supported provider, including GitHub Enterprise. Atmos fetches every page on first use and caches the resulting snapshot for the entire invocation, so components share one consistent result without repeated API requests. The next invocation fetches fresh labels.</p>
<p><a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/functions/yaml/ci.labels#merge-queues">Merge-queue runs</a> use the labels of the individual PR being tested. Labels from earlier queued PRs do not affect that run, even when their changes are included in the checkout.</p>
<p>Outside a review context, matching returns <code>false</code> and list mode returns <code>[]</code>, without credentials or API calls. Authentication and API failures in a review context remain errors.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/ci-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>Set a boolean <a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/stacks/components/component-metadata#labels">component label</a> alongside the preview setting:</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">preview</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line 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">preview</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)">!ci.labels</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token plain">preview</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">settings</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        </span><span class="token key atrule">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">enabled</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)">!ci.labels</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token plain">preview</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span></span><br></div></code></pre></div></div>
<p>Then filter the <a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/describe/affected">affected components</a>:</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 describe affected </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--labels</span><span class="token plain"> preview:true</span><br></div></code></pre></div></div>
<p>Use <code>!ci.labels [preview, deploy]</code> to require both labels, or bare <code>!ci.labels</code> to retrieve a sorted list. Matching is exact and case-sensitive; quote names containing spaces, such as <code>!ci.labels ["needs review"]</code>.</p>
<p>In GitHub Actions, pass <code>GITHUB_TOKEN: ${{ github.token }}</code> to the Atmos step with <code>pull-requests: read</code> permission. See the <a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/functions/yaml/ci.labels#live-lookup-and-credentials">credentials and snapshot documentation</a> for token precedence, Enterprise configuration, and examples.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/ci-labels#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>Share feedback and requests for additional CI providers in <a href="https://github.com/cloudposse/atmos/discussions" target="_blank" rel="noopener noreferrer" class="">GitHub Discussions</a>.</p>]]></content>
        <author>
            <name>Erik Osterman</name>
            <uri>https://github.com/osterman</uri>
        </author>
        <category label="Feature" term="Feature"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Atmos CI, Auth, Toolchain, Emulator, and Source Vendoring Graduate to Stable]]></title>
        <id>https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/core-features-graduate-to-stable</id>
        <link href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/core-features-graduate-to-stable"/>
        <updated>2026-10-15T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[The past year has changed how we build Atmos. Advances in AI have accelerated]]></summary>
        <content type="html"><![CDATA[<p>The past year has changed how we build Atmos. Advances in AI have accelerated
our development and helped us bring many new capabilities to the project. Some
needed more time and real-world experience before they were ready for broad
adoption. We introduced the <a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/experimental">experimental designation</a> to make that maturity visible
and help you decide which features were ready for everyday use.</p>
<p>Since then, we, our customers, and the community have put many of these features
to work in production. That use has brought valuable feedback. Interfaces have
stabilized, functionality has been validated, and feedback has increasingly shifted
from critical problems toward refinements and nice-to-haves.</p>
<p>We're graduating <a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/ci">Atmos CI</a>, <a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/auth/usage">Atmos Auth</a>,
<a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/toolchain/usage">Atmos Toolchain</a>, <a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/emulator/usage">Atmos Emulator</a>,
and <a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/terraform/source">source vendoring</a> to stable. These capabilities
have demonstrated stable interfaces and real-world use;
this release formalizes their supported status. Other features will keep the
experimental designation while we continue assessing them.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/core-features-graduate-to-stable#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>These capabilities have become part of everyday infrastructure delivery while
still carrying experimental warnings. Some roadmap entries already omitted the
experimental label, while commands and documentation retained it. Teams needed a
consistent answer about which interfaces they could rely on.</p>
<p>We applied the existing <a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/experimental#graduation-criteria">graduation criteria</a>
and reviewed the preceding 90 days of available history. That is an evidence window,
not a claim that every feature went 90 days without a bug or a requirement to wait
another quarter before recognizing established use.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/core-features-graduate-to-stable#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>The following capabilities now have stable command and configuration interfaces:</p>
<table><thead><tr><th>Capability</th><th>What you can rely on</th></tr></thead><tbody><tr><td><a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/ci">Atmos CI</a></td><td>Native plan/apply/deploy reporting, summaries, outputs, and configured planfile storage, with GitHub Actions and generic CI support</td></tr><tr><td><a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/auth/usage">Atmos Auth</a></td><td>The identity, credential, and session-management interface used locally and in automation</td></tr><tr><td><a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/toolchain/usage">Atmos Toolchain</a></td><td>Declaring, installing, and selecting tool versions, including reproducible installs through lockfiles</td></tr><tr><td><a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/terraform/source">Source vendoring</a></td><td>Fetching component sources on demand, refreshing changed versions, and reusing cached sources in isolated workdirs</td></tr><tr><td><a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/emulator/usage">Atmos Emulator</a></td><td>Managing local emulator components and their lifecycle for development and testing</td></tr></tbody></table>
<p>Here's what that use looks like:</p>
<ul>
<li class="">CI and Toolchain run in production at dozens of our own customers,
with broader adoption across the community.</li>
<li class="">We've used Auth exclusively for several months. CI, Auth,
and Toolchain are frequently used together in production.</li>
<li class="">Nearly all of our <a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/examples">demos</a> use the Emulator functionality.
Repeatedly exercising infrastructure locally has helped identify and fix problems in Atmos itself.</li>
<li class="">We use source vendoring ourselves, and we've seen substantial community adoption.
It went through a rough patch; that feedback led to fixes for retrieval failures
and workdir interactions.</li>
</ul>
<p><strong>Atmos Auth, Toolchain, and CI commands have been executed more than a million
times in the past 90 days.</strong> Anonymous telemetry recorded 1,030,935 executions
from July 17 through October 14, 2026, without an extrapolation multiplier.
This counts explicit command executions; embedded use of these features inside
other commands is not separately counted.</p>
<p>Auth's adoption extends beyond CI automation: <strong>nearly 120,000 authentication
commands were run outside CI pipelines</strong> during the same period.</p>
<p>We've seen relatively few reports affecting core functionality across these features.
We combined that experience with regression checks; neither means bugs cannot occur. Recent fixes remain part of the record. Newer providers and integrations,
including Azure, have less production history than the established features.
Emulator's stable status concerns Atmos's lifecycle interface; it does not promise
that a third-party emulator implements every cloud API.</p>
<p>Source vendoring includes automatic workdir use for remote component sources. The
<a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/terraform/workdir"><code>terraform workdir</code> commands</a> also graduate,
covering listing, inspecting, and cleaning component working directories.</p>
<p>Atmos CI also works with <a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/pro">Atmos Pro</a>, which is already used in production.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/core-features-graduate-to-stable#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>Upgrade Atmos. No configuration changes are required; your existing commands and
configuration continue to work. The graduated features no longer display
experimental warnings.</p>
<div class="theme-admonition theme-admonition-tip admonition_EgRf alert alert--success"><div class="admonitionHeading_nA1E"><span class="admonitionIcon_iNSx"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>Optional: silence experimental warnings</div><div class="admonitionContent_mRSl"><p>To suppress warnings for features that are still experimental, use
<a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/config/config-set"><code>atmos config set</code></a>:</p><div class="language-shell codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-shell codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A"><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos config </span><span class="token builtin class-name" style="color:rgb(255, 203, 139)">set</span><span class="token plain"> settings.experimental silence</span><br></div></code></pre></div></div></div></div>
<p>The remaining <a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/experimental">experimental features</a> keep their labels and
restrictions. Affected-component detection, Devcontainers, backend provisioning,
and other candidates will graduate when their own evidence supports it. We expect another round of promotions soon, with
Kubernetes, Helm, and container components next in the review.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/core-features-graduate-to-stable#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>Continue reporting reproducible problems through <a href="https://github.com/cloudposse/atmos/issues" target="_blank" rel="noopener noreferrer" class="">GitHub Issues</a>.
Include the Atmos version, a minimal configuration, and the expected behavior,
with credentials and identifying infrastructure details removed. Real-world use
and regression reports help us assess the next candidates.</p>]]></content>
        <author>
            <name>Erik Osterman</name>
            <uri>https://github.com/osterman</uri>
        </author>
        <category label="Enhancement" term="Enhancement"/>
        <category label="DX" term="DX"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Exclude Expected Attribute Changes from Plan Comparisons]]></title>
        <id>https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/plan-diff-ignore-changes</id>
        <link href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/plan-diff-ignore-changes"/>
        <updated>2026-10-13T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[An RDS instance's latest restorable time can advance between Terraform plans even when its configuration has not changed. That timestamp can make a plan comparison fail and interrupt deployment verification. Atmos now supports configured attribute exclusions for both comparisons.]]></summary>
        <content type="html"><![CDATA[<p>An RDS instance's latest restorable time can advance between Terraform plans even when its configuration has not changed. That timestamp can make a plan comparison fail and interrupt deployment verification. Atmos now supports <a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/terraform/plan-diff#ignoring-attribute-changes">configured attribute exclusions</a> for both comparisons.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/plan-diff-ignore-changes#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>Provider-maintained attributes can vary independently of configuration changes. As reported in <a href="https://github.com/cloudposse/atmos/issues/2088" target="_blank" rel="noopener noreferrer" class="">#2088</a>, comparing RDS plans can report differences in <code>latest_restorable_time</code> that a project wants to ignore.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/plan-diff-ignore-changes#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>The new <code>components.terraform.plan_diff.ignore_changes</code> setting applies exclusions consistently to the displayed diff and the comparison result. Both <code>atmos terraform plan-diff</code> and deployment plan verification honor the same configuration.</p>
<p>Other attribute changes, resource additions and removals, action changes, and replacement metadata remain detectable. Variables and outputs are compared independently, including outputs that export an excluded attribute.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/plan-diff-ignore-changes#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 an exact resource type and top-level attribute to <code>atmos.yaml</code>:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockTitle_JJ7b">atmos.yaml</div><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token key atrule">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">plan_diff</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">ignore_changes</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="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"> aws_db_instance.latest_restorable_time</span></span><br></div></code></pre></div></div>
<p>This entry applies to all instances of <code>aws_db_instance</code>, including those inside modules. Wildcards, nested paths, and unqualified attribute names are rejected before Terraform runs.</p>
<p>These exclusions control Atmos comparisons. They do not change Terraform's <code>lifecycle.ignore_changes</code>, resource updates, plans, or state.</p>
<h3 class="anchor anchorTargetStickyNavbar_cA1_" id="existing-projects-and-editions">Existing projects and editions<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/plan-diff-ignore-changes#existing-projects-and-editions" class="hash-link" aria-label="Direct link to Existing projects and editions" title="Direct link to Existing projects and editions" translate="no">​</a></h3>
<p>No attributes are automatically excluded from comparisons. Content hashes and encoded response
bodies can represent real changes, so exclude them only when your project expects those changes.</p>
<p>Atmos previously hid seven attributes from displayed diffs while still reporting a comparison
failure for their differences. The <code>2026-10-13</code> <a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/edition">edition</a> displays them:
<code>response_body_base64</code>, <code>content_base64sha256</code>, <code>content_base64sha512</code>, <code>content_md5</code>,
<code>content_sha1</code>, <code>content_sha256</code>, and <code>content_sha512</code>. Unpinned projects get the new display too.
A pin before that date preserves the old display-only suppression and still detects the differences.
Explicit exclusions work identically under every edition.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/plan-diff-ignore-changes#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-3459.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/terraform/plan-diff">plan-diff documentation</a> for command usage, and <a href="https://github.com/cloudposse/atmos/issues" target="_blank" rel="noopener noreferrer" class="">report unexpected comparison behavior</a> with a sanitized example.</p>]]></content>
        <author>
            <name>Erik Osterman</name>
            <uri>https://github.com/osterman</uri>
        </author>
        <category label="Feature" term="Feature"/>
        <category label="Bug Fix" term="Bug Fix"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Diagnose and repair configuration with Atmos Doctor]]></title>
        <id>https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/atmos-doctor</id>
        <link href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/atmos-doctor"/>
        <updated>2026-10-11T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Configuration can pass schema validation while still using deprecated fields or depending on an archived upstream repository. Migrating those fields also takes care: a valid replacement can change which components run or how missing dependencies behave. The new Atmos Doctor brings those findings together and verifies supported repairs before applying them.]]></summary>
        <content type="html"><![CDATA[<p>Configuration can pass schema validation while still using deprecated fields or depending on an archived upstream repository. Migrating those fields also takes care: a valid replacement can change which components run or how missing dependencies behave. The new <a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/doctor">Atmos Doctor</a> brings those findings together and verifies supported repairs before applying them.</p>
<!-- -->
<div><div class="window_X9dN"><div class="titlebar_DN7h"><span class="dots_R2sg" aria-hidden="true"><i></i><i></i><i></i></span><span class="title_Dael">Diagnose and verify configuration repairs</span></div><pre class="screen__b5c noPreWrap_ImkX screenLoading_abuO"><span> </span></pre><div class="controls_eyLV" data-cast-controls="true"><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 class="time_lEbH">00:00.0<!-- --> / <!-- -->00:00.0</span></div></div><div class="castActions_M13G"><div class="container_zGFV"><div class="group_ncGU" role="group" aria-label="Share this demo"><button type="button" class="primary_hpkh" title="Copy a link to this demo" aria-live="polite"><svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" class="icon_P_nE" aria-hidden="true" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><circle cx="18" cy="5" r="3"></circle><circle cx="6" cy="12" r="3"></circle><circle cx="18" cy="19" r="3"></circle><line x1="8.59" y1="13.51" x2="15.42" y2="17.49"></line><line x1="15.41" y1="6.51" x2="8.59" y2="10.49"></line></svg><span>Share</span></button><button type="button" class="caret_pPxC" aria-expanded="false" aria-label="More share options" title="More share options"><svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" class="icon_P_nE" aria-hidden="true" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><polyline points="6 9 12 15 18 9"></polyline></svg></button></div></div><div class="container_EXko"><button type="button" class="trigger_WxG7" aria-expanded="false" aria-label="Download cast"><svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" class="icon_LbC3" aria-hidden="true" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline points="7 10 12 15 17 10"></polyline><line x1="12" y1="15" x2="12" y2="3"></line></svg><span>Download</span><svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" class="icon_LbC3" aria-hidden="true" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><polyline points="6 9 12 15 18 9"></polyline></svg></button></div></div></div>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/atmos-doctor#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>Project health checks span configuration schemas, stack validation, formatting, CI workflows, and upstream sources. Deprecation guidance identifies replacement fields, but a replacement is safe only when its behavior matches the original configuration.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/atmos-doctor#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>Doctor combines built-in checks in a streaming report. Supported repairs cover custom-command semantic arguments and flags, recognized legacy hook events, explicit Terraform reconfigure values, simple legacy <code>settings.depends_on</code> lists, and component sources that point at archived repositories. Each repair compares runtime field behavior and unrelated YAML values before writing, and comments on a migrated field move with it. A repair is blocked only by inputs that can change what it means, such as an import, an active profile, or a template in the edited value, and the finding names the file and line responsible. Templates elsewhere in the file do not get in the way. Repaired files can have blank lines or folded scalars reformatted, so review the diff before committing.</p>
<p>A simple dependency list, where each entry names a component and optionally its stack, moves to <code>dependencies.components</code> and adopts modern required semantics on purpose: a missing or disabled target that only produced a warning before is now reported as an error, so you see it before it breaks a deployment. Context selectors, file and folder entries, and stack naming migrations remain manual.</p>
<p>GitHub source metadata identifies archived repositories and distinguishes inaccessible sources from confirmed removal. The health check itself never rewrites source URLs. The one exception is the <code>component-monorepo</code> repair, which moves a source to its successor repository at the same version only after verifying the files are identical. Access errors, private-repository 404 responses, and unsupported hosts remain inconclusive.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/atmos-doctor#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>Start with a diagnosis, then inspect a verified dry run:</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 doctor</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos doctor </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--fix</span><span class="token plain"> --dry-run</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos doctor </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--fix</span><br></div></code></pre></div></div>
<p>The <a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/doctor#verification-and-recovery">verification and recovery report</a> explains repairs and skipped migrations. Before writing, doctor warns about affected Git changes or unavailable Git and saves exact originals in a private backup directory. Each replacement is atomic; partial failures report exactly which files changed.</p>
<p>For CI, use <a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/doctor#output-and-exit-codes">JSON or SARIF output</a>. Warnings are advisory by default; select <code>--fail-on=warning</code> to make them blocking. Use <code>--offline</code> to skip repository requests; the skipped checks are reported as notices that never trip <code>--fail-on=warning</code>. Doctor exits <code>2</code> for invocation errors and when it cannot find a project configuration, and with JSON output those errors arrive in an <code>operational_error</code> field.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/atmos-doctor#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-3459.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/doctor">command reference</a> and share unsupported migration cases in <a href="https://github.com/cloudposse/atmos/discussions" target="_blank" rel="noopener noreferrer" class="">Atmos discussions</a>.</p>]]></content>
        <author>
            <name>Erik Osterman</name>
            <uri>https://github.com/osterman</uri>
        </author>
        <category label="Feature" term="Feature"/>
        <category label="DX" term="DX"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Experimental Policy Gates and Required Hooks]]></title>
        <id>https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/policy-gates-and-hooks</id>
        <link href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/policy-gates-and-hooks"/>
        <updated>2026-10-11T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[A successful infrastructure command does not prove that a plan respected your safety rules or that]]></summary>
        <content type="html"><![CDATA[<p>A successful infrastructure command does not prove that a plan respected your safety rules or that
the required scanner ran. Experimental <a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/policies">Atmos policies</a> let you reject saved Terraform plans and
require lifecycle hooks using CEL expressions, with native GitHub Actions context available locally
inside the job.</p>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/policy-gates-and-hooks#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>Guardrails scattered across workflow scripts are difficult to apply consistently. A destructive
replacement can slip past a deletion-only check, and an optional hook can be skipped even when your
deployment process requires it.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/policy-gates-and-hooks#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>The opt-in policy integration evaluates native saved-plan JSON after Terraform planning and again
before applying a private copy of the selected artifact. Lifecycle policies can deny operations or
select existing hooks for Terraform, Helmfile, native Helm, and native Kubernetes. Required hooks
cannot be skipped with <code>--skip-hooks</code>; requiring execution and requiring success are separate choices.</p>
<p>GitHub Actions policies can inspect allowlisted runner metadata and the supplied native event
without API credentials or additional token permissions. Missing required context blocks evaluation.
The event records the trigger, not current review state. Policies evaluate the input and required
hooks for the current invocation.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/policy-gates-and-hooks#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>Place this document in a protected policy directory:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockTitle_JJ7b">policy.d/safety.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">apiVersion</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> atmos/v1</span></span><br></div><div class="token-line 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"> Policy</span></span><br></div><div class="token-line 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">name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> safety</span></span><br></div><div class="token-line 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">policies</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">protect-databases</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">on</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> 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 key atrule">action</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> deny</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">reason</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> Database deletion and replacement require a different deployment process</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">rule</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)">&gt;</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">        has(input.resource_changes) </span><span class="token important">&amp;&amp;</span><span class="token plain"> input.resource_changes.exists(r</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">          r.mode == 'managed' </span><span class="token important">&amp;&amp;</span><span class="token plain"> r.type == 'aws_db_instance' </span><span class="token important">&amp;&amp;</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">          'delete' in r.change.actions)</span></span><br></div></code></pre></div></div>
<p>Then run an explicit plan and saved-plan apply:</p>
<div class="language-shell codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-shell codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A"><div class="token-line" style="color:#d6deeb"><span class="token builtin class-name" style="color:rgb(255, 203, 139)">export</span><span class="token plain"> </span><span class="token assign-left variable" style="color:rgb(214, 222, 235)">ATMOS_POLICY_DIR</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">/trusted/policy.d</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos terraform plan database </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-s</span><span class="token plain"> prod</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos terraform apply database </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-s</span><span class="token plain"> prod --from-plan</span><br></div></code></pre></div></div>
<p>With plan policies configured, implicit apply/deploy and direct destroy are rejected. These checks
do not require <code>--affected</code>. Dry-run does not evaluate a saved plan and is not policy approval.</p>
<p>Protect the governing directory, workflow, environment, and executable dependencies: this opt-in
feature is not a sandbox against someone who controls the runner. A failed post-apply hook can fail
the command, but cannot undo the completed apply.</p>
<p>See <a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/policies/configuration">Policy Configuration</a> for the manifest and trust boundary,
<a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/policies/terraform-plan">Terraform Plans</a> for saved-plan checks, and <a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/policies/hooks">Hooks</a>
for required lifecycle actions.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="try-it-out">Try it out<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/policy-gates-and-hooks#try-it-out" class="hash-link" aria-label="Direct link to Try it out" title="Direct link to Try it out" translate="no">​</a></h2>
<div class="example_jMgJ"><div class="theme-tabs-container tabs-container tabList_oBn1"><ul role="tablist" aria-orientation="horizontal" class="tabs"><li role="tab" tabindex="-1" aria-selected="false" class="tabs__item tabItem_A3p1">Install Atmos</li><li role="tab" tabindex="0" aria-selected="true" class="tabs__item tabItem_A3p1 tabs__item--active">Try the example</li></ul><div class="margin-top--md"><div role="tabpanel" class="tabItem_gg6W" hidden=""><div class="install-widget install-widget--docs"><div class="install-widget__content"><div class="install-widget__select-wrapper"><span class="install-widget__label">Quick Install</span><select class="install-widget__select" aria-label="Installation method"><option value="0" selected="">Quick Install</option><option value="1">macOS</option><option value="2">Windows</option><option value="3">Docker</option></select><svg class="install-widget__chevron" width="12" height="8" viewBox="0 0 12 8" fill="none"><path d="M1 1.5L6 6.5L11 1.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path></svg></div><div class="install-widget__command"><code class="install-widget__code"><span class="install-widget__command-curl">curl -fsSL</span> <span class="install-widget__command-url">https://atmos.tools/install.sh</span> | <span class="install-widget__command-bash">bash</span></code></div><button class="install-widget__copy" type="button" aria-label="Copy installation command" title="Copy to clipboard"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="5" y="5" width="9" height="9" rx="1" stroke="currentColor" stroke-width="1.5"></rect><path d="M3 11V3C3 2.44772 3.44772 2 4 2H11" stroke="currentColor" stroke-width="1.5"></path></svg></button></div></div><div class="links_ZD8T"><a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/install">Installation guide →</a><a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/examples/policies">Explore the example →</a></div></div><div role="tabpanel" class="tabItem_gg6W"><p>Copy the example into a new directory and make it your 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 init examples/policies</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)">cd</span><span class="token plain"> policies</span><br></div></code></pre></div></div><p>Only Atmos is required. Validate the rule and run its offline fixtures, then follow the README to compare an allowed command with an intentional denial.</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 policy check</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos policy list</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos policy </span><span class="token builtin class-name" style="color:rgb(255, 203, 139)">test</span><span class="token plain"> tests/cases.json</span><br></div></code></pre></div></div><div class="links_ZD8T"><a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/examples/policies">Explore the example →</a><a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/init#examples-and-source-directories">Initialization and repository settings</a></div></div></div></div></div>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/policy-gates-and-hooks#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>Try the <a href="https://github.com/cloudposse/atmos/tree/main/examples/policies" target="_blank" rel="noopener noreferrer" class="">tested policy demonstrations</a>
and share feedback in <a href="https://github.com/cloudposse/atmos/discussions" target="_blank" rel="noopener noreferrer" class="">GitHub Discussions</a>.</p>]]></content>
        <author>
            <name>Erik Osterman</name>
            <uri>https://github.com/osterman</uri>
        </author>
        <category label="Feature" term="Feature"/>
        <category label="Experimental" term="Experimental"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[A Conversation, Not a Dead End: Interactive atmos ai ask]]></title>
        <id>https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/ai-ask-interactive</id>
        <link href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/ai-ask-interactive"/>
        <updated>2026-10-09T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[You ask the AI how many stacks you have. After a pause with nothing on screen, it answers that it needs your approval to run a command, and asks whether you would approve it. There is no prompt to say yes to, no sign that anything was happening while you waited, and no way to reply. The answer ends, and so does the conversation.]]></summary>
        <content type="html"><![CDATA[<p>You ask the AI how many stacks you have. After a pause with nothing on screen, it answers that it needs your approval to run a command, and asks whether you would approve it. There is no prompt to say yes to, no sign that anything was happening while you waited, and no way to reply. The answer ends, and so does the conversation.</p>
<p>That is what asking a question from the terminal has felt like when the AI runs through Claude Code. Atmos now keeps the conversation open: it shows you what the AI wants to do, lets you approve it, lets the AI ask you to choose, and lets you follow up without starting over.</p>
<div><div class="window_X9dN"><div class="titlebar_DN7h"><span class="dots_R2sg" aria-hidden="true"><i></i><i></i><i></i></span><span class="title_Dael">atmos ai ask</span></div><pre class="screen__b5c noPreWrap_ImkX screenLoading_abuO"><span> </span></pre><div class="controls_eyLV" data-cast-controls="true"><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 class="time_lEbH">00:00.0<!-- --> / <!-- -->00:00.0</span></div></div><div class="castActions_M13G"><div class="container_zGFV"><div class="group_ncGU" role="group" aria-label="Share this demo"><button type="button" class="primary_hpkh" title="Copy a link to this demo" aria-live="polite"><svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" class="icon_P_nE" aria-hidden="true" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><circle cx="18" cy="5" r="3"></circle><circle cx="6" cy="12" r="3"></circle><circle cx="18" cy="19" r="3"></circle><line x1="8.59" y1="13.51" x2="15.42" y2="17.49"></line><line x1="15.41" y1="6.51" x2="8.59" y2="10.49"></line></svg><span>Share</span></button><button type="button" class="caret_pPxC" aria-expanded="false" aria-label="More share options" title="More share options"><svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" class="icon_P_nE" aria-hidden="true" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><polyline points="6 9 12 15 18 9"></polyline></svg></button></div></div><div class="container_EXko"><button type="button" class="trigger_WxG7" aria-expanded="false" aria-label="Download cast"><svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" class="icon_LbC3" aria-hidden="true" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline points="7 10 12 15 17 10"></polyline><line x1="12" y1="15" x2="12" y2="3"></line></svg><span>Download</span><svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" class="icon_LbC3" aria-hidden="true" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><polyline points="6 9 12 15 18 9"></polyline></svg></button></div></div></div>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/ai-ask-interactive#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>Claude Code runs without a terminal of its own when Atmos starts it for a one-off question. It cannot ask you anything, so it refuses any tool that needs permission and then describes the refusal in its answer. You see a request for approval that you have no way to give.</p>
<p>Two more rough edges made it worse:</p>
<ul>
<li class="">Nothing showed that work was in progress, so a slow answer looked the same as a hung command.</li>
<li class="">Answers often ended with an offer ("I can break that down by tenant if you'd like") that you could only accept by retyping the whole question.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/ai-ask-interactive#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p><a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/ai/ask"><code>atmos ai ask</code></a> is now interactive when it runs through the <code>claude-code</code> provider.</p>
<p><strong>Approval in the same run.</strong> When the AI needs to run a command, Atmos pauses and shows the request in a block that wraps to your terminal width, with the command in its own panel. You choose Allow once (the default), Always allow, Deny once, or Always deny. The AI waits for your answer and continues in the same run. A one-line receipt stays behind so you can see what you approved.</p>
<p><strong>Choices instead of guesses.</strong> When the AI needs you to pick between options or confirm something, it asks with a selection list. You choose with the arrow keys, or choose Other to type your own answer. Your choice goes straight back to the AI.</p>
<p><strong>Progress you can see.</strong> A spinner shows that work is happening and names the command in progress, for example Running <code>atmos list stacks</code>. It steps aside while a prompt is on screen, and Ctrl-C cancels the request.</p>
<p><strong>Follow-up questions.</strong> After an answer, a prompt offers to continue. Type a reply and the AI answers with the earlier questions and answers as context, so a short "yes, by tenant" is enough. Press Enter on an empty line to finish.</p>
<p>Answers are also written in Markdown with the command, file, and stack names set off as code, so they read well in the terminal.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/ai-ask-interactive#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>Ask as usual. With the Claude Code CLI installed, Atmos prompts when approval is needed:</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 ai ask </span><span class="token string" style="color:rgb(173, 219, 103)">"how many stacks do we have?"</span><br></div></code></pre></div></div>
<p>Approvals you choose to keep are saved in <code>.atmos/ai.settings.local.json</code>. For Bash commands, Always allow applies to that exact command, so a different command asks again.</p>
<p>One setting now controls how tool requests are approved. The new <code>ai.tools.mode</code> option replaces the pair of booleans <code>yolo_mode</code> and <code>require_confirmation</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">ai</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line 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><br></div><div class="token-line 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 class="token plain"></span></span><br></div><div class="token-line 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"> require_confirmation   </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># default: prompt for tools that need approval</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># mode: allow                # never prompt; ai.tools.blocked still applies</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># mode: yolo                 # never prompt and skip the blocked and restricted checks</span></span><br></div></code></pre></div></div>
<p>The old settings still work as aliases, and <code>mode</code> wins when both are set. The <a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/ai/tools">AI tools configuration</a> page describes each mode.</p>
<p>Follow-up questions and selection lists appear only when both input and output are a terminal and the command is not running in CI. When you pipe the output or run in a pipeline, <code>ask</code> prints the answer and exits, and a command that would need approval fails with an error that names it and suggests <code>mode: allow</code>.</p>
<p>If you configure <code>mcp.servers</code>, Atmos used to start Claude Code with every tool call pre-approved. For <code>ask</code> and <a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/ai/exec"><code>exec</code></a>, those calls now go through the same approval as everything else. Set <code>ai.tools.mode: allow</code> for unattended runs, or <code>yolo</code> in an isolated runner.</p>
<p>An empty answer, for example when Claude Code runs out of turns, is now reported as an error with a hint to raise <code>ai.providers.claude-code.max_turns</code>, instead of printing a blank line.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/ai-ask-interactive#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>This feature is experimental. If an approval, a question, or a follow-up does not behave the way you expect, <a href="https://github.com/cloudposse/atmos/issues" target="_blank" rel="noopener noreferrer" class="">open an issue</a> with the command you ran and what you saw.</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[Declare and Lock AI Skills with Version Tracks]]></title>
        <id>https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/declarative-ai-skills</id>
        <link href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/declarative-ai-skills"/>
        <updated>2026-10-09T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Shared AI skills need a record of where they came from and which revision a project uses.]]></summary>
        <content type="html"><![CDATA[<p>Shared AI skills need a record of where they came from and which revision a project uses.
<a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/ai/skills#declarative-sources">Declarative skill sources</a> put that selection in
Atmos configuration and lock each contributing repository for repeatable installation.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/declarative-ai-skills#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>Installing a repository manually records an action, but does not give a team a shared declaration
of the skills, plugins, clients, and versions their project needs. A marketplace may also reference
plugins in other repositories, each advancing independently.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/declarative-ai-skills#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>Declare sources under <code>ai.skills</code> and commit the resulting skills lock. Configuration commands edit
those declarations independently of installation. Project installations have their own ownership
records, and ordinary synchronization retains obsolete copies until you explicitly prune them.</p>
<p>Managed refs can use the <a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/functions/yaml/version">version function</a> to follow an Atmos version track.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/declarative-ai-skills#how-to-use-it" class="hash-link" aria-label="Direct link to How to Use It" title="Direct link to How to Use It" translate="no">​</a></h2>
<div class="language-shell codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-shell codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A"><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos ai skill </span><span class="token function" style="color:rgb(130, 170, 255)">add</span><span class="token plain"> cloudposse/atmos </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--name</span><span class="token plain"> cloudposse</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos ai skill </span><span class="token builtin class-name" style="color:rgb(255, 203, 139)">set</span><span class="token plain"> cloudposse plugins </span><span class="token string" style="color:rgb(173, 219, 103)">'[atmos]'</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos ai skill </span><span class="token function" style="color:rgb(130, 170, 255)">sync</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos ai skill </span><span class="token function" style="color:rgb(130, 170, 255)">sync</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--frozen</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos ai skill </span><span class="token function" style="color:rgb(130, 170, 255)">sync</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--check</span><br></div></code></pre></div></div>
<p>Commit <code>skills.lock.yaml</code> and ignore <code>.atmos/skills/</code>. See the
<a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/ai/skills#declarative-sources">configuration reference</a> for managed versions,
local sources, explicit pruning, and recovery.</p>
<h3 class="anchor anchorTargetStickyNavbar_cA1_" id="migrating-claude-code-automation">Migrating Claude Code Automation<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/declarative-ai-skills#migrating-claude-code-automation" class="hash-link" aria-label="Direct link to Migrating Claude Code Automation" title="Direct link to Migrating Claude Code Automation" translate="no">​</a></h3>
<p>Existing MCP configurations previously caused Claude Code to approve every tool automatically.
The <code>atmos ai chat</code>, <code>atmos ai ask</code>, and <code>atmos ai exec</code> commands now enforce
<a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/ai/providers#claude-code-tool-approval">Atmos tool permissions</a> for
requests Claude delegates to Atmos. Native and provider-preapproved requests follow Claude’s
own permission policy.
With the default confirmation policy, unattended runs fail when a tool needs approval.</p>
<p>Before upgrading CI jobs, set an explicit policy. For example, <code>allow</code> avoids prompts while
still enforcing blocked tools on delegated requests:</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">ai</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line 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><br></div><div class="token-line 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"> allow</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">blocked</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)">"Edit"</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)">"Write"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span></span><br></div></code></pre></div></div>
<p>For narrower approvals, configure <code>ai.providers.claude-code.allowed_tools</code> with the specific
Claude Code tools your job needs. The <code>yolo</code> mode bypasses all Atmos permission checks,
including blocked tools. Edition pins do not restore the former implicit approval.
See the <a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/ai/exec#claude-code-tool-permissions">automation migration guide</a>.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/declarative-ai-skills#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>Report issues and share your workflows in the <a href="https://github.com/cloudposse/atmos" target="_blank" rel="noopener noreferrer" class="">Atmos repository</a>.</p>]]></content>
        <author>
            <name>Erik Osterman</name>
            <uri>https://github.com/osterman</uri>
        </author>
        <category label="Feature" term="Feature"/>
        <category label="Breaking Change" term="Breaking Change"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Deliver GitOps Changes Through Pull Requests]]></title>
        <id>https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/gitops-pull-request-delivery</id>
        <link href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/gitops-pull-request-delivery"/>
        <updated>2026-10-09T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[In most GitOps setups the deployment repository is protected. Nothing lands on main without review, because whatever reaches main is what Argo CD or Flux applies to the cluster. Delivering rendered manifests into that repository has meant giving the deploy pipeline permission to push straight to the branch the cluster reconciles from, which skips the review step the repository exists to enforce. Git provision targets can now deliver through a pull request.]]></summary>
        <content type="html"><![CDATA[<p>In most GitOps setups the deployment repository is protected. Nothing lands on <code>main</code> without review, because whatever reaches <code>main</code> is what Argo CD or Flux applies to the cluster. Delivering rendered manifests into that repository has meant giving the deploy pipeline permission to push straight to the branch the cluster reconciles from, which skips the review step the repository exists to enforce. Git provision targets can now deliver through a pull request.</p>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/gitops-pull-request-delivery#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>A <a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/stacks/components/kubernetes#publishing-through-a-pull-request">git provision target</a> renders the manifests for a Helm, Helmfile, or Kubernetes component and commits them to a deployment repository. Until now it could only push to the repository's configured branch. Teams that protect that branch had two options: open an exception for the deploy identity, or wrap Atmos in scripts that create a branch, push it, and call the forge API to open a pull request.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/gitops-pull-request-delivery#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>Set <code>pull_request.enabled</code> on the target. Atmos commits the rendered manifests to a head branch, pushes it (never the base), and opens a pull request into the repository's branch, or into the remote's default branch when none is configured. If that pull request already exists, Atmos updates it.</p>
<ul>
<li class="">Re-deliveries stack onto the open branch as new commits, and the same pull request updates in place. Atmos never force-pushes.</li>
<li class="">Identical re-deliveries create no commit. A rerun still reconciles the pull request, which recovers a run where the push succeeded but the pull request call failed.</li>
<li class="">GitHub and Azure DevOps are both supported, and Atmos detects which one from the repository URI. Title, body, labels, reviewers, assignees, and draft status are configurable, and the text fields support templates.</li>
</ul>
<p>This applies everywhere a git target is used: <code>atmos helm deploy</code>, <code>atmos helmfile template --target</code>, and <code>atmos kubernetes apply</code> / <code>deploy</code>.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/gitops-pull-request-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">git</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">repositories</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">deployments</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">      </span><span class="token key atrule">uri</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> https</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain">//github.com/acme/deployments.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">branch</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> main               </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># the pull request base</span><span class="token plain"></span></span><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">helm</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">    </span><span class="token key atrule">monitoring</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line 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)">"clusters/{{ .vars.stage }}/monitoring"</span><span class="token plain"></span></span><br></div><div class="token-line 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">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 class="token plain"></span></span><br></div><div class="token-line 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)">"Deploy monitoring to {{ .vars.stage }}"</span><span class="token plain"></span></span><br></div><div class="token-line 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">gitops</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">              </span><span class="token key atrule">reviewers</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token plain">platform</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">team</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 helm deploy monitoring </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">-s</span><span class="token plain"> plat-ue2-dev </span><span class="token parameter variable" style="color:rgb(214, 222, 235)">--target</span><span class="token plain"> deployment-repo</span><br></div></code></pre></div></div>
<p>Git credentials work as they already do for git targets, including <code>GIT_CONFIG_*</code> headers set in CI. The pull request API token comes from <code>GITHUB_TOKEN</code> (or <code>ATMOS_CI_GITHUB_TOKEN</code> / <code>GH_TOKEN</code>) for GitHub, and from <code>AZURE_DEVOPS_EXT_PAT</code> for Azure DevOps. See <a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/stacks/components/kubernetes#publishing-through-a-pull-request">Publishing through a pull request</a> for every option.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="try-it-out">Try it out<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/gitops-pull-request-delivery#try-it-out" class="hash-link" aria-label="Direct link to Try it out" title="Direct link to Try it out" translate="no">​</a></h2>
<div class="example_jMgJ"><div class="theme-tabs-container tabs-container tabList_oBn1"><ul role="tablist" aria-orientation="horizontal" class="tabs"><li role="tab" tabindex="-1" aria-selected="false" class="tabs__item tabItem_A3p1">Install Atmos</li><li role="tab" tabindex="0" aria-selected="true" class="tabs__item tabItem_A3p1 tabs__item--active">Try the example</li></ul><div class="margin-top--md"><div role="tabpanel" class="tabItem_gg6W" hidden=""><div class="install-widget install-widget--docs"><div class="install-widget__content"><div class="install-widget__select-wrapper"><span class="install-widget__label">Quick Install</span><select class="install-widget__select" aria-label="Installation method"><option value="0" selected="">Quick Install</option><option value="1">macOS</option><option value="2">Windows</option><option value="3">Docker</option></select><svg class="install-widget__chevron" width="12" height="8" viewBox="0 0 12 8" fill="none"><path d="M1 1.5L6 6.5L11 1.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path></svg></div><div class="install-widget__command"><code class="install-widget__code"><span class="install-widget__command-curl">curl -fsSL</span> <span class="install-widget__command-url">https://atmos.tools/install.sh</span> | <span class="install-widget__command-bash">bash</span></code></div><button class="install-widget__copy" type="button" aria-label="Copy installation command" title="Copy to clipboard"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="5" y="5" width="9" height="9" rx="1" stroke="currentColor" stroke-width="1.5"></rect><path d="M3 11V3C3 2.44772 3.44772 2 4 2H11" stroke="currentColor" stroke-width="1.5"></path></svg></button></div></div><div class="links_ZD8T"><a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/install">Installation guide →</a><a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/examples/gitops">Explore the example →</a></div></div><div role="tabpanel" class="tabItem_gg6W"><p>Copy the example into a new directory and make it your 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 init examples/gitops</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)">cd</span><span class="token plain"> gitops</span><br></div></code></pre></div></div><p>Git and network access are required to clone the configured repository. Follow the README for publishing and pull requests.</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 </span><span class="token function" style="color:rgb(130, 170, 255)">git</span><span class="token plain"> clone deploy</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">atmos </span><span class="token function" style="color:rgb(130, 170, 255)">git</span><span class="token plain"> status deploy</span><br></div></code></pre></div></div><div class="links_ZD8T"><a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/examples/gitops">Explore the example →</a><a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/init#examples-and-source-directories">Initialization and repository settings</a></div></div></div></div></div>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/gitops-pull-request-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 it on your deployment repository and tell us how it fits your review flow in <a href="https://github.com/cloudposse/atmos/discussions" target="_blank" rel="noopener noreferrer" class="">GitHub Discussions</a> or the <a href="https://cloudposse.com/slack" target="_blank" rel="noopener noreferrer" class="">SweetOps Slack</a>.</p>]]></content>
        <author>
            <name>Dmytro Bondar</name>
            <uri>https://github.com/bonddim</uri>
        </author>
        <category label="Feature" term="Feature"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Plain Logs Without Losing Terminal Color]]></title>
        <id>https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/log-color-controls</id>
        <link href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/log-color-controls"/>
        <updated>2026-10-09T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Comparing debug logs is harder when ANSI color escapes appear in the files, even after you ask for plain output. Atmos now consistently honors global color opt-outs and adds an independent log color setting, so you can save plain logs while keeping your terminal UI colored.]]></summary>
        <content type="html"><![CDATA[<p>Comparing debug logs is harder when ANSI color escapes appear in the files, even after you ask for plain output. Atmos now consistently honors global color opt-outs and adds an independent <a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/logs">log color setting</a>, so you can save plain logs while keeping your terminal UI colored.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/log-color-controls#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>As reported in <a href="https://github.com/cloudposse/atmos/issues/3342" target="_blank" rel="noopener noreferrer" class="">issue #3342</a>, <code>--no-color</code> could still produce colored debug logs in GitHub Actions. Forced color could also override the flag. In our reproduction, 19 of 20 log lines contained ANSI escapes despite the explicit opt-out.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/log-color-controls#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-3459.atmos-docs.ue2.dev.plat.cloudposse.org/cli/global-flags"><code>--no-color</code> flag</a> and a nonempty <code>NO_COLOR</code> environment variable now take precedence throughout startup, logging, and UI output, including when color is forced. GitHub Actions still gets color by default because it supports it.</p>
<p>The new boolean <code>logs.color</code> setting controls Atmos log color independently:</p>
<ul>
<li class=""><code>true</code> (the default) uses color when available, following existing terminal and CI detection.</li>
<li class=""><code>false</code> removes ANSI escapes from logs, including preformatted log messages.</li>
</ul>
<p>Use the existing <code>--force-color</code> or <code>ATMOS_FORCE_COLOR=true</code> controls to force color when log color is enabled. Global color opt-outs always win.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/log-color-controls#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>Disable log color in your project configuration:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockTitle_JJ7b">atmos.yaml</div><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token key atrule">logs</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">color</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token boolean important" style="color:rgb(255, 88, 116)">false</span></span><br></div></code></pre></div></div>
<p>Or save a plain debug log for one invocation while retaining terminal UI colors:</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 --logs-level</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">debug --logs-file</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">/tmp/atmos.log --logs-color</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">false version</span><br></div></code></pre></div></div>
<p>You can also set <code>ATMOS_LOGS_COLOR=false</code>. The command-line flag takes precedence over the environment variable, which takes precedence over configuration. These controls affect Atmos logs; child-process output keeps its own color settings.</p>
<p>To disable color throughout Atmos, including its UI, use:</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 --logs-level</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">debug --logs-file</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">/tmp/atmos.log --no-color version</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/log-color-controls#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-3459.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/logs">logging documentation</a> for configuration details. If you encounter another color opt-out regression, <a href="https://github.com/cloudposse/atmos/issues/new/choose" target="_blank" rel="noopener noreferrer" class="">open an issue</a> with your command and terminal or CI environment.</p>]]></content>
        <author>
            <name>Erik Osterman</name>
            <uri>https://github.com/osterman</uri>
        </author>
        <category label="Feature" term="Feature"/>
        <category label="Bug Fix" term="Bug Fix"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Your .tool-versions Now Picks the Terraform Every Component Runs]]></title>
        <id>https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/tool-versions-baseline</id>
        <link href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/tool-versions-baseline"/>
        <updated>2026-10-09T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[You pin hashicorp/terraform 1.15.8 in .tool-versions, run atmos terraform plan, and Atmos quietly runs whatever Terraform happens to be first on your PATH — a Homebrew upgrade, a teammate's tfenv shim, or an older binary on a CI runner. The Terraform versions guide promised the pinned version; components didn't deliver it. Now every command and component uses .tool-versions as its baseline.]]></summary>
        <content type="html"><![CDATA[<p>You pin <code>hashicorp/terraform 1.15.8</code> in <code>.tool-versions</code>, run <code>atmos terraform plan</code>, and Atmos quietly runs whatever Terraform happens to be first on your <code>PATH</code> — a Homebrew upgrade, a teammate's tfenv shim, or an older binary on a CI runner. The <a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/howto/manage-terraform-versions">Terraform versions guide</a> promised the pinned version; components didn't deliver it. Now every command and component uses <code>.tool-versions</code> as its baseline.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/tool-versions-baseline#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>Atmos already reads <code>.tool-versions</code> for <code>atmos toolchain</code> commands and workflows, but component runs only looked at explicit <code>dependencies.tools</code> in stack configuration. A project that pinned its tools in one file still got whatever executable the machine offered when it ran <code>atmos terraform plan</code>, <code>atmos helmfile diff</code>, or a <code>!terraform.output</code> lookup. Custom commands and hooks ignored the file too.</p>
<p>Fixing that naively would create new problems. Many <code>.tool-versions</code> files are shared with asdf or mise and list tools Atmos doesn't manage (<code>nodejs</code>, <code>python</code>) or versions like <code>system</code>. And nobody wants <code>atmos describe stacks</code> to download every tool in the file just to evaluate a template.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/tool-versions-baseline#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>The project's <code>.tool-versions</code> is now a baseline for every command and <a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/stacks/dependencies#project-defaults">component type</a>, with installs limited to what a run actually executes:</p>
<ul>
<li class=""><strong>Components</strong> install their own executable when the file pins it — <code>terraform</code>, <code>tofu</code> when the component sets <code>command: tofu</code>, <code>helmfile</code> (plus <code>helm</code>), <code>packer</code>, or <code>ansible</code>. Other tools in the file are added to <code>PATH</code> only if they're already installed. Nothing else is downloaded during a component run, including read-only commands like <code>describe</code>, <code>plan --dry-run</code>, and <code>terraform version</code>.</li>
<li class=""><strong>Every Atmos command</strong> inherits already-installed versions selected by the file on <code>PATH</code>. Cached tools absent from the file, and other cached versions, are not added.</li>
<li class=""><strong>Custom commands and hooks</strong> install only their own <code>dependencies.tools</code>.</li>
<li class=""><strong>Workflows</strong> keep their existing behavior: they install every listed tool that is missing before the first step.</li>
</ul>
<p>How much Atmos installs on its own is a setting, so you can make it more or less eager (see <a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/tool-versions-baseline#control-what-atmos-installs" class="">Control What Atmos Installs</a>).</p>
<p>Explicit <code>dependencies.tools</code> always win, even when one side uses a short name or alias and the other uses <code>owner/repo</code>. Entries Atmos can't use — <code>system</code>, <code>ref:</code> and <code>path:</code> versions, unknown tools, lines without a version, or <code>~&gt; 1.15.0</code> written with a space — are skipped instead of failing the run. Two entries for the same tool with different versions (<code>tofu 1.12.6</code> and <code>opentofu/opentofu 1.11.0</code>) now stop with an error naming both, instead of picking one at random.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/tool-versions-baseline#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>Pin the tool once:</p>
<div class="language-text codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockTitle_JJ7b">.tool-versions</div><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">hashicorp/terraform 1.15.8</span><br></div></code></pre></div></div>
<p>Every component without an override runs Terraform 1.15.8, installing it on first use. Override a single component when it needs something else:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockTitle_JJ7b">stacks/deploy/prod.yaml</div><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token key atrule">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">legacy-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">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">tools</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line 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 class="token string" style="color:rgb(173, 219, 103)">"1.15.6"</span></span><br></div></code></pre></div></div>
<p>Running <code>legacy-vpc</code> uses 1.15.6 and leaves <code>.tool-versions</code> untouched. If your configuration points at a different manifest, <a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/toolchain"><code>toolchain.file_path</code></a> is now honored everywhere.</p>
<p>If a component previously relied on a binary from <code>PATH</code> while <code>.tool-versions</code> pinned a different version, it now runs the pinned version. Remove or update the pin, or set <code>dependencies.tools</code> on the component, to keep the old binary.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="control-what-atmos-installs">Control What Atmos Installs<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/tool-versions-baseline#control-what-atmos-installs" class="hash-link" aria-label="Direct link to Control What Atmos Installs" title="Direct link to Control What Atmos Installs" translate="no">​</a></h2>
<p>The new <a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/toolchain#install"><code>toolchain.install</code></a> setting controls downloads separately from version selection. Every command inherits installed project selections under every policy; explicit <code>dependencies.tools</code> override them. The setting decides which missing tools Atmos installs on its own:</p>
<div class="language-yaml codeBlockContainer_W6UR theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockTitle_JJ7b">atmos.yaml</div><div class="codeBlockContent_gU9i"><pre tabindex="0" class="prism-code language-yaml codeBlock_dlrW thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_YA7A codeBlockLinesWithNumbering_UQ30" style="counter-reset:line-count 0"><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token key atrule">toolchain</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">install</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> auto   </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># never | declared | auto | always</span></span><br></div></code></pre></div></div>
<ul>
<li class=""><code>never</code> installs nothing. Tools are used only when they are already installed, and a missing <code>dependencies.tools</code> entry fails with a hint to run <code>atmos toolchain install</code>. Use it on air-gapped runners or when an image bakes in every tool.</li>
<li class=""><code>declared</code> installs only explicit <code>dependencies.tools</code> (and, for workflows, every <code>.tool-versions</code> tool). Other runs use already-installed project selections without installing missing defaults.</li>
<li class=""><code>auto</code> is the default and the behavior described above.</li>
<li class=""><code>always</code> installs every tool in <code>.tool-versions</code> for every run, including custom commands and hooks.</li>
</ul>
<p>Projects pinned to an <a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/cli/configuration/edition">edition</a> dated before 2026-10-09 keep <code>declared</code> automatically, preserving their automatic download policy. Installed project selections still supply the baseline under every policy. Set <code>ATMOS_TOOLCHAIN_INSTALL</code> to override the setting for a single run.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/tool-versions-baseline#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>Questions or edge cases with your <code>.tool-versions</code>? Open an issue or join the conversation in the <a href="https://cloudposse.com/slack" target="_blank" rel="noopener noreferrer" class="">Cloud Posse community</a>.</p>]]></content>
        <author>
            <name>Erik Osterman</name>
            <uri>https://github.com/osterman</uri>
        </author>
        <category label="Enhancement" term="Enhancement"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Start an Atmos Project from Any Example Directory]]></title>
        <id>https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/initialize-from-examples</id>
        <link href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/initialize-from-examples"/>
        <updated>2026-10-08T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Trying Atmos for the first time should be easy. Install it, check out an example, and run it. Now you can with atmos init.]]></summary>
        <content type="html"><![CDATA[<p>Trying Atmos for the first time should be easy. Install it, check out an example, and run it. Now you can with <a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/init"><code>atmos init</code></a>.</p>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-problem">The Problem<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/initialize-from-examples#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem" translate="no">​</a></h2>
<p>Someone new to Atmos should be able to kick the tires almost immediately. A working example provides the configuration, stacks, and components to start exploring with just a few commands.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="the-fix">The Fix<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/initialize-from-examples#the-fix" class="hash-link" aria-label="Direct link to The Fix" title="Direct link to The Fix" translate="no">​</a></h2>
<p>Start with any of the <a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/examples">official Atmos examples</a>. Atmos copies the example verbatim, including examples that contain a scaffold manifest.</p>
<p>The same command also works with directories in other Git repositories, supported remote sources, and local directories. These sources use scaffold generation when a root manifest exists and copy their contents otherwise.</p>
<p>Git sources use a single shallow fetch to avoid downloading repository history. Configure <code>init.depth</code> for any repository: use <code>1</code> for the latest revision or <code>0</code> for full history. A source URL's explicit <code>depth</code> parameter takes precedence. The CLI prints the actual destination and displays the example's README when present.</p>
<p>Copies preserve literal template content, dotfiles, executable permissions, and empty directories while excluding Git metadata. Existing template names and interactive selection continue to work.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="how-to-use-it">How to Use It<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/initialize-from-examples#how-to-use-it" class="hash-link" aria-label="Direct link to How to Use It" title="Direct link to How to Use It" translate="no">​</a></h2>
<p>The quick start below initializes a complete project and lists its stacks. The destination defaults
to the source directory's name. Supply a second argument to choose another destination:</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 init examples/quick-start-simple ./my-project</span><br></div></code></pre></div></div>
<p>Configure <a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/init#examples-and-source-directories">initialization defaults</a> in <code>atmos.yaml</code> to use your team's repository and revision:</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">init</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">repository</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> github.com/acme/starters</span></span><br></div><div class="token-line 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"> main</span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">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)">1</span><span class="token plain"></span></span><br></div><div class="token-line codeLine_MYOh" style="color:#d6deeb"><span class="codeLineNumber_C7H_"></span><span class="codeLineContent_hnsy"><span class="token plain">  </span><span class="token key atrule">git</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>The repository defaults to <code>github.com/cloudposse/atmos</code>. Git initialization and an initial commit are enabled by default; set <code>git: false</code> or pass <code>--no-git</code> to skip them. Explicit source URLs bypass the default repository, and a revision embedded in the source takes precedence over <code>--ref</code> and configuration.</p>
<p>Use <code>--copy</code> to copy another source verbatim even when it contains a scaffold manifest. Copy mode skips template rendering and scaffold hooks, requires an empty destination unless <code>--force</code> is supplied, and does not support scaffold updates or template variables. Read the <a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/init">init reference</a> for source formats, precedence, and overwrite behavior.</p>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="try-it-out">Try it out<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/initialize-from-examples#try-it-out" class="hash-link" aria-label="Direct link to Try it out" title="Direct link to Try it out" translate="no">​</a></h2>
<div class="example_jMgJ"><div class="theme-tabs-container tabs-container tabList_oBn1"><ul role="tablist" aria-orientation="horizontal" class="tabs"><li role="tab" tabindex="-1" aria-selected="false" class="tabs__item tabItem_A3p1">Install Atmos</li><li role="tab" tabindex="0" aria-selected="true" class="tabs__item tabItem_A3p1 tabs__item--active">Try the example</li></ul><div class="margin-top--md"><div role="tabpanel" class="tabItem_gg6W" hidden=""><div class="install-widget install-widget--docs"><div class="install-widget__content"><div class="install-widget__select-wrapper"><span class="install-widget__label">Quick Install</span><select class="install-widget__select" aria-label="Installation method"><option value="0" selected="">Quick Install</option><option value="1">macOS</option><option value="2">Windows</option><option value="3">Docker</option></select><svg class="install-widget__chevron" width="12" height="8" viewBox="0 0 12 8" fill="none"><path d="M1 1.5L6 6.5L11 1.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path></svg></div><div class="install-widget__command"><code class="install-widget__code"><span class="install-widget__command-curl">curl -fsSL</span> <span class="install-widget__command-url">https://atmos.tools/install.sh</span> | <span class="install-widget__command-bash">bash</span></code></div><button class="install-widget__copy" type="button" aria-label="Copy installation command" title="Copy to clipboard"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="5" y="5" width="9" height="9" rx="1" stroke="currentColor" stroke-width="1.5"></rect><path d="M3 11V3C3 2.44772 3.44772 2 4 2H11" stroke="currentColor" stroke-width="1.5"></path></svg></button></div></div><div class="links_ZD8T"><a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/install">Installation guide →</a><a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/examples/quick-start-simple">Explore the example →</a></div></div><div role="tabpanel" class="tabItem_gg6W"><p>Copy the example into a new directory and make it your 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 init examples/quick-start-simple</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)">cd</span><span class="token plain"> quick-start-simple</span><br></div></code></pre></div></div><p>Inspect the example stacks. Install Terraform before continuing with the README's component walkthrough.</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 stacks</span><br></div></code></pre></div></div><div class="links_ZD8T"><a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/examples/quick-start-simple">Explore the example →</a><a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/cli/commands/init#examples-and-source-directories">Initialization and repository settings</a></div></div></div></div></div>
<h2 class="anchor anchorTargetStickyNavbar_cA1_" id="get-involved">Get Involved<a href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/changelog/initialize-from-examples#get-involved" class="hash-link" aria-label="Direct link to Get Involved" title="Direct link to Get Involved" translate="no">​</a></h2>
<p>Explore the <a class="" href="https://pr-3459.atmos-docs.ue2.dev.plat.cloudposse.org/examples">examples</a> and share your experience in <a href="https://github.com/cloudposse/atmos/discussions" target="_blank" rel="noopener noreferrer" class="">GitHub Discussions</a>.</p>]]></content>
        <author>
            <name>Erik Osterman</name>
            <uri>https://github.com/osterman</uri>
        </author>
        <category label="Feature" term="Feature"/>
        <category label="DX" term="DX"/>
    </entry>
</feed>