<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>OpenTofu Blog</title>
        <link>https://opentofu.org/blog</link>
        <description>OpenTofu Blog</description>
        <lastBuildDate>Fri, 25 Apr 2025 00:00:00 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <item>
            <title><![CDATA[Help us test OpenTofu 1.10.0-alpha2]]></title>
            <link>https://opentofu.org/blog/help-us-test-opentofu-1-10-0-alpha2</link>
            <guid>https://opentofu.org/blog/help-us-test-opentofu-1-10-0-alpha2</guid>
            <pubDate>Fri, 25 Apr 2025 00:00:00 GMT</pubDate>
            <description><![CDATA[Hello, OpenTofu community! We're thrilled to announce the second alpha release of OpenTofu 1.10.0! We have been hard at work adding new features, fixing bugs, and iterating with community feedback. This alpha delivers several long awaited features that we know you have been rooting for.]]></description>
            <content:encoded><![CDATA[<p>Hello, OpenTofu community! We're thrilled to announce the second alpha release of OpenTofu 1.10.0! We have been hard at work adding new features, fixing bugs, and iterating with community feedback. This alpha delivers several long awaited features that we know you have been rooting for.</p>
<p>Your involvement is crucial as we refine these features. If you have a <strong>non-production</strong> environment where you could test any of these new capabilities, we'd be grateful for your help. Even if everything works perfectly (which we hope it does!), your <a href="https://github.com/opentofu/opentofu/issues/new/choose" target="_blank" rel="noopener noreferrer">feedback via GitHub issues</a> is invaluable to ensuring 1.10.0 becomes the rock-solid release our community deserves.</p>
<div class="flex flex-col py-2 px-3 not-prose border gap-1 [&amp;+&amp;]:mt-3 [&amp;_a:hover]:text-gray-900 dark:[&amp;_a:hover]:text-gray-50 [&amp;_a>code]:font-bold [&amp;_code]:text-base [&amp;_code]:px-1.5 [&amp;_a]:underline [&amp;_p]:mb-2 bg-yellow-100 border-yellow-500 text-yellow-800 dark:bg-yellow-950 dark:border-yellow-700 dark:text-yellow-100" role="alert"><div class="flex gap-3 font-bold"><span class="flex w-4 fill-current [&amp;>svg]:w-full" aria-hidden="true"><svg viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"></path></svg></span>Warning</div><div class="leading-relaxed"><p>Do not test this release on a production project! It is not a stable release!</p></div></div>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="downloading-the-alpha-release">Downloading the alpha release<a href="https://opentofu.org/blog/help-us-test-opentofu-1-10-0-alpha2#downloading-the-alpha-release" class="hash-link" aria-label="Direct link to Downloading the alpha release" title="Direct link to Downloading the alpha release">​</a></h2>
<p>The alpha release is available exclusively from the <a href="https://github.com/opentofu/opentofu/releases/tag/v1.10.0-alpha2" target="_blank" rel="noopener noreferrer">GitHub Releases page</a>. Please select the appropriate file for your platform. Here are some quick links:</p>
<table><thead><tr><th>Platform/Device</th><th>Download link</th></tr></thead><tbody><tr><td><strong>Desktop Windows computer</strong><br>(64-bit)</td><td><a href="https://github.com/opentofu/opentofu/releases/download/v1.10.0-alpha2/tofu_1.10.0-alpha2_windows_amd64.zip" target="_blank" rel="noopener noreferrer">tofu_1.10.0-alpha2_windows_amd64.zip</a></td></tr><tr><td><strong>MacOS</strong><br>(Macbook M1 or higher; ARM64)</td><td><a href="https://github.com/opentofu/opentofu/releases/download/v1.10.0-alpha2/tofu_1.10.0-alpha2_darwin_arm64.tar.gz" target="_blank" rel="noopener noreferrer">tofu_1.10.0-alpha2_darwin_arm64.tar.gz</a></td></tr><tr><td><strong>MacOS</strong><br>(Macbook pre-M1; AMD64)</td><td><a href="https://github.com/opentofu/opentofu/releases/download/v1.10.0-alpha2/tofu_1.10.0-alpha2_darwin_amd64.tar.gz" target="_blank" rel="noopener noreferrer">tofu_1.10.0-alpha2_darwin_amd64.tar.gz</a></td></tr><tr><td><strong>Intel/AMD Linux computer or server</strong><br>(AMD64)</td><td><a href="https://github.com/opentofu/opentofu/releases/download/v1.10.0-alpha2/tofu_1.10.0-alpha2_linux_amd64.tar.gz" target="_blank" rel="noopener noreferrer">tofu_1.10.0-alpha2_linux_amd64.tar.gz</a></td></tr><tr><td><strong>ARM-based Linux computer<br>or<br>Raspberry Pi 3 or higher</strong><br>(ARM64)</td><td><a href="https://github.com/opentofu/opentofu/releases/download/v1.10.0-alpha2/tofu_1.10.0-alpha2_linux_arm64.tar.gz" target="_blank" rel="noopener noreferrer">tofu_1.10.0-alpha2_linux_arm64.tar.gz</a></td></tr></tbody></table>
<p>After downloading one of the releases above, unpack the archive to find your <code>tofu</code> binary. For those who prefer verified downloads, you can also use the <a href="https://opentofu.org/docs/intro/install/standalone/" target="_blank" rel="noopener noreferrer">standalone installer</a> with signature verification.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="the-building-blocks-of-1100">The Building Blocks of 1.10.0<a href="https://opentofu.org/blog/help-us-test-opentofu-1-10-0-alpha2#the-building-blocks-of-1100" class="hash-link" aria-label="Direct link to The Building Blocks of 1.10.0" title="Direct link to The Building Blocks of 1.10.0">​</a></h2>
<p>If you're just joining us for alpha 2, OpenTofu 1.10.0 is bringing several groundbreaking features to the table:</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="oci-registry-integration">OCI Registry Integration<a href="https://opentofu.org/blog/help-us-test-opentofu-1-10-0-alpha2#oci-registry-integration" class="hash-link" aria-label="Direct link to OCI Registry Integration" title="Direct link to OCI Registry Integration">​</a></h3>
<p>OpenTofu now seamlessly integrates with OCI registries for both provider distribution and module installation (new for alpha 2). This is a game-changer for private, air-gapped environments and teams looking for more flexible ways to distribute their infrastructure components.</p>
<p>Configure provider installation from OCI Registries with a <code>oci_mirror</code> block:</p>
<div class="language-hcl codeBlockContainer_APcc theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_m3Ux"><figure><figcaption class="sr-only">Code Block</figcaption><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div><pre tabindex="0" class="prism-code language-hcl codeBlock_qGQc thin-scrollbar" style="color:#F8F8F2;background-color:#282A36" role="code" aria-label="Code Block"><code class="codeBlockLines_p187"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">provider_installation</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">oci_mirror</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">repository_template</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"example.com/opentofu-providers/</span><span class="token string interpolation punctuation" style="color:rgb(248, 248, 242)">$</span><span class="token string interpolation punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token string interpolation" style="color:rgb(255, 121, 198)">namespace</span><span class="token string interpolation punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token string" style="color:rgb(255, 121, 198)">/</span><span class="token string interpolation punctuation" style="color:rgb(248, 248, 242)">$</span><span class="token string interpolation punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token string interpolation" style="color:rgb(255, 121, 198)">type</span><span class="token string interpolation punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token string" style="color:rgb(255, 121, 198)">"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">include</span><span class="token plain">             </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token string" style="color:rgb(255, 121, 198)">"registry.opentofu.org/*/*"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre></figure></div></div>
<p>Or install modules directly using the new <code>oci:</code> source scheme:</p>
<div class="language-hcl codeBlockContainer_APcc theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_m3Ux"><figure><figcaption class="sr-only">Code Block</figcaption><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div><pre tabindex="0" class="prism-code language-hcl codeBlock_qGQc thin-scrollbar" style="color:#F8F8F2;background-color:#282A36" role="code" aria-label="Code Block"><code class="codeBlockLines_p187"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">module</span><span class="token keyword type variable" style="color:rgb(189, 147, 249);font-style:italic"> "vpc" </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">source</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"oci://example.com/modules/vpc/aws"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre></figure></div></div>
<p>For more information, see our <a href="https://opentofu.org/blog/help-us-test-opentofu-1-10-0-alpha1/#provider-distribution-through-oci-registries" target="_blank" rel="noopener noreferrer">alpha 1 blog post</a> for provider instructions and <a href="https://opentofu.org/docs/main/cli/oci_registries/module-package/" target="_blank" rel="noopener noreferrer">our latest docs</a> for module instructions.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="simplified-state-management-with-native-s3-locking">Simplified State Management with Native S3 Locking<a href="https://opentofu.org/blog/help-us-test-opentofu-1-10-0-alpha2#simplified-state-management-with-native-s3-locking" class="hash-link" aria-label="Direct link to Simplified State Management with Native S3 Locking" title="Direct link to Simplified State Management with Native S3 Locking">​</a></h3>
<p>Why use two services when one will do? The <code>s3</code> backend now supports native locking without requiring DynamoDB, streamlining your state management in AWS environments with the simple addition of <code>use_lockfile</code>:</p>
<div class="language-hcl codeBlockContainer_APcc theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_m3Ux"><figure><figcaption class="sr-only">Code Block</figcaption><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div><pre tabindex="0" class="prism-code language-hcl codeBlock_qGQc thin-scrollbar" style="color:#F8F8F2;background-color:#282A36" role="code" aria-label="Code Block"><code class="codeBlockLines_p187"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">terraform</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">backend</span><span class="token keyword type variable" style="color:rgb(189, 147, 249);font-style:italic"> "s3" </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">bucket</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"tofu-state-backend"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">key</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"statefile"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">region</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"us-east-1"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">use_lockfile</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token boolean">true</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre></figure></div></div>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="peek-behind-the-curtain-with-opentelemetry-tracing">Peek Behind the Curtain with OpenTelemetry Tracing<a href="https://opentofu.org/blog/help-us-test-opentofu-1-10-0-alpha2#peek-behind-the-curtain-with-opentelemetry-tracing" class="hash-link" aria-label="Direct link to Peek Behind the Curtain with OpenTelemetry Tracing" title="Direct link to Peek Behind the Curtain with OpenTelemetry Tracing">​</a></h3>
<p>Ever wondered what's happening under the hood during those long provider installations? Alpha 2 introduces experimental OpenTelemetry (OTel) tracing that gives you unprecedented visibility into OpenTofu's operations.</p>
<div class="flex flex-col py-2 px-3 not-prose border gap-1 [&amp;+&amp;]:mt-3 [&amp;_a:hover]:text-gray-900 dark:[&amp;_a:hover]:text-gray-50 [&amp;_a>code]:font-bold [&amp;_code]:text-base [&amp;_code]:px-1.5 [&amp;_a]:underline [&amp;_p]:mb-2 bg-sky-100 border-sky-300 text-sky-800 dark:bg-sky-950 dark:border-sky-700 dark:text-sky-100" role="alert"><div class="flex gap-3 font-bold"><span class="flex w-4 fill-current [&amp;>svg]:w-full" aria-hidden="true"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>Note</div><div class="leading-relaxed"><p>Although this builds on a project named Open<em>Telemetry</em>, we are adding this support explicitly for you to trace <em>your application</em> using <em>your tooling</em> on <em>your infrastructure</em>. To be absolutely clear: we are <em>not</em> adding telemetry that will phone home to us or anyone else.</p></div></div>
<p>Getting started with tracing takes two steps. First, launch a tracing backend like Jaeger:</p>
<div class="language-bash codeBlockContainer_APcc theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_m3Ux"><figure><figcaption class="sr-only">Code Block</figcaption><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div><pre tabindex="0" class="prism-code language-bash codeBlock_qGQc thin-scrollbar" style="color:#F8F8F2;background-color:#282A36" role="code" aria-label="Code Block"><code class="codeBlockLines_p187"><span class="token-line" style="color:#F8F8F2"><span class="token plain">docker run -d --rm --name jaeger \</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  -p 16686:16686 \</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  -p 4317:4317 \</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  -p 4318:4318 \</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  -p 5778:5778 \</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  -p 9411:9411 \</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  jaegertracing/jaeger:2.5.0</span><br></span></code></pre></figure></div></div>
<p>Then tell OpenTofu to use it with these environment variables:</p>
<div class="language-bash codeBlockContainer_APcc theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_m3Ux"><figure><figcaption class="sr-only">Code Block</figcaption><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div><pre tabindex="0" class="prism-code language-bash codeBlock_qGQc thin-scrollbar" style="color:#F8F8F2;background-color:#282A36" role="code" aria-label="Code Block"><code class="codeBlockLines_p187"><span class="token-line" style="color:#F8F8F2"><span class="token plain"># Required variables</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">export OTEL_TRACES_EXPORTER=otlp</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">export OTEL_EXPORTER_OTLP_INSECURE=true</span><br></span></code></pre></figure></div></div>
<p>Now you can watch your OpenTofu operations unfold in real-time through the Jaeger UI at <a href="http://localhost:16686/" target="_blank" rel="noopener noreferrer">http://localhost:16686</a>. Currently, tracing describes:</p>
<ul>
<li>Provider installation and downloads</li>
<li>Lock file operations</li>
</ul>
<p>This is just the beginning – future releases will expand tracing to cover even more of your OpenTofu workflow. Let us know what areas you want more insight into!</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="deprecation-for-module-variables-and-outputs">Deprecation for module variables and outputs<a href="https://opentofu.org/blog/help-us-test-opentofu-1-10-0-alpha2#deprecation-for-module-variables-and-outputs" class="hash-link" aria-label="Direct link to Deprecation for module variables and outputs" title="Direct link to Deprecation for module variables and outputs">​</a></h3>
<p>It is now possible to communicate variable and output deprecation via the <code>deprecated</code> attribute! Module
authors are able to mark variables and outputs as deprecated by including a suggestion on how to migrate. Module callers will receive a warning if their configuration is affected. Here is an example of configuration:</p>
<div class="language-hcl codeBlockContainer_APcc theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_m3Ux"><figure><figcaption class="sr-only">Code Block</figcaption><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div><pre tabindex="0" class="prism-code language-hcl codeBlock_qGQc thin-scrollbar" style="color:#F8F8F2;background-color:#282A36" role="code" aria-label="Code Block"><code class="codeBlockLines_p187"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">variable</span><span class="token keyword type variable" style="color:rgb(189, 147, 249);font-style:italic"> "examle" </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">type</span><span class="token plain">       </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> string</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">deprecated</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"'examle' variable must no longer be used due to a typo, use 'example' instead"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">output</span><span class="token keyword type variable" style="color:rgb(189, 147, 249);font-style:italic"> "examle" </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">value</span><span class="token plain">      </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"someval"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">deprecated</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"'examle' output must no longer be used due to a typo, use 'example' instead"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre></figure></div></div>
<p>For more information, see <a href="https://1-10-0-alpha2-blog.opentofu.pages.dev/docs/main/language/values/variables/#marking-variable-as-deprecated" target="_blank" rel="noopener noreferrer">marking variable as deprecated</a> and <a href="https://1-10-0-alpha2-blog.opentofu.pages.dev/docs/main/language/values/outputs/#deprecated--marking-output-as-deprecated" target="_blank" rel="noopener noreferrer">marking output as deprecated</a></p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="global-provider-cache-locking">Global Provider Cache Locking<a href="https://opentofu.org/blog/help-us-test-opentofu-1-10-0-alpha2#global-provider-cache-locking" class="hash-link" aria-label="Direct link to Global Provider Cache Locking" title="Direct link to Global Provider Cache Locking">​</a></h3>
<p>The <a href="https://opentofu.org/docs/cli/config/config-file/#provider-plugin-cache" target="_blank" rel="noopener noreferrer">Global Provider Plugin Cache</a> allows OpenTofu to download providers into a shared cache directory. Prior to this release, it was not safe to use this with multiple instances of OpenTofu running in parallel as they could clobber each other. We now have added support for filesystem level locking to this cache!</p>
<div class="language-sh codeBlockContainer_APcc theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_m3Ux"><figure><figcaption class="sr-only">Code Block</figcaption><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div><pre tabindex="0" class="prism-code language-sh codeBlock_qGQc thin-scrollbar" style="color:#F8F8F2;background-color:#282A36" role="code" aria-label="Code Block"><code class="codeBlockLines_p187"><span class="token-line" style="color:#F8F8F2"><span class="token plain">export TF_PLUGIN_CACHE_DIR=/storage/tofu/cache</span><br></span></code></pre></figure></div></div>
<p>This now means the global provider plugin cache is safe for tofu to use concurrently:</p>
<ul>
<li>With your CI system that runs dozens of <code>tofu init</code>s in parallel</li>
<li>With your orchestration tool that runs multiple pipelines at the same time</li>
<li>With all of your Terragrunt projects and stacks</li>
</ul>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="multi-project-postgresql-state-management">Multi-Project PostgreSQL State Management<a href="https://opentofu.org/blog/help-us-test-opentofu-1-10-0-alpha2#multi-project-postgresql-state-management" class="hash-link" aria-label="Direct link to Multi-Project PostgreSQL State Management" title="Direct link to Multi-Project PostgreSQL State Management">​</a></h3>
<p>The <code>pg</code> backend gets a significant upgrade with the ability to specify custom table and index names, unlocking multi-project state management within a single database schema:</p>
<div class="language-hcl codeBlockContainer_APcc theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_m3Ux"><figure><figcaption class="sr-only">Code Block</figcaption><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div><pre tabindex="0" class="prism-code language-hcl codeBlock_qGQc thin-scrollbar" style="color:#F8F8F2;background-color:#282A36" role="code" aria-label="Code Block"><code class="codeBlockLines_p187"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">terraform</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">backend</span><span class="token keyword type variable" style="color:rgb(189, 147, 249);font-style:italic"> "pg" </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">conn_str</span><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"postgres://user:pass@db.example.com/database"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">schema_name</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"opentofu"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">table_name</span><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"project_a_state"</span><span class="token plain">  </span><span class="token comment" style="color:rgb(98, 114, 164)"># Default is "terraform_state"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">index_name</span><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"project_a_index"</span><span class="token plain">  </span><span class="token comment" style="color:rgb(98, 114, 164)"># Default is "terraform_state_idx"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre></figure></div></div>
<p>We've also solved an issue that could cause state corruption when sharing a database between different OpenTofu versions, making your state storage more robust than ever.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="resource-migration-with-moved">Resource Migration with <code>moved</code><a href="https://opentofu.org/blog/help-us-test-opentofu-1-10-0-alpha2#resource-migration-with-moved" class="hash-link" aria-label="Direct link to resource-migration-with-moved" title="Direct link to resource-migration-with-moved">​</a></h3>
<p>The <code>moved</code> block now supports migration between entirely different resource types:</p>
<div class="language-hcl codeBlockContainer_APcc theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_m3Ux"><figure><figcaption class="sr-only">Code Block</figcaption><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div><pre tabindex="0" class="prism-code language-hcl codeBlock_qGQc thin-scrollbar" style="color:#F8F8F2;background-color:#282A36" role="code" aria-label="Code Block"><code class="codeBlockLines_p187"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">moved</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">from</span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain">gpg_key.this</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">to</span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain">gpg_key_pair.this</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre></figure></div></div>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="fine-grained-resource-removal-with-removed">Fine-Grained Resource Removal with <code>removed</code><a href="https://opentofu.org/blog/help-us-test-opentofu-1-10-0-alpha2#fine-grained-resource-removal-with-removed" class="hash-link" aria-label="Direct link to fine-grained-resource-removal-with-removed" title="Direct link to fine-grained-resource-removal-with-removed">​</a></h3>
<p>The <code>removed</code> block now supports <code>lifecycle</code> and <code>provisioner</code> configurations:</p>
<div class="language-hcl codeBlockContainer_APcc theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_m3Ux"><figure><figcaption class="sr-only">Code Block</figcaption><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div><pre tabindex="0" class="prism-code language-hcl codeBlock_qGQc thin-scrollbar" style="color:#F8F8F2;background-color:#282A36" role="code" aria-label="Code Block"><code class="codeBlockLines_p187"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">removed</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">from</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> aws_instance.example</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">lifecycle</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">destroy</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token boolean">true</span><span class="token plain">  </span><span class="token comment" style="color:rgb(98, 114, 164)"># Destroys the resource (default is false which just forgets it)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token comment" style="color:rgb(98, 114, 164)"># Provisioners will run before destruction when destroy = true</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">provisioner</span><span class="token keyword type variable" style="color:rgb(189, 147, 249);font-style:italic"> "local-exec" </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">when</span><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> destroy</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">command</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"echo 'Cleaning up before destroying resource'"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre></figure></div></div>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="streamlined-resource-planning">Streamlined Resource Planning<a href="https://opentofu.org/blog/help-us-test-opentofu-1-10-0-alpha2#streamlined-resource-planning" class="hash-link" aria-label="Direct link to Streamlined Resource Planning" title="Direct link to Streamlined Resource Planning">​</a></h3>
<p>The new <code>-target-file</code> and <code>-exclude-file</code> options transform how you manage complex deployments, allowing you to maintain consistent target and exclusion patterns across your team:</p>
<div class="language-bash codeBlockContainer_APcc theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_m3Ux"><figure><figcaption class="sr-only">Code Block</figcaption><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div><pre tabindex="0" class="prism-code language-bash codeBlock_qGQc thin-scrollbar" style="color:#F8F8F2;background-color:#282A36" role="code" aria-label="Code Block"><code class="codeBlockLines_p187"><span class="token-line" style="color:#F8F8F2"><span class="token plain"># Target specific resources listed in targets.txt</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">tofu plan -target-file=targets.txt</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"># Exclude specific resources listed in excludes.txt</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">tofu apply -exclude-file=excludes.txt</span><br></span></code></pre></figure></div></div>
<p>No more copy-pasting long resource addresses – just reference your carefully maintained resource lists.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="flexible-state-encryption-with-external-key-providers">Flexible State Encryption with External Key Providers<a href="https://opentofu.org/blog/help-us-test-opentofu-1-10-0-alpha2#flexible-state-encryption-with-external-key-providers" class="hash-link" aria-label="Direct link to Flexible State Encryption with External Key Providers" title="Direct link to Flexible State Encryption with External Key Providers">​</a></h3>
<p>Security-conscious teams will appreciate the new external key providers for state encryption, bringing unprecedented flexibility to your secret management approach:</p>
<div class="language-hcl codeBlockContainer_APcc theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_m3Ux"><figure><figcaption class="sr-only">Code Block</figcaption><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div><pre tabindex="0" class="prism-code language-hcl codeBlock_qGQc thin-scrollbar" style="color:#F8F8F2;background-color:#282A36" role="code" aria-label="Code Block"><code class="codeBlockLines_p187"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">terraform</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">encryption</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    key_provider </span><span class="token string" style="color:rgb(255, 121, 198)">"external"</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"password_manager"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token property">command</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token string" style="color:rgb(255, 121, 198)">"./state_encryption_key.sh"</span><span class="token plain">, </span><span class="token string" style="color:rgb(255, 121, 198)">"some_parameter"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre></figure></div></div>
<p>The PBKDF2 key provider now supports chaining, allowing you to compose multiple key providers:</p>
<div class="language-hcl codeBlockContainer_APcc theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_m3Ux"><figure><figcaption class="sr-only">Code Block</figcaption><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div><pre tabindex="0" class="prism-code language-hcl codeBlock_qGQc thin-scrollbar" style="color:#F8F8F2;background-color:#282A36" role="code" aria-label="Code Block"><code class="codeBlockLines_p187"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">terraform</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">encryption</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    key_provider </span><span class="token string" style="color:rgb(255, 121, 198)">"external"</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"password_manager"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token property">command</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token string" style="color:rgb(255, 121, 198)">"./get_password.sh"</span><span class="token plain">, </span><span class="token string" style="color:rgb(255, 121, 198)">"some_parameter"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    key_provider </span><span class="token string" style="color:rgb(255, 121, 198)">"pbkdf2"</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"passphrase"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token property">chain</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> key_provider.external.password_manager</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre></figure></div></div>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="and-thats-not-all">And That's Not All<a href="https://opentofu.org/blog/help-us-test-opentofu-1-10-0-alpha2#and-thats-not-all" class="hash-link" aria-label="Direct link to And That's Not All" title="Direct link to And That's Not All">​</a></h3>
<p>Alpha 2 packs numerous other quality-of-life improvements:</p>
<ul>
<li>The <code>element</code> function now accepts negative indices, with <code>-1</code> selecting the last element</li>
<li>Test <code>run</code> outputs can now be referenced in test <code>provider</code> blocks</li>
<li>Force-unlock capability now extends to the HTTP backend</li>
<li>Plan outputs now show forgotten resources count, improving visibility into state changes</li>
</ul>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="before-you-upgrade">Before You Upgrade<a href="https://opentofu.org/blog/help-us-test-opentofu-1-10-0-alpha2#before-you-upgrade" class="hash-link" aria-label="Direct link to Before You Upgrade" title="Direct link to Before You Upgrade">​</a></h2>
<p>As with any significant release, there are some key compatibility points to consider:</p>
<ul>
<li>On Linux, OpenTofu now requires kernel version 3.2 or later</li>
<li>On macOS, OpenTofu now requires macOS 11 Big Sur or later</li>
<li>OpenTofu 1.10 with the <code>pg</code> backend should not be used alongside older versions</li>
<li>The <code>ghcr.io/opentofu/opentofu</code> image is no longer supported as a base image</li>
<li>On Windows, symbolic links and junctions are now handled differently</li>
</ul>
<p>For complete details, please review the <a href="https://github.com/opentofu/opentofu/blob/v1-10-0-alpha2/CHANGELOG.md" target="_blank" rel="noopener noreferrer">full changelog</a>.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="join-the-testing-effort">Join the Testing Effort<a href="https://opentofu.org/blog/help-us-test-opentofu-1-10-0-alpha2#join-the-testing-effort" class="hash-link" aria-label="Direct link to Join the Testing Effort" title="Direct link to Join the Testing Effort">​</a></h2>
<p>OpenTofu 1.10.0 is shaping up to be a landmark release, and your input can help make it truly exceptional. Whether you're intrigued by the OCI registry integration, excited about native S3 locking, or curious about OpenTelemetry tracing, we'd love your feedback.</p>
<p>Share your testing experiences through <a href="https://github.com/opentofu/opentofu/issues/new/choose" target="_blank" rel="noopener noreferrer">GitHub issues</a> or join the conversation in the <a href="https://opentofu.org/slack/" target="_blank" rel="noopener noreferrer">OpenTofu Slack</a>. Every bit of feedback brings us closer to a rock-solid 1.10.0 release.</p>
<p>Thank you!</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Help us test OpenTofu 1.10.0-alpha1]]></title>
            <link>https://opentofu.org/blog/help-us-test-opentofu-1-10-0-alpha1</link>
            <guid>https://opentofu.org/blog/help-us-test-opentofu-1-10-0-alpha1</guid>
            <pubDate>Fri, 28 Mar 2025 00:00:00 GMT</pubDate>
            <description><![CDATA[Hello, OpenTofu community! Today we are proud to announce the first preprelease version of 1.10.0. The new version comes with a few highly anticipated features: provider distribution through OCI registries, native state locking support for s3 backend and many more! We are kindly asking for your help in testing OpenTofu 1.10.0-alpha1.]]></description>
            <content:encoded><![CDATA[<p>Hello, OpenTofu community! Today we are proud to announce the first preprelease version of 1.10.0. The new version comes with a few highly anticipated features: provider distribution through OCI registries, native state locking support for <code>s3</code> backend and many more! We are kindly asking for your help in testing OpenTofu 1.10.0-alpha1.</p>
<p>We have done everything we could to make sure that the new alpha release doesn't break anything, and we need your help to get this release tested. If you have a <strong>non-production</strong> setup that you would be willing to test any of the new features on, please give it a try and give us <a href="https://github.com/opentofu/opentofu/issues/new/choose" target="_blank" rel="noopener noreferrer">feedback using a GitHub issue</a>, even if it's just telling us that everything went well.</p>
<p>This blog post will go over how to download the new preview release and detail how each of the new features works.</p>
<div class="flex flex-col py-2 px-3 not-prose border gap-1 [&amp;+&amp;]:mt-3 [&amp;_a:hover]:text-gray-900 dark:[&amp;_a:hover]:text-gray-50 [&amp;_a>code]:font-bold [&amp;_code]:text-base [&amp;_code]:px-1.5 [&amp;_a]:underline [&amp;_p]:mb-2 bg-yellow-100 border-yellow-500 text-yellow-800 dark:bg-yellow-950 dark:border-yellow-700 dark:text-yellow-100" role="alert"><div class="flex gap-3 font-bold"><span class="flex w-4 fill-current [&amp;>svg]:w-full" aria-hidden="true"><svg viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"></path></svg></span>Warning</div><div class="leading-relaxed"><p>Do not test this release on a production project! It is not a stable release!</p></div></div>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="downloading-the-alpha-release">Downloading the alpha release<a href="https://opentofu.org/blog/help-us-test-opentofu-1-10-0-alpha1#downloading-the-alpha-release" class="hash-link" aria-label="Direct link to Downloading the alpha release" title="Direct link to Downloading the alpha release">​</a></h2>
<p>The alpha release is available exclusively from the <a href="https://github.com/opentofu/opentofu/releases/tag/v1.10.0-alpha1" target="_blank" rel="noopener noreferrer">GitHub Releases page</a>. Please select the appropriate file for your platform. Here are some quick links:</p>
<table><thead><tr><th>Platform/Device</th><th>Download link</th></tr></thead><tbody><tr><td><strong>Desktop Windows computer</strong><br>(64-bit)</td><td><a href="https://github.com/opentofu/opentofu/releases/download/v1.10.0-alpha1/tofu_1.10.0-alpha1_windows_amd64.zip" target="_blank" rel="noopener noreferrer">tofu_1.10.0-alpha1_windows_amd64.zip</a></td></tr><tr><td><strong>MacOS</strong><br>(Macbook M1 or higher; ARM64)</td><td><a href="https://github.com/opentofu/opentofu/releases/download/v1.10.0-alpha1/tofu_1.10.0-alpha1_darwin_arm64.tar.gz" target="_blank" rel="noopener noreferrer">tofu_1.10.0-alpha1_darwin_arm64.tar.gz</a></td></tr><tr><td><strong>MacOS</strong><br>(Macbook pre-M1; AMD64)</td><td><a href="https://github.com/opentofu/opentofu/releases/download/v1.10.0-alpha1/tofu_1.10.0-alpha1_darwin_amd64.tar.gz" target="_blank" rel="noopener noreferrer">tofu_1.10.0-alpha1_darwin_amd64.tar.gz</a></td></tr><tr><td><strong>Intel/AMD Linux computer or server</strong><br>(AMD64)</td><td><a href="https://github.com/opentofu/opentofu/releases/download/v1.10.0-alpha1/tofu_1.10.0-alpha1_linux_amd64.tar.gz" target="_blank" rel="noopener noreferrer">tofu_1.10.0-alpha1_linux_amd64.tar.gz</a></td></tr><tr><td><strong>ARM-based Linux computer<br>or<br>Raspberry Pi 3 or higher</strong><br>(ARM64)</td><td><a href="https://github.com/opentofu/opentofu/releases/download/v1.10.0-alpha1/tofu_1.10.0-alpha1_linux_arm64.tar.gz" target="_blank" rel="noopener noreferrer">tofu_1.10.0-alpha1_linux_arm64.tar.gz</a></td></tr></tbody></table>
<p>For the releases above, please unpack the archive and you should find the <code>tofu</code> binary inside. You can also use the <a href="https://opentofu.org/docs/intro/install/standalone/" target="_blank" rel="noopener noreferrer">standalone installer</a> to download the release with signature verification.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="provider-distribution-through-oci-registries">Provider distribution through OCI registries<a href="https://opentofu.org/blog/help-us-test-opentofu-1-10-0-alpha1#provider-distribution-through-oci-registries" class="hash-link" aria-label="Direct link to Provider distribution through OCI registries" title="Direct link to Provider distribution through OCI registries">​</a></h2>
<p>One of OpenTofu's top-voted issues is to support distribution of providers and modules through OCI registries. This release brings the first part of it - now you can use OCI registries to install a copy of a provider through a special "provider mirror" location.</p>
<p>Creating a local mirror of some or all of the providers you use can reduce data transfer costs and can help with running OpenTofu in "air-gapped" environments that cannot access any services over the public internet.</p>
<p>Alternative provider installation methods are configured as part of <a href="https://opentofu.org/docs/main/cli/config/config-file/" target="_blank" rel="noopener noreferrer">the OpenTofu CLI Configuration</a>. You can configure installation from OCI Registries using an <code>oci_mirror</code> block as part of your <a href="https://opentofu.org/docs/main/cli/config/config-file/#explicit-installation-method-configuration" target="_blank" rel="noopener noreferrer">Explicit Installation Method Configuration</a>:</p>
<div class="language-hcl codeBlockContainer_APcc theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_m3Ux"><figure><figcaption class="sr-only">Code Block</figcaption><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div><pre tabindex="0" class="prism-code language-hcl codeBlock_qGQc thin-scrollbar" style="color:#F8F8F2;background-color:#282A36" role="code" aria-label="Code Block"><code class="codeBlockLines_p187"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">provider_installation</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">oci_mirror</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">repository_template</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"example.com/opentofu-providers/</span><span class="token string interpolation punctuation" style="color:rgb(248, 248, 242)">$</span><span class="token string interpolation punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token string interpolation" style="color:rgb(255, 121, 198)">namespace</span><span class="token string interpolation punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token string" style="color:rgb(255, 121, 198)">/</span><span class="token string interpolation punctuation" style="color:rgb(248, 248, 242)">$</span><span class="token string interpolation punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token string interpolation" style="color:rgb(255, 121, 198)">type</span><span class="token string interpolation punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token string" style="color:rgb(255, 121, 198)">"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">include</span><span class="token plain">             </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token string" style="color:rgb(255, 121, 198)">"registry.opentofu.org/*/*"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre></figure></div></div>
<p>The above example specifies that any provider that belongs to the primary OpenTofu Registry should instead be installed from a repository in an OCI registry, constructing the repository address dynamically using the components of the provider source address.</p>
<p>We also prepared <a href="https://github.com/opentofu-v1-10-alpha-testing" target="_blank" rel="noopener noreferrer">a full-featured guide</a> on how to test OCI Registry Provider Mirrors.</p>
<p>For more information, please refer to <a href="https://opentofu.org/docs/main/cli/oci_registries/provider-mirror/" target="_blank" rel="noopener noreferrer">the documentation</a>. Also, you can check out our progress via the <a href="https://github.com/opentofu/opentofu/issues/2540" target="_blank" rel="noopener noreferrer">Provider and module packages from OCI registries RFC Tracker</a>.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="native-locking-support-for-s3-backend">Native locking support for <code>s3</code> backend<a href="https://opentofu.org/blog/help-us-test-opentofu-1-10-0-alpha1#native-locking-support-for-s3-backend" class="hash-link" aria-label="Direct link to native-locking-support-for-s3-backend" title="Direct link to native-locking-support-for-s3-backend">​</a></h2>
<p>Now, OpenTofu can leverage native <code>s3</code> conditional writes to eliminate the need of DynamoDB to handle locks. This allows you to rely on a single cloud service to handle both storage and locking of the state file. Please, keep in mind, not all of the s3-compatible storage support this feature yet.</p>
<p>We introduced a new <code>use_lockfile</code> field, which makes OpenTofu create a separate lock file in the same bucket:</p>
<div class="language-hcl codeBlockContainer_APcc theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_m3Ux"><figure><figcaption class="sr-only">Code Block</figcaption><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div><pre tabindex="0" class="prism-code language-hcl codeBlock_qGQc thin-scrollbar" style="color:#F8F8F2;background-color:#282A36" role="code" aria-label="Code Block"><code class="codeBlockLines_p187"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">terraform</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">backend</span><span class="token keyword type variable" style="color:rgb(189, 147, 249);font-style:italic"> "s3" </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">bucket</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"tofu-state-backend"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">key</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"statefile"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">region</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"us-east-1"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">use_lockfile</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token boolean">true</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre></figure></div></div>
<p>For more information, please refer to <a href="https://opentofu.org/docs/main/language/settings/backends/s3/#s3-state-locking" target="_blank" rel="noopener noreferrer">the documentation of the s3 backend</a>.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="what-else">What else?<a href="https://opentofu.org/blog/help-us-test-opentofu-1-10-0-alpha1#what-else" class="hash-link" aria-label="Direct link to What else?" title="Direct link to What else?">​</a></h2>
<p>This release brings a lot more other enhancements such as:</p>
<ul>
<li>External programs as key providers for state encryption;</li>
<li>The <code>element</code> function now accepts negative indices;</li>
<li><code>moved</code> now supports moving between different types;</li>
<li>Multiple enhancements for <code>tofu test</code>;</li>
<li>Count of forgotten resources in plan and apply outputs;</li>
<li>and much more!</li>
</ul>
<p>You can find <a href="https://github.com/opentofu/opentofu/blob/57376f6ec64da8adaa271c1610396fbb86ada549/CHANGELOG.md" target="_blank" rel="noopener noreferrer">the detailed changelog here</a>.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="providing-feedback">Providing feedback<a href="https://opentofu.org/blog/help-us-test-opentofu-1-10-0-alpha1#providing-feedback" class="hash-link" aria-label="Direct link to Providing feedback" title="Direct link to Providing feedback">​</a></h2>
<p>Thank you for taking the time to test this preview release. If you have any feedback, please use <a href="https://github.com/opentofu/opentofu/issues/new/choose" target="_blank" rel="noopener noreferrer">a GitHub issue</a> or chat with us on the <a href="https://opentofu.org/slack/" target="_blank" rel="noopener noreferrer">OpenTofu Slack</a>.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[OpenTofu 1.9.0 is available now with provider for_each]]></title>
            <link>https://opentofu.org/blog/opentofu-1-9-0</link>
            <guid>https://opentofu.org/blog/opentofu-1-9-0</guid>
            <pubDate>Fri, 10 Jan 2025 00:00:00 GMT</pubDate>
            <description><![CDATA[OpenTofu 1.9.0 available now with provider for_each, a much-requested feature that makes multi-zone deployments easier and reduces code duplication.]]></description>
            <content:encoded><![CDATA[<p>Today marks the one-year anniversary of the <a href="https://opentofu.org/blog/opentofu-is-going-ga/">1.6 release</a> and we are proud to announce the immediate availability of <a href="https://github.com/opentofu/opentofu/releases/tag/v1.9.0" target="_blank" rel="noopener noreferrer">OpenTofu 1.9.0</a> with a number of features the community has been requesting for some time. Chief among them is provider <code>for_each</code> allowing for easier multi-zone or multi-region deployments. In detail, this release brings:</p>
<ul>
<li>Provider iteration (<code>for_each</code>)</li>
<li>The <code>-exclude</code> flag</li>
<li>Improvements to early evaluation, encryption, AzureRM and HTTP backends</li>
<li>Several new CLI options</li>
<li>Significant performance improvements</li>
</ul>
<p>You can find the full list of improvements and changes on the <a href="https://opentofu.org/docs/intro/whats-new/">What's new in OpenTofu 1.9?</a> page.</p>
<p>In line with our support policy, this release also means that OpenTofu 1.6 is no longer supported and we will not release security updates for it anymore. If you are still using 1.6, please upgrade to at least 1.7.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="massive-growth-300-increase-in-registry-traffic-rising-download-numbers">Massive growth: ~300% increase in registry traffic, rising download numbers<a href="https://opentofu.org/blog/opentofu-1-9-0#massive-growth-300-increase-in-registry-traffic-rising-download-numbers" class="hash-link" aria-label="Direct link to Massive growth: ~300% increase in registry traffic, rising download numbers" title="Direct link to Massive growth: ~300% increase in registry traffic, rising download numbers">​</a></h2>
<p>Yes, you read that right. While our previous release showed <a href="https://opentofu.org/blog/opentofu-1-8-0/">an increase of roughly 30% over a period of 4 months</a>, in the current release the amount of registry requests have tripled to over 6 million requests per day, peaking at a data transfer of over 140 GB per day.</p>
<p><img loading="lazy" alt="A graph showing the OpenTofu registry requests per day" src="https://opentofu.org/assets/images/opentofu-registry-january-2025-6393738f09aa82db216469ab600ef556.svg" width="1542" height="620" class="img_ev3q"></p>
<p>Similarly, the number of GitHub downloads has risen significantly by about 30% in the 1.8 release to almost 1.5 million downloads. Interestingly, we had over 5000 downloads on the 1.9 prerelease versions.</p>
<p><img loading="lazy" alt="A graph showing the OpenTofu GitHub downloads by version" src="https://opentofu.org/assets/images/opentofu-downloads-january-2025-67f8e998d3a72ee3a8f9500de9460c3e.svg" width="1542" height="620" class="img_ev3q">
<img loading="lazy" alt="A graph showing the OpenTofu GitHub downloads by OS" src="https://opentofu.org/assets/images/opentofu-downloads-by-os-january-2025-930454829922d259798e1a4470fd171f.svg" width="1542" height="620" class="img_ev3q"></p>
<p>Apart from users, we also have a very active community helping out with reporting issues, fixing bugs, and helping newcomers with questions. The number of GitHub stars grew to over 23.000, we have received over 150 new issues and the community has been <a href="https://github.com/opentofu/opentofu/issues/1496" target="_blank" rel="noopener noreferrer">actively voting on them</a>. For this release, our community has contributed over 200 pull requests with features and bugfixes from 49 contributors on the main repository alone.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="opentofu-search-beta">OpenTofu Search (beta)<a href="https://opentofu.org/blog/opentofu-1-9-0#opentofu-search-beta" class="hash-link" aria-label="Direct link to OpenTofu Search (beta)" title="Direct link to OpenTofu Search (beta)">​</a></h2>
<p>Since our last release, we have indexed the documentation of over 4.000 providers and over 20.000 modules in the <a href="https://search.opentofu.org/" target="_blank" rel="noopener noreferrer">OpenTofu Search</a> interface. This was a monumental effort producing over 146 GB of raw data and the project updates the documentation for new provider and module versions every 15-30 minutes. Thanks to the generous sponsorship by Cloudflare, our costs for maintaining this infrastructure are minimal. It took over 12.000 lines of combined Go and Typescript code to accomplish.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="jetbrains-support">JetBrains support<a href="https://opentofu.org/blog/opentofu-1-9-0#jetbrains-support" class="hash-link" aria-label="Direct link to JetBrains support" title="Direct link to JetBrains support">​</a></h2>
<p>In their 2024.3 release, <a href="https://www.jetbrains.com/idea/whatsnew/2024-3/" target="_blank" rel="noopener noreferrer">JetBrains has announced support for OpenTofu</a>. The integration switches to OpenTofu when it detects a <code>.tofu</code> file in a project and provides OpenTofu-specific code completion, such as state encryption.</p>
<p><img loading="lazy" alt="A screenshot showing OpenTofu support in Goland" src="https://opentofu.org/assets/images/jetbrains-opentofu-support-d55181557e8d07e4685bd7b7f7e41742.png" width="1366" height="754" class="img_ev3q"></p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="visual-studio-code-integration">Visual Studio Code integration<a href="https://opentofu.org/blog/opentofu-1-9-0#visual-studio-code-integration" class="hash-link" aria-label="Direct link to Visual Studio Code integration" title="Direct link to Visual Studio Code integration">​</a></h2>
<p>In parallel, the OpenTofu core team started working with the community on <a href="https://github.com/opentofu/vscode-opentofu" target="_blank" rel="noopener noreferrer">a possible port of the Visual Studio Code extension for OpenTofu</a>.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="future-plans">Future plans<a href="https://opentofu.org/blog/opentofu-1-9-0#future-plans" class="hash-link" aria-label="Direct link to Future plans" title="Direct link to Future plans">​</a></h2>
<p>With provider iteration now implemented, we are turning our attention to the other <a href="https://github.com/opentofu/opentofu/issues/1496" target="_blank" rel="noopener noreferrer">much-requested features</a>. Most importantly, we already have a working prototype for the OCI provider registry and we are also <a href="https://github.com/opentofu/opentofu/pulls?q=is%3Apr+is%3Aopen+oci+rfc" target="_blank" rel="noopener noreferrer">looking for your input on the related RFCs</a>. For more details on upcoming features take a look at the <a href="https://github.com/opentofu/opentofu/milestone/11" target="_blank" rel="noopener noreferrer">1.10.0 planning milestone</a> on GitHub.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Get ready for OpenTofu Beta 1.9.0]]></title>
            <link>https://opentofu.org/blog/opentofu-1-9-0-beta1</link>
            <guid>https://opentofu.org/blog/opentofu-1-9-0-beta1</guid>
            <pubDate>Thu, 05 Dec 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Hey there, OpenTofu community! We've been working hard to refine the 1.9.0-alpha2 with your feedback! A few rough edges have been polished and a few new features have been added.]]></description>
            <content:encoded><![CDATA[<p>Hey there, OpenTofu community! We've been working hard to refine the <a href="https://opentofu.org/blog/help-us-test-opentofu-1-9-0-alpha2/">1.9.0-alpha2</a> with your feedback! A few rough edges have been polished and a few new features have been added.</p>
<p>If you have a <strong>non-production</strong> setup that you would be willing to test any of the new features on, please give it a try and give us <a href="https://github.com/opentofu/opentofu/issues/new/choose" target="_blank" rel="noopener noreferrer">feedback using a GitHub issue</a>, even if it's just telling us that everything went well.</p>
<p>This blog post will go over how to download the new preview release and expand on the features presented in the <a href="https://opentofu.org/blog/help-us-test-opentofu-1-9-0-alpha2/">1.9.0-alpha2 blog post</a>.</p>
<div class="flex flex-col py-2 px-3 not-prose border gap-1 [&amp;+&amp;]:mt-3 [&amp;_a:hover]:text-gray-900 dark:[&amp;_a:hover]:text-gray-50 [&amp;_a>code]:font-bold [&amp;_code]:text-base [&amp;_code]:px-1.5 [&amp;_a]:underline [&amp;_p]:mb-2 bg-yellow-100 border-yellow-500 text-yellow-800 dark:bg-yellow-950 dark:border-yellow-700 dark:text-yellow-100" role="alert"><div class="flex gap-3 font-bold"><span class="flex w-4 fill-current [&amp;>svg]:w-full" aria-hidden="true"><svg viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"></path></svg></span>Warning</div><div class="leading-relaxed"><p>Do not test this release on a production project! It is not a stable release!</p></div></div>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="downloading-the-beta-release">Downloading the beta release<a href="https://opentofu.org/blog/opentofu-1-9-0-beta1#downloading-the-beta-release" class="hash-link" aria-label="Direct link to Downloading the beta release" title="Direct link to Downloading the beta release">​</a></h2>
<p>The beta release is available exclusively from the <a href="https://github.com/opentofu/opentofu/releases/tag/v1.9.0-beta1" target="_blank" rel="noopener noreferrer">GitHub Releases page</a>. Please select the appropriate file for your platform. Here are some quick links:</p>
<table><thead><tr><th>Platform/Device</th><th>Download link</th></tr></thead><tbody><tr><td><strong>Desktop Windows computer</strong><br>(64-bit)</td><td><a href="https://github.com/opentofu/opentofu/releases/download/v1.9.0-beta1/tofu_1.9.0-beta1_windows_amd64.zip" target="_blank" rel="noopener noreferrer">tofu_1.9.0-beta1_windows_amd64.zip</a></td></tr><tr><td><strong>MacOS</strong><br>(Macbook M1 or higher; ARM64)</td><td><a href="https://github.com/opentofu/opentofu/releases/download/v1.9.0-beta1/tofu_1.9.0-beta1_darwin_arm64.tar.gz" target="_blank" rel="noopener noreferrer">tofu_1.9.0-beta1_darwin_arm64.tar.gz</a></td></tr><tr><td><strong>MacOS</strong><br>(Macbook pre-M1; AMD64)</td><td><a href="https://github.com/opentofu/opentofu/releases/download/v1.9.0-beta1/tofu_1.9.0-beta1_darwin_amd64.tar.gz" target="_blank" rel="noopener noreferrer">tofu_1.9.0-beta1_darwin_amd64.tar.gz</a></td></tr><tr><td><strong>Intel/AMD Linux computer or server</strong><br>(AMD64)</td><td><a href="https://github.com/opentofu/opentofu/releases/download/v1.9.0-beta1/tofu_1.9.0-beta1_linux_amd64.tar.gz" target="_blank" rel="noopener noreferrer">tofu_1.9.0-beta1_linux_amd64.tar.gz</a></td></tr><tr><td><strong>ARM-based Linux computer<br>or<br>Raspberry Pi 3 or higher</strong><br>(ARM64)</td><td><a href="https://github.com/opentofu/opentofu/releases/download/v1.9.0-beta1/tofu_1.9.0-beta1_linux_arm64.tar.gz" target="_blank" rel="noopener noreferrer">tofu_1.9.0-beta1_linux_arm64.tar.gz</a></td></tr></tbody></table>
<p>For the releases above, please unpack the archive and you should find the <code>tofu</code> binary inside. You can also use the <a href="https://opentofu.org/docs/intro/install/standalone/" target="_blank" rel="noopener noreferrer">standalone installer</a> to download the release with signature verification.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="provider-iteration-for_each">Provider iteration (<code>for_each</code>)<a href="https://opentofu.org/blog/opentofu-1-9-0-beta1#provider-iteration-for_each" class="hash-link" aria-label="Direct link to provider-iteration-for_each" title="Direct link to provider-iteration-for_each">​</a></h2>
<p>One of the biggest challenges keeping the code clean in a multi-region or multi-zone deployment is the sheer number of providers and related configurations you have to juggle. Essentially, you will have to create duplicated code for each region or zone.</p>
<p>With provider iteration, you can now get rid of your code duplications by iterating over a set of providers instead of the duplicated code. If you have a small-scale setup with one of the cloud providers offering multiple zones, start by adding two variables:</p>
<div class="language-hcl codeBlockContainer_APcc theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_m3Ux"><figure><figcaption class="sr-only">Code Block</figcaption><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div><pre tabindex="0" class="prism-code language-hcl codeBlock_qGQc thin-scrollbar" style="color:#F8F8F2;background-color:#282A36" role="code" aria-label="Code Block"><code class="codeBlockLines_p187"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">variable</span><span class="token keyword type variable" style="color:rgb(189, 147, 249);font-style:italic"> "regions" </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">description</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"A list of regions that should have a deployment."</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">type</span><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> set(string)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">variable</span><span class="token keyword type variable" style="color:rgb(189, 147, 249);font-style:italic"> "disabled_regions" </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">description</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"A list of regions that should be disabled and all resources removed."</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">type</span><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> set(string)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">default</span><span class="token plain">     </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre></figure></div></div>
<p>The <code>regions</code> variable serves as a list of regions you will want to deploy to. The <code>disabled_regions</code> variable will allow you to remove a region later without removing the provider. This feature is extremely important because if you remove the provider without removing its resources, OpenTofu will be unable to remove the resources in that region.</p>
<p>As a next step, you can create your provider declarations. As you can see, this is only a single declaration. The only restriction worth mentioning here is the <code>alias</code>. Due to technical limitations, in this version you can only use <code>for_each</code> in conjunction with <code>alias</code>.</p>
<div class="language-hcl codeBlockContainer_APcc theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_m3Ux"><figure><figcaption class="sr-only">Code Block</figcaption><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div><pre tabindex="0" class="prism-code language-hcl codeBlock_qGQc thin-scrollbar" style="color:#F8F8F2;background-color:#282A36" role="code" aria-label="Code Block"><code class="codeBlockLines_p187"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">provider</span><span class="token keyword type variable" style="color:rgb(189, 147, 249);font-style:italic"> "aws" </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">alias</span><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"by_region"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">region</span><span class="token plain">   </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> each.value</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">for_each</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> var.regions</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre></figure></div></div>
<p>Finally, you can use the provider set to call a submodule. Note that in contrast to the <code>provider</code> block above, the <code>for_each</code> iterates only over the providers that are not disabled. This lets you deprovision a region properly and later completely remove the provider.</p>
<div class="language-hcl codeBlockContainer_APcc theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_m3Ux"><figure><figcaption class="sr-only">Code Block</figcaption><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div><pre tabindex="0" class="prism-code language-hcl codeBlock_qGQc thin-scrollbar" style="color:#F8F8F2;background-color:#282A36" role="code" aria-label="Code Block"><code class="codeBlockLines_p187"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">module</span><span class="token keyword type variable" style="color:rgb(189, 147, 249);font-style:italic"> "deploy" </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">source</span><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"./deploy"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">providers</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">aws</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> aws.by_region</span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token plain">each.key</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">for_each</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> setsubtract(var.regions, var.disabled_regions)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre></figure></div></div>
<p>As this feature is very new, there are a few limitations in place you may want to observe:</p>
<ol>
<li>You can only use <code>for_each</code> on variables and locals that can be obtained statically. Expressions that rely on data sources or resources are currently not usable.</li>
<li>If you have an already-deployed infrastructure, don't simply remove a provider from the list as this will make it impossible for OpenTofu to destroy the infrastructure in this region. Instead, you will need to implement removing that infrastructure first and then remove the provider from the list. See the <code>disabled_regions</code> variable for an example above.</li>
<li>Currently, each provider used in a <code>for_each</code> <strong>must</strong> have an alias. Providers without aliases are not supported for now due to internal technical reasons.</li>
<li>There is currently no way to pass a set of providers to a module, you can only pass individual providers.</li>
</ol>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="the--exclude-flag">The <code>-exclude</code> flag<a href="https://opentofu.org/blog/opentofu-1-9-0-beta1#the--exclude-flag" class="hash-link" aria-label="Direct link to the--exclude-flag" title="Direct link to the--exclude-flag">​</a></h2>
<p>OpenTofu already has a <code>-target</code> option to only plan or apply certain resources. Why not apply everything except a certain resource? This was the thought behind the <code>-exclude</code> flag and, in fact, this was one of the highest upvoted feature requests for this release.</p>
<p>You can test it by creating the following simple configuration:</p>
<div class="language-hcl codeBlockContainer_APcc theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_m3Ux"><figure><figcaption class="sr-only">Code Block</figcaption><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div><pre tabindex="0" class="prism-code language-hcl codeBlock_qGQc thin-scrollbar" style="color:#F8F8F2;background-color:#282A36" role="code" aria-label="Code Block"><code class="codeBlockLines_p187"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">resource </span><span class="token keyword type variable" style="color:rgb(189, 147, 249);font-style:italic">"local_file"</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"a"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">filename</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"a.txt"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">content</span><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"a"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">resource </span><span class="token keyword type variable" style="color:rgb(189, 147, 249);font-style:italic">"local_file"</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"b"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">filename</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"b.txt"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">content</span><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"b"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">resource </span><span class="token keyword type variable" style="color:rgb(189, 147, 249);font-style:italic">"local_file"</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"c"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">filename</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"c.txt"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">content</span><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"c"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre></figure></div></div>
<p>If you run <code>tofu apply -exclude local_file.b</code>, you will see that OpenTofu creates <code>a.txt</code> and <code>c.txt</code>, but not <code>b.txt</code>.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="bugfixes-and-improvements">Bugfixes and improvements<a href="https://opentofu.org/blog/opentofu-1-9-0-beta1#bugfixes-and-improvements" class="hash-link" aria-label="Direct link to Bugfixes and improvements" title="Direct link to Bugfixes and improvements">​</a></h2>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="early-evaluation-improvements">Early evaluation improvements<a href="https://opentofu.org/blog/opentofu-1-9-0-beta1#early-evaluation-improvements" class="hash-link" aria-label="Direct link to Early evaluation improvements" title="Direct link to Early evaluation improvements">​</a></h3>
<p>When using early evaluation introduced in OpenTofu 1.8, OpenTofu will now prompt you for the variables needed for evaluation.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="the-new-encrypted_metadata_alias-option-for-state-encryption">The new <code>encrypted_metadata_alias</code> option for state encryption<a href="https://opentofu.org/blog/opentofu-1-9-0-beta1#the-new-encrypted_metadata_alias-option-for-state-encryption" class="hash-link" aria-label="Direct link to the-new-encrypted_metadata_alias-option-for-state-encryption" title="Direct link to the-new-encrypted_metadata_alias-option-for-state-encryption">​</a></h3>
<p>One of the tricky parts when using state encryption in previous versions is that OpenTofu needs to store the name of the key provider into the encrypted data alongside some metadata needed for decryption. This meant that changing the key provider name would involve using a <code>fallback</code> block and key provider naming for remote state data sources would have to be synchronized. With OpenTofu 1.9, we are introducing a new <code>encrypted_metadata_alias</code> option you can use to explicitly set the ID stored with the encrypted data:</p>
<div class="language-hcl codeBlockContainer_APcc theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_m3Ux"><figure><figcaption class="sr-only">Code Block</figcaption><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div><pre tabindex="0" class="prism-code language-hcl codeBlock_qGQc thin-scrollbar" style="color:#F8F8F2;background-color:#282A36" role="code" aria-label="Code Block"><code class="codeBlockLines_p187"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">terraform</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">encryption</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    key_provider </span><span class="token string" style="color:rgb(255, 121, 198)">"pbkdf2"</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"mykey"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token property">passphrase</span><span class="token plain">               </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"OpenTofu has encryption"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token comment" style="color:rgb(98, 114, 164)"># Note the fixed encrypted_metadata_alias here:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token property">encrypted_metadata_alias</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"certificates"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    method </span><span class="token string" style="color:rgb(255, 121, 198)">"aes_gcm"</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"mymethod"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token property">keys</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> key_provider.pbkdf2.mykey</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">state</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token property">method</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> method.aes_gcm.mymethod</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre></figure></div></div>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="logging-and-other-improvements">Logging and other improvements<a href="https://opentofu.org/blog/opentofu-1-9-0-beta1#logging-and-other-improvements" class="hash-link" aria-label="Direct link to Logging and other improvements" title="Direct link to Logging and other improvements">​</a></h3>
<ul>
<li>You can now use the <code>-consolidate-warnings</code> and <code>-consolidate-errors</code> options to consolidate similar warnings and errors together.</li>
<li>The HTTP backend now supports extended trace logging, including request and response bodies.</li>
<li>OpenTofu will now prompt for values for input variables needed for early evaluation.</li>
<li><code>tofu console</code> now accepts expressions split over multiple lines, when the newline characters appear inside bracketing pairs or when they are escaped using a backslash.</li>
<li><code>tofu test</code> now throws errors instead of warnings for invalid override and mock fields.</li>
<li>Several performance improvements for large graphs and large amounts of submodules.</li>
</ul>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="providing-feedback">Providing feedback<a href="https://opentofu.org/blog/opentofu-1-9-0-beta1#providing-feedback" class="hash-link" aria-label="Direct link to Providing feedback" title="Direct link to Providing feedback">​</a></h2>
<p>Thank you for taking the time to test this preview release. If you have any feedback, please use <a href="https://github.com/opentofu/opentofu/issues/new/choose" target="_blank" rel="noopener noreferrer">a GitHub issue</a> or chat with us on the <a href="https://opentofu.org/slack/" target="_blank" rel="noopener noreferrer">OpenTofu Slack</a>.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Help us test OpenTofu 1.9.0-alpha2]]></title>
            <link>https://opentofu.org/blog/help-us-test-opentofu-1-9-0-alpha2</link>
            <guid>https://opentofu.org/blog/help-us-test-opentofu-1-9-0-alpha2</guid>
            <pubDate>Mon, 11 Nov 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Hello everyone! As we have taken on one of the most difficult tasks since the inception of OpenTofu and it's been a while since we last released a feature version. Today, we are very proud to ask for your help in testing OpenTofu 1.9.0-alpha2, coming with a much-requested feature: provider iteration using for_each. Additionally, this release includes the new -exclude flag for plan and apply.]]></description>
            <content:encoded><![CDATA[<p>Hello everyone! As we have taken on one of the most difficult tasks since the inception of OpenTofu and it's been a while since we last released a feature version. Today, we are very proud to ask for your help in testing OpenTofu 1.9.0-alpha2, coming with a much-requested feature: provider iteration using <code>for_each</code>. Additionally, this release includes the new <code>-exclude</code> flag for plan and apply.</p>
<p>We have done everything we could to make sure that the new alpha release doesn't break anything, and we need your help to get this release tested. If you have a <strong>non-production</strong> setup that you would be willing to test any of the new features on, please give it a try and give us <a href="https://github.com/opentofu/opentofu/issues/new/choose" target="_blank" rel="noopener noreferrer">feedback using a GitHub issue</a>, even if it's just telling us that everything went well.</p>
<p>This blog post will go over how to download the new preview release and detail how each of the new features works.</p>
<div class="flex flex-col py-2 px-3 not-prose border gap-1 [&amp;+&amp;]:mt-3 [&amp;_a:hover]:text-gray-900 dark:[&amp;_a:hover]:text-gray-50 [&amp;_a>code]:font-bold [&amp;_code]:text-base [&amp;_code]:px-1.5 [&amp;_a]:underline [&amp;_p]:mb-2 bg-yellow-100 border-yellow-500 text-yellow-800 dark:bg-yellow-950 dark:border-yellow-700 dark:text-yellow-100" role="alert"><div class="flex gap-3 font-bold"><span class="flex w-4 fill-current [&amp;>svg]:w-full" aria-hidden="true"><svg viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"></path></svg></span>Warning</div><div class="leading-relaxed"><p>Do not test this release on a production project! It is not a stable release!</p></div></div>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="downloading-the-alpha-release">Downloading the alpha release<a href="https://opentofu.org/blog/help-us-test-opentofu-1-9-0-alpha2#downloading-the-alpha-release" class="hash-link" aria-label="Direct link to Downloading the alpha release" title="Direct link to Downloading the alpha release">​</a></h2>
<p>The alpha release is available exclusively from the <a href="https://github.com/opentofu/opentofu/releases/tag/v1.9.0-alpha2" target="_blank" rel="noopener noreferrer">GitHub Releases page</a>. Please select the appropriate file for your platform. Here are some quick links:</p>
<table><thead><tr><th>Platform/Device</th><th>Download link</th></tr></thead><tbody><tr><td><strong>Desktop Windows computer</strong><br>(64-bit)</td><td><a href="https://github.com/opentofu/opentofu/releases/download/v1.9.0-alpha2/tofu_1.9.0-alpha2_windows_amd64.zip" target="_blank" rel="noopener noreferrer">tofu_1.9.0-alpha2_windows_amd64.zip</a></td></tr><tr><td><strong>MacOS</strong><br>(Macbook M1 or higher; ARM64)</td><td><a href="https://github.com/opentofu/opentofu/releases/download/v1.9.0-alpha2/tofu_1.9.0-alpha2_darwin_arm64.tar.gz" target="_blank" rel="noopener noreferrer">tofu_1.9.0-alpha2_darwin_arm64.tar.gz</a></td></tr><tr><td><strong>MacOS</strong><br>(Macbook pre-M1; AMD64)</td><td><a href="https://github.com/opentofu/opentofu/releases/download/v1.9.0-alpha2/tofu_1.9.0-alpha2_darwin_amd64.tar.gz" target="_blank" rel="noopener noreferrer">tofu_1.9.0-alpha2_darwin_amd64.tar.gz</a></td></tr><tr><td><strong>Intel/AMD Linux computer or server</strong><br>(AMD64)</td><td><a href="https://github.com/opentofu/opentofu/releases/download/v1.9.0-alpha2/tofu_1.9.0-alpha2_linux_amd64.tar.gz" target="_blank" rel="noopener noreferrer">tofu_1.9.0-alpha2_linux_amd64.tar.gz</a></td></tr><tr><td><strong>ARM-based Linux computer<br>or<br>Raspberry Pi 3 or higher</strong><br>(ARM64)</td><td><a href="https://github.com/opentofu/opentofu/releases/download/v1.9.0-alpha2/tofu_1.9.0-alpha2_linux_arm64.tar.gz" target="_blank" rel="noopener noreferrer">tofu_1.9.0-alpha2_linux_arm64.tar.gz</a></td></tr></tbody></table>
<p>For the releases above, please unpack the archive and you should find the <code>tofu</code> binary inside. You can also use the <a href="https://opentofu.org/docs/intro/install/standalone/" target="_blank" rel="noopener noreferrer">standalone installer</a> to download the release with signature verification.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="provider-for_each">Provider <code>for_each</code><a href="https://opentofu.org/blog/help-us-test-opentofu-1-9-0-alpha2#provider-for_each" class="hash-link" aria-label="Direct link to provider-for_each" title="Direct link to provider-for_each">​</a></h2>
<p>Imagine you have to deploy an infrastructure that involves multiple regions using your cloud provider. In order to minimize code duplication, you created a module that you can use for each region. However, your main module still looks like this:</p>
<div class="language-hcl codeBlockContainer_APcc theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_m3Ux"><figure><figcaption class="sr-only">Code Block</figcaption><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div><pre tabindex="0" class="prism-code language-hcl codeBlock_qGQc thin-scrollbar" style="color:#F8F8F2;background-color:#282A36" role="code" aria-label="Code Block"><code class="codeBlockLines_p187"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">provider</span><span class="token keyword type variable" style="color:rgb(189, 147, 249);font-style:italic"> "aws" </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">alias</span><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"useast"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">region</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"us-east-1"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">provider</span><span class="token keyword type variable" style="color:rgb(189, 147, 249);font-style:italic"> "aws" </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">alias</span><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"uswest"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">region</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"us-west-1"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">provider</span><span class="token keyword type variable" style="color:rgb(189, 147, 249);font-style:italic"> "aws" </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">alias</span><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"eucentral"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">region</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"eu-central-1"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">module</span><span class="token keyword type variable" style="color:rgb(189, 147, 249);font-style:italic"> "deploy-useast" </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">source</span><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"./deploy"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">providers</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">aws</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> aws.useast</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">module</span><span class="token keyword type variable" style="color:rgb(189, 147, 249);font-style:italic"> "deploy-uswest" </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">source</span><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"./deploy"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">providers</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">aws</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> aws.uswest</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">module</span><span class="token keyword type variable" style="color:rgb(189, 147, 249);font-style:italic"> "deploy-eucentral" </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">source</span><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"./deploy"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">providers</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">aws</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> aws.eucentral</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre></figure></div></div>
<p>Starting OpenTofu 1.9, you can now use a <code>for_each</code> instead:</p>
<div class="language-hcl codeBlockContainer_APcc theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_m3Ux"><figure><figcaption class="sr-only">Code Block</figcaption><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div><pre tabindex="0" class="prism-code language-hcl codeBlock_qGQc thin-scrollbar" style="color:#F8F8F2;background-color:#282A36" role="code" aria-label="Code Block"><code class="codeBlockLines_p187"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">variable</span><span class="token keyword type variable" style="color:rgb(189, 147, 249);font-style:italic"> "regions" </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">description</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"A list of regions that should have a deployment."</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">type</span><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> set(string)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">variable</span><span class="token keyword type variable" style="color:rgb(189, 147, 249);font-style:italic"> "disabled_regions" </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">description</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"A list of regions that should be disabled and all resources removed."</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">type</span><span class="token plain">        </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> set(string)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">default</span><span class="token plain">     </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">provider</span><span class="token keyword type variable" style="color:rgb(189, 147, 249);font-style:italic"> "aws" </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">alias</span><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"by_region"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">region</span><span class="token plain">   </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> each.value</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">for_each</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> var.regions</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">module</span><span class="token keyword type variable" style="color:rgb(189, 147, 249);font-style:italic"> "deploy" </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">source</span><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"./deploy"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">providers</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">aws</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> aws.by_region</span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token plain">each.key</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token comment" style="color:rgb(98, 114, 164)">// Here we make sure that all resources from a region are removed</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token comment" style="color:rgb(98, 114, 164)">// if the region is disabled. This must be done before removing</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token comment" style="color:rgb(98, 114, 164)">// a region entirely.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">for_each</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> setsubtract(var.regions, var.disabled_regions)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre></figure></div></div>
<p>As you can see, you can pass in the set of regions using a variable and then call the module as many times as you need it.</p>
<p>However, there are some important considerations to remember when using <code>for_each</code> in this manner:</p>
<ol>
<li>You can only use <code>for_each</code> on variables and locals that can be obtained statically. Expressions that rely on data sources or resources are currently not usable.</li>
<li>If you have an already-deployed infrastructure, don't simply remove a provider from the list as this will make it impossible for OpenTofu to destroy the infrastructure in this region. Instead, you will need to implement removing that infrastructure first and then remove the provider from the list. See the <code>disabled_regions</code> variable for an example above.</li>
<li>Currently, each provider used in a <code>for_each</code> <strong>must</strong> have an alias. Providers without aliases are not supported for now due to internal technical reasons.</li>
<li>There is currently no way to pass a set of providers to a module, you can only pass individual providers.</li>
</ol>
<p>We are actively working on resolving these limitations and future OpenTofu versions will see this capability improved.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="exclude-on-plan-and-apply">Exclude on plan and apply<a href="https://opentofu.org/blog/help-us-test-opentofu-1-9-0-alpha2#exclude-on-plan-and-apply" class="hash-link" aria-label="Direct link to Exclude on plan and apply" title="Direct link to Exclude on plan and apply">​</a></h2>
<p>This flag is small but powerful: similar to <code>-target</code>, you can now tell OpenTofu to ignore a certain resource when applying your configuration.</p>
<p>For example:</p>
<div class="language-hcl2 codeBlockContainer_APcc theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_m3Ux"><figure><figcaption class="sr-only">Code Block</figcaption><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div><pre tabindex="0" class="prism-code language-hcl2 codeBlock_qGQc thin-scrollbar" style="color:#F8F8F2;background-color:#282A36" role="code" aria-label="Code Block"><code class="codeBlockLines_p187"><span class="token-line" style="color:#F8F8F2"><span class="token plain">tofu plan -exclude=kubernetes_manifest.crds</span><br></span></code></pre></figure></div></div>
<p>In this case, OpenTofu will ignore <code>kubernetes_manifest.crds</code> during planning.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="providing-feedback">Providing feedback<a href="https://opentofu.org/blog/help-us-test-opentofu-1-9-0-alpha2#providing-feedback" class="hash-link" aria-label="Direct link to Providing feedback" title="Direct link to Providing feedback">​</a></h2>
<p>Thank you for taking the time to test this preview release. If you have any feedback, please use <a href="https://github.com/opentofu/opentofu/issues/new/choose" target="_blank" rel="noopener noreferrer">a GitHub issue</a> or chat with us on the <a href="https://opentofu.org/slack/" target="_blank" rel="noopener noreferrer">OpenTofu Slack</a>.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Building the OpenTofu Registry]]></title>
            <link>https://opentofu.org/blog/building-the-opentofu-registry</link>
            <guid>https://opentofu.org/blog/building-the-opentofu-registry</guid>
            <pubDate>Thu, 12 Sep 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[With the Registry Search now in beta it is time to take a technical deep dive into how the OpenTofu Registry and Search work and what it took to build them.]]></description>
            <content:encoded><![CDATA[<p>Recently, we published the beta version of the <a href="https://search.opentofu.org/" target="_blank" rel="noopener noreferrer">OpenTofu Registry Search</a>, a user interface that lets you search for and view the documentation of providers and modules in the OpenTofu Registry. With this important milestone reached, it is finally time to talk about how the OpenTofu Registry and Search work under the hood and the pitfalls of running a public registry.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="the-registry-api">The Registry API<a href="https://opentofu.org/blog/building-the-opentofu-registry#the-registry-api" class="hash-link" aria-label="Direct link to The Registry API" title="Direct link to The Registry API">​</a></h2>
<p>OpenTofu and its predecessor Terraform rely on provider binaries created by the community to interact with various APIs. There are currently over 4,000 such providers in the OpenTofu Registry, enabling a wide range of integrations from cloud providers to managing your GitHub account. Anything that has an API to create some kind of resource can be integrated with OpenTofu.</p>
<p>Aside from providers, the community has also created well over 20,000 reusable modules that implement higher level functionality, such as provisioning an entire infrastructure with a cloud provider with only a few configuration options.</p>
<p>Since these providers and modules are created by the community, OpenTofu needs to know where to download them and what versions are available. This is where the Registry comes into play: it holds the information about available providers and modules, download URLs, checksums, and GPG keys for integrity verification.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="step-1-service-discovery">Step 1: Service Discovery<a href="https://opentofu.org/blog/building-the-opentofu-registry#step-1-service-discovery" class="hash-link" aria-label="Direct link to Step 1: Service Discovery" title="Direct link to Step 1: Service Discovery">​</a></h3>
<p>For both providers and modules, OpenTofu first requests the <code>https://registry.opentofu.org/.well-known/terraform.json</code> file, which has the following content:</p>
<div class="language-json codeBlockContainer_APcc theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_m3Ux"><figure><figcaption class="sr-only">Code Block</figcaption><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div><pre tabindex="0" class="prism-code language-json codeBlock_qGQc thin-scrollbar" style="color:#F8F8F2;background-color:#282A36" role="code" aria-label="Code Block"><code class="codeBlockLines_p187"><span class="token-line" style="color:#F8F8F2"><span class="token plain">{</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  "modules.v1": "/v1/modules/",</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  "providers.v1": "/v1/providers/"</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">}</span><br></span></code></pre></figure></div></div>
<p>This file lists the endpoints OpenTofu should query for information about modules and providers. For private registries there is also a third endpoint named <code>login.v1</code>, providing information about an OAuth endpoint to use for authentication. If you are interested in the details, you can read more about this protocol <a href="https://opentofu.org/docs/internals/login-protocol/" target="_blank" rel="noopener noreferrer">in the OpenTofu documentation</a>.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="step-2-version-listing">Step 2: Version Listing<a href="https://opentofu.org/blog/building-the-opentofu-registry#step-2-version-listing" class="hash-link" aria-label="Direct link to Step 2: Version Listing" title="Direct link to Step 2: Version Listing">​</a></h3>
<p>With the endpoint information, OpenTofu can query the version listing endpoint for the desired provider or module.</p>
<ul>
<li>For providers this endpoint would be <code>/v1/providers/NAMESPACE/NAME/versions</code> (<a href="https://registry.opentofu.org/v1/providers/opentofu/random/versions" target="_blank" rel="noopener noreferrer">example</a>).</li>
<li>For modules it would be <code>/v1/modules/NAMESPACE/NAME/SYSTEM/versions</code> (<a href="https://registry.opentofu.org/v1/modules/hashicorp/consul/aws/versions" target="_blank" rel="noopener noreferrer">example</a>).</li>
</ul>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="step-3-download-info">Step 3: Download Info<a href="https://opentofu.org/blog/building-the-opentofu-registry#step-3-download-info" class="hash-link" aria-label="Direct link to Step 3: Download Info" title="Direct link to Step 3: Download Info">​</a></h3>
<p>Based on the information received, OpenTofu can request the information about the specific version, operating system and architecture.</p>
<ul>
<li>For providers, it would be located at <code>/v1/providers/NAMESPACE/NAME/VERSION/download/OS/ARCH</code> (<a href="https://registry.opentofu.org/v1/providers/opentofu/random/2.0.0/download/linux/amd64" target="_blank" rel="noopener noreferrer">example</a>).</li>
<li>For modules, it would be located at <code>/v1/modules/NAMESPACE/NAME/SYSTEM/VERSION/download</code> (<a href="https://registry.opentofu.org/v1/modules/hashicorp/consul/aws/0.11.0/download" target="_blank" rel="noopener noreferrer">example</a>).</li>
</ul>
<p>OpenTofu then downloads the provider from the supplied GitHub releases URL and verifies the checksum and signature, or clones the returned Git repository for modules.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="hosting-the-registry-for-free">Hosting the Registry (for free)<a href="https://opentofu.org/blog/building-the-opentofu-registry#hosting-the-registry-for-free" class="hash-link" aria-label="Direct link to Hosting the Registry (for free)" title="Direct link to Hosting the Registry (for free)">​</a></h2>
<p>As an open source project with a small core team working on developing OpenTofu itself, it was paramount that we kept the costs of running the Registry as low as possible both in terms of bandwidth and also in human cost. However, we also needed to make sure that the Registry had an uptime close to 100% since thousands upon thousands of developers would be left without a means to update their infrastructure if it went down.</p>
<p>Here we owe a big thanks to Cloudflare. Their very competitive pricing for <a href="https://www.cloudflare.com/developer-platform/r2/" target="_blank" rel="noopener noreferrer">R2</a> with no egress fees and their sponsorship of OpenTofu meant that we would be able to run the Registry essentially for free with no servers and scaling issues to worry about. The <a href="https://github.com/opentofu/registry" target="_blank" rel="noopener noreferrer">Registry codebase</a> (written in Go) pre-generates all possible answers of the API above and uploads the static files to an R2 bucket.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="populating-the-registry">Populating the Registry<a href="https://opentofu.org/blog/building-the-opentofu-registry#populating-the-registry" class="hash-link" aria-label="Direct link to Populating the Registry" title="Direct link to Populating the Registry">​</a></h2>
<p>Alongside the Terraform license change, HashiCorp <a href="https://registry.terraform.io/terms" target="_blank" rel="noopener noreferrer">closed the Terraform Registry</a> for software that isn't Terraform, so using it as a source of data for the OpenTofu Registry was out of the question. However, since the Terraform Registry was coupled exclusively to GitHub, it was relatively straight forward for us to use the GitHub search API to populate the Registry, if a little slow.</p>
<p>Updating the Registry, however, was a much harder problem. GitHub limits the API to ~5,000 requests per hour, which is not enough to update roughly 30,000 providers and modules in a speedy fashion, especially since some updates required multiple requests.</p>
<p>We <em>could</em> have requested provider authors to log in with their GitHub account, granting us an access token we could use for a higher rate limit, but that would have been impractical when we launched the Registry since we would have had to ask thousands of developers to log in at a time when OpenTofu wasn't even released yet.</p>
<p>The solution came by the way of the GitHub RSS feeds, which are not rate limited. The releases RSS located at <code>http://github.com/USERNAME/REPO/releases.atom</code> always contains the last 5 releases, which is sufficient if we only need to add the latest versions as it is unlikely that a provider or module would have more than 5 releases within an hour. For modules, we needed to query the tags instead of the releases, which was even easier because the <code>git ls-remote</code> command gave us all this information and was also not rate limited. (You are going to keep it that way, right, GitHub?)</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="the-submission-process">The submission process<a href="https://opentofu.org/blog/building-the-opentofu-registry#the-submission-process" class="hash-link" aria-label="Direct link to The submission process" title="Direct link to The submission process">​</a></h3>
<p>Since we didn't need to ask provider and module authors for their credentials using OAuth, we were able to create a simple submission process that anyone with a GitHub account could use.</p>
<p>While anyone could submit a provider or a module, we still needed provider authors to submit their GPG keys so their binaries could be verified. Instead of asking for OAuth logins, we again decided to use the GitHub API in a creative way. In order to submit a GPG key for a provider, the author needed to set their organization membership to public for the repository of the provider and then submit a GitHub issue. We would verify their membership in the provider organization and process their GPG keys.</p>
<p>Having the submission process being as simple as opening a GitHub issue turned out to be quite popular. To date, the community has opened almost 1,000 pull requests and issues on the Registry repository. It also meant that provider and module authors working for larger organizations did not need to expend any organizational capacity to sign up for an OpenTofu account, resulting in quite a few high profile providers adding their GPG key.</p>
<div class="flex flex-col py-2 px-3 not-prose border gap-1 [&amp;+&amp;]:mt-3 [&amp;_a:hover]:text-gray-900 dark:[&amp;_a:hover]:text-gray-50 [&amp;_a>code]:font-bold [&amp;_code]:text-base [&amp;_code]:px-1.5 [&amp;_a]:underline [&amp;_p]:mb-2 bg-sky-100 border-sky-300 text-sky-800 dark:bg-sky-950 dark:border-sky-700 dark:text-sky-100" role="alert"><div class="flex gap-3 font-bold"><span class="flex w-4 fill-current [&amp;>svg]:w-full" aria-hidden="true"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>Learn more</div><div class="leading-relaxed"><p>Do you want to learn more about the early days of the OpenTofu Registry? James and Arel from the OpenTofu team <a href="https://www.youtube.com/watch?v=iJUcOBwPxVU" target="_blank" rel="noopener noreferrer">held a talk about this topic at the OpenTofu Day at Kubecon 2024</a>.</p></div></div>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="building-a-user-interface">Building a user interface<a href="https://opentofu.org/blog/building-the-opentofu-registry#building-a-user-interface" class="hash-link" aria-label="Direct link to Building a user interface" title="Direct link to Building a user interface">​</a></h2>
<p>After working on the Registry and taking a few months pause for some much-needed work on OpenTofu itself, we returned to building a search and documentation reading interface. As we would soon learn, this was a larger task and resulted in three times the amount of code needing to be written.</p>
<p><img loading="lazy" alt="A screenshot of the OpenTofu Registry Search" src="https://opentofu.org/assets/images/registry-ui-723067c7ca2d4636fb23928b1dc79b92.png" width="1894" height="1086" class="img_ev3q"></p>
<p>As before, we chose an architecture that would generate static files. Early on we had to make a decision between simply generating static HTML files or using a Single Page Application and load the data from an API. We chose the latter because we were concerned that a layout change would require a complete regeneration of all files, which would be cost-prohibitive to upload again and again.</p>
<p>Having made this decision we set out to build a backend and a frontend component, the former being responsible for producing the data the latter would consume. We built <a href="https://github.com/opentofu/libregistry" target="_blank" rel="noopener noreferrer">libregistry</a>, a standardized Go library that would make it easier to access the metadata stored in the Registry repository and provide a useful abstraction layer on top of GitHub and the various creative API integrations we built to fetch the data.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="pre-processing-the-documentation">Pre-processing the documentation<a href="https://opentofu.org/blog/building-the-opentofu-registry#pre-processing-the-documentation" class="hash-link" aria-label="Direct link to Pre-processing the documentation" title="Direct link to Pre-processing the documentation">​</a></h3>
<p>While the Registry always regenerates all API responses from the raw metadata, this approach was not feasible for the documentation due to the sheer volume of data we needed to process. Not only would we have to produce documentation responses for tens of thousands of providers and modules, some of them also had several hundred versions, each of which needed their own copy of the documentation stored.</p>
<p>We decided that we would process the data from the source repositories directly into an R2 bucket without storing any intermediate data. This approach came with its own problems. While the Registry could make use of git to track changes in the intermediate data, we needed to make sure that our uploads to the R2 bucket were as close to atomic as possible so no partial uploads are left behind. While we have implemented a <a href="https://github.com/opentofu/registry-ui/tree/4adefb41539f14e78e84479e45c69e3f8a505b89/backend/internal/indexstorage/bufferedstorage" target="_blank" rel="noopener noreferrer">partial solution that can continue an upload</a>, this still remains one of the unsolved issues with the Registry.</p>
<p>In order to simplify the necessary frontend logic for displaying the documentation, the backend's main job is to rename and move each of the documentation files into their standardized place. There is no formalized description on how providers can store their documentation, so the logic for extracting this information is <a href="https://github.com/opentofu/registry-ui/blob/4adefb41539f14e78e84479e45c69e3f8a505b89/backend/internal/providerindex/providerdocsource/scrape.go#L159-L190" target="_blank" rel="noopener noreferrer">only empirically known</a>. We needed several iterations to work around various bugs as we expanded the number of repositories we ingested and discovered newer and newer edge cases.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="module-schemas">Module schemas<a href="https://opentofu.org/blog/building-the-opentofu-registry#module-schemas" class="hash-link" aria-label="Direct link to Module schemas" title="Direct link to Module schemas">​</a></h3>
<p>While providers typically have their own, explicit documentation, often generated by tools like <a href="https://terraform-docs.io/" target="_blank" rel="noopener noreferrer">terraform-docs</a>, modules don't have such information readily available. This makes it difficult to generate information about their inputs, outputs and dependencies.</p>
<p>HashiCorp published <a href="https://github.com/hashicorp/terraform-schema" target="_blank" rel="noopener noreferrer">terraform-schema</a> for extracting this information, duplicating some of the module parsing logic from Terraform. However, we decided that maintaining duplicated codebases would likely cause a maintenance issue down the line and implemented this functionality directly into OpenTofu. This patch currently <a href="https://github.com/opentofu/opentofu/tree/experiment/json_config_dump" target="_blank" rel="noopener noreferrer">lives on a branch</a>, but will be integrated into the main branch as an experimental feature at a later date.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="licenses">Licenses<a href="https://opentofu.org/blog/building-the-opentofu-registry#licenses" class="hash-link" aria-label="Direct link to Licenses" title="Direct link to Licenses">​</a></h3>
<p>During the ingestion process we also needed to concern ourselves with licenses: as we were unsure under what legal standard such a documentation dataset would fall, we deliberately chose a <a href="https://github.com/opentofu/registry-ui/blob/4adefb41539f14e78e84479e45c69e3f8a505b89/licenses.json" target="_blank" rel="noopener noreferrer">restricted set of licenses</a> that we would accept into the Registry documentation. We performed automatic license detection on each provider and module repository to avoid ingesting content under potentially problematic licenses.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="the-opentofu-docs-api-and-how-you-can-use-it">The OpenTofu Docs API (and how you can use it)<a href="https://opentofu.org/blog/building-the-opentofu-registry#the-opentofu-docs-api-and-how-you-can-use-it" class="hash-link" aria-label="Direct link to The OpenTofu Docs API (and how you can use it)" title="Direct link to The OpenTofu Docs API (and how you can use it)">​</a></h3>
<p>Doing all this work on the backend and splitting the display logic from the data also had an unintended but very welcomed side effect: we were able to offer <a href="https://api.opentofu.org/" target="_blank" rel="noopener noreferrer">an API for provider and module documentation</a>, which would come in handy as just a few weeks later <a href="https://youtrack.jetbrains.com/issue/IJPL-157423/Support-for-OpenTofu-in-Terraform-and-HCL-Plugin#focus=Comments-27-10245678.0-0" target="_blank" rel="noopener noreferrer">Jetbrains requested just such an API for their OpenTofu integration</a>.</p>
<p>The backend produces the dataset in this format and is easily runnable locally from the <a href="https://github.com/opentofu/registry-ui" target="_blank" rel="noopener noreferrer">registry-ui</a> repository, while the <a href="https://api.opentofu.org/" target="_blank" rel="noopener noreferrer">public API</a> is available for anyone to build integrations with. We even made sure to include the correct <a href="https://en.wikipedia.org/wiki/Cross-Origin_Resource_Sharing" target="_blank" rel="noopener noreferrer">CORS headers</a> if you would like to build a browser-only integration. If you build something cool with it, let us know!</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="search">Search<a href="https://opentofu.org/blog/building-the-opentofu-registry#search" class="hash-link" aria-label="Direct link to Search" title="Direct link to Search">​</a></h2>
<p>As we were building the backend, one issue was constantly on our minds: how do we make such a vast data set searchable? We hoped that it would be possible to simply generate a search index and let the client JavaScript deal with the entire search problem. As we were looking at <a href="https://lunrjs.com/" target="_blank" rel="noopener noreferrer">lunr.js</a>, a robust and mature library for search, it quickly became apparent that this path would be entirely unfeasible. Even with a limited data set, the download size of the search index quickly ballooned to several hundred megabytes, which is not exactly ideal for a snappy search functionality not to mention really upsetting to people with data caps.</p>
<p>Not wanting to run our own database server or involve any more service dependencies, we looked at <a href="https://developers.cloudflare.com/d1/" target="_blank" rel="noopener noreferrer">Cloudflare's D1</a>, a SQLite database service and a <a href="https://workers.cloudflare.com/" target="_blank" rel="noopener noreferrer">worker</a> to handle search queries. While it initially looked promising, we discovered that we would have to submit all updates in a single HTTP request in order to run them in a transaction.</p>
<p>It would have been possible to work around it and still perform atomic search index updates, but we ended up using <a href="https://neon.tech/" target="_blank" rel="noopener noreferrer">Neon</a>, a database-as-a-service offering, instead. They don't explicitly sponsor OpenTofu, but their free tier was comfortably enough for our search index and the next tier was also quite affordable. Their tight integration with Cloudflare was also a very welcome addition.</p>
<p>To query the database hosted at Neon, we <a href="https://github.com/opentofu/registry-ui/tree/4adefb41539f14e78e84479e45c69e3f8a505b89/search" target="_blank" rel="noopener noreferrer">created a Cloudflare worker</a>. This worker ended up handling all requests to <code>api.opentofu.org</code>, forwarding the static requests to R2 and handling the search queries itself.</p>
<p>The backend would prepare a line-delimited JSON (ndjson) file with a data feed at <a href="https://api.opentofu.org/registry/docs/search.ndjson" target="_blank" rel="noopener noreferrer">https://api.opentofu.org/registry/docs/search.ndjson</a>, containing all recent updates to the search index that the worker could ingest and fill into the database.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="where-do-we-go-from-here">Where do we go from here?<a href="https://opentofu.org/blog/building-the-opentofu-registry#where-do-we-go-from-here" class="hash-link" aria-label="Direct link to Where do we go from here?" title="Direct link to Where do we go from here?">​</a></h2>
<p>The OpenTofu Registry Search is currently in beta, indicating that not everything is working yet. As we are expanding the amount of providers and modules indexed, we will certainly discover more edge cases that need to be fixed.</p>
<p>The libregistry library also duplicates a lot of the functionality present in the registry codebase as well. We want to deduplicate this functionality, both for long-term maintenance and because libregistry would make it easier for people to run their own mirror or even independent copy of the Registry.</p>
<p>During this process your feedback is invaluable for prioritization. If you find a bug or have a use case we haven't considered, please use <a href="https://github.com/opentofu/registry-ui/issues/new/choose" target="_blank" rel="noopener noreferrer">GitHub issues</a> to let us know.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[OpenTofu 1.8.0 is out with Early Evaluation, Provider Mocking, and a Coder-Friendly Future]]></title>
            <link>https://opentofu.org/blog/opentofu-1-8-0</link>
            <guid>https://opentofu.org/blog/opentofu-1-8-0</guid>
            <pubDate>Mon, 29 Jul 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[OpenTofu 1.8.0 is now available with early variable/locals evaluation, provider mocking for tests, and a future that makes every-day Tofu code a lot simpler.]]></description>
            <content:encoded><![CDATA[<p>Since the <a href="https://opentofu.org/blog/opentofu-1-7-0/">1.7 release</a>, the OpenTofu community and core team have been hard at work on much-requested features, making <code>.tf</code> code easier to write, reducing unnecessary boilerplate, improving performance, and more. We are happy to announce the <a href="https://github.com/opentofu/opentofu/releases/tag/v1.8.0" target="_blank" rel="noopener noreferrer">immediate availability of OpenTofu 1.8</a> with the following main features:</p>
<ul>
<li><a href="https://opentofu.org/docs/intro/whats-new/#early-variablelocals-evaluation">You can now use variables and locals in places</a> that were not previously available, such as module sources, backend configuration and state encryption. Being able to assign variables more dynamically will eliminate code duplication and boilerplate code, making projects easier to maintain. However, we are not stopping there: future releases will see <a href="https://github.com/opentofu/opentofu/issues/300" target="_blank" rel="noopener noreferrer">dynamic provider configuration assignments</a> and more.</li>
<li>Since Terraform doesn't support these new language features, <a href="https://opentofu.org/docs/intro/whats-new/#override-files-for-opentofu-keeping-compatibility">OpenTofu now supports the <code>.tofu</code> file extension</a>. When a file with the <code>.tofu</code> extension is present, OpenTofu will ignore the identically named <code>.tf</code> file. Using this new file extension, module authors can use the new features of OpenTofu and still keep older code around for compatibility.</li>
<li>You can now use <a href="https://opentofu.org/docs/intro/whats-new/#provider-mocking-in-tofu-test">provider mocking</a> as well as <a href="https://opentofu.org/docs/intro/whats-new/#resource-overrides-in-tofu-test">resource overrides</a> with <code>tofu test</code>. This allows for more flexible testing similar to traditional software testing methods.</li>
</ul>
<p>You can find the full list of improvements and changes on the <a href="https://opentofu.org/docs/v1.8/intro/whats-new/">What's new in OpenTofu 1.8?</a> page.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="growth-continues-30-increase-in-registry-traffic">Growth continues: ~30% increase in registry traffic<a href="https://opentofu.org/blog/opentofu-1-8-0#growth-continues-30-increase-in-registry-traffic" class="hash-link" aria-label="Direct link to Growth continues: ~30% increase in registry traffic" title="Direct link to Growth continues: ~30% increase in registry traffic">​</a></h2>
<p>While we don't believe in tracking our users and OpenTofu does not have phone-home telemetry, we can observe a trajectory based on registry usage. In our <a href="https://opentofu.org/blog/opentofu-1-7-0/">last release post</a> 3 months ago we recorded a peak of roughly 1.4 million daily requests to the registry. We are happy to report that this number has increased by roughly 30% to almost 1.8 million peak daily requests.</p>
<p><img loading="lazy" alt="A graph showing the OpenTofu registry requests per day." src="https://opentofu.org/assets/images/opentofu-registry-july-2024-5e1bb32e861e4a5cd427261cecf2a079.svg" width="1542" height="620" class="img_ev3q"></p>
<p>As before, the OpenTofu community is very active in reporting and voting on issues, fixing bugs, and helping out with testing. The number of GitHub stars grew by ~10% to almost 22.000, the <a href="https://github.com/opentofu/opentofu/issues/1496" target="_blank" rel="noopener noreferrer">top-voted issues</a> received hundreds of votes and quite a few comments in the discussions. This release has also seen significant contributions from outside the core team, ranging from small fixes to large performance overhaul PRs. In total, over 100 issues and over 150 pull requests were opened since the last release. 26 people contributed to this release on the main repository alone, with several significant contributions added to other repositories as well.</p>
<p>Finally, we'd like to direct your attention to <a href="https://awesome-opentofu.com/" target="_blank" rel="noopener noreferrer">Awesome OpenTofu</a>, a community page containing a host of tools, platforms, registry implementations and learning material for OpenTofu.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="better-documentation-for-the-future-the-new-rfc-process">Better documentation for the future: the new RFC process<a href="https://opentofu.org/blog/opentofu-1-8-0#better-documentation-for-the-future-the-new-rfc-process" class="hash-link" aria-label="Direct link to Better documentation for the future: the new RFC process" title="Direct link to Better documentation for the future: the new RFC process">​</a></h2>
<p>As the community kept working hand-in-hand with the core team it became clear that our previous RFC process based on GitHub Issues wasn't detailed enough. The linear nature of issue comments didn't encourage discussing specific parts of an RFC and the RFCs themselves did not contain enough context for someone in a few months or years to fully understand why the change was necessary.</p>
<p>Our <a href="https://github.com/opentofu/opentofu/tree/main/rfc" target="_blank" rel="noopener noreferrer">new pull request-based RFC process</a> fills this gap by using PR reviews to discuss parts of a document and the document itself encourages creating a historical record. We have trialled this process during the development of the <a href="https://github.com/opentofu/opentofu/blob/main/rfc/20240513-static-evaluation.md" target="_blank" rel="noopener noreferrer">early (static) evaluation feature</a> and also the upcoming <a href="https://github.com/opentofu/opentofu/blob/main/rfc/20240513-static-evaluation-providers.md" target="_blank" rel="noopener noreferrer">dynamic provider assignment</a> functionality. We hope that these documents will provide a better view into the new features coming to OpenTofu and also help create a historical record on why engineering decision were made the way they were.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="coming-soon-the-opentofu-registry-ui">Coming soon: the OpenTofu Registry UI<a href="https://opentofu.org/blog/opentofu-1-8-0#coming-soon-the-opentofu-registry-ui" class="hash-link" aria-label="Direct link to Coming soon: the OpenTofu Registry UI" title="Direct link to Coming soon: the OpenTofu Registry UI">​</a></h2>
<p>In parallel to this release, we have been hard at work on a web-based user interface for the OpenTofu Registry. This user interface will allow you to browse and search for providers, resources and modules and read their documentation in a convenient format. We are aiming to release this user interface in the next few weeks.</p>
<p><img loading="lazy" alt="A preview screenshot of the OpenTofu Registry UI" src="https://opentofu.org/assets/images/opentofu-registry-preview-130128cdbfafd1448637e9c74071db8e.png" width="2334" height="1330" class="img_ev3q"></p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="fulfilling-promises-our-first-go-libraries">Fulfilling promises: our first Go libraries<a href="https://opentofu.org/blog/opentofu-1-8-0#fulfilling-promises-our-first-go-libraries" class="hash-link" aria-label="Direct link to Fulfilling promises: our first Go libraries" title="Direct link to Fulfilling promises: our first Go libraries">​</a></h2>
<p>OpenTofu was founded on the principle of openness and modularity. While it is not always easy to modularize a codebase with a long history, we have released our first Go libraries for interoperability.</p>
<p><a href="https://github.com/opentofu/tofudl" target="_blank" rel="noopener noreferrer">TofuDL</a> encodes the process of fetching the latest version of OpenTofu, verifying the signature and extracting the binary for local use into an easy-to-use Go library. Tool authors can use this library to cut down on the complexity of downloading the Tofu binary when needed. Furthermore, this library contains a full release mirroring tool, allowing you to build a release server with OpenTofu releases for air-gapped infrastructure that TofuDL-based tools can use to obtain the mirrored binaries.</p>
<p>The currently experimental <a href="https://github.com/opentofu/libregistry" target="_blank" rel="noopener noreferrer">libregistry</a> provides structured access to the data stored in the OpenTofu registry using the metadata API. In the future, we will transition the processes currently written for GitHub Actions into this library, allowing you to execute all registry processes independently of GitHub. You can use this library as a basis for writing your own registry, although the batteries are definitely not included.</p>
<p>Please give these libraries a go (pun totally intended) and let us know what functionality you would like to see in them.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="the-future-more-dynamic-functionality-even-more-community-focussed-development">The future: more dynamic functionality, even more community-focussed development<a href="https://opentofu.org/blog/opentofu-1-8-0#the-future-more-dynamic-functionality-even-more-community-focussed-development" class="hash-link" aria-label="Direct link to The future: more dynamic functionality, even more community-focussed development" title="Direct link to The future: more dynamic functionality, even more community-focussed development">​</a></h2>
<p>Ever since we created our <a href="https://github.com/opentofu/opentofu/issues/1496" target="_blank" rel="noopener noreferrer">top-ranking issues</a> list, new votes from the community started pouring in, giving us a strong signal on where you want us to take OpenTofu. By a large margin, the top-requested issue was one we partly solved in this release by introducing early evaluation for variables and locals. However, this is only the first step. As you helped us test the early alpha and beta of this release, one of the most commonly asked questions was: <em>“When can I use early evaluation to dynamically configure providers?”</em></p>
<p>The top-voted enhancement reflects a similar sentiment. In 1.9 and beyond, we aim to bring you dynamic provider assignments and more early-evaluation features, which let you cut down on the unnecessary code repetition even further. If you are interested in this topic, give the <a href="https://github.com/opentofu/opentofu/blob/main/rfc/20240513-static-evaluation-providers.md" target="_blank" rel="noopener noreferrer">corresponding RFC a read</a>.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="an-ask-for-help-gpg-keys-for-providers">An ask for help: GPG keys for providers<a href="https://opentofu.org/blog/opentofu-1-8-0#an-ask-for-help-gpg-keys-for-providers" class="hash-link" aria-label="Direct link to An ask for help: GPG keys for providers" title="Direct link to An ask for help: GPG keys for providers">​</a></h2>
<p>Finally, we have a favor to ask. The OpenTofu registry currently contains GPG signing keys only for a small number of providers as these keys are not publicly available on GitHub. If you are a provider author, <a href="https://github.com/opentofu/registry/issues/new/choose" target="_blank" rel="noopener noreferrer">please submit your signing key here</a>. It takes only a few minutes and does not require you to sign any legal documents or grant us access to your GitHub organization. If you are an OpenTofu user and you see that your providers are not signed, please let your provider author know that they can submit their keys and help secure the OpenTofu ecosystem.</p>
<p>You can identify a missing signing key by running <code>tofu init</code> and keeping an eye out for the following message:</p>
<blockquote>
<p>Signature validation was skipped due to the registry not containing GPG keys for this provider</p>
</blockquote>
<p>Thank you for your help!</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Get ready for OpenTofu Beta 1.8.0]]></title>
            <link>https://opentofu.org/blog/opentofu-1-8-0-beta1</link>
            <guid>https://opentofu.org/blog/opentofu-1-8-0-beta1</guid>
            <pubDate>Tue, 09 Jul 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Hey there, OpenTofu community! We've been working hard to refine the 1.8.0-alpha1 with your feedback! A few rough edges have been polished and a few new features have been added.]]></description>
            <content:encoded><![CDATA[<p>Hey there, OpenTofu community! We've been working hard to refine the <a href="https://opentofu.org/blog/help-us-test-opentofu-1-8-0-alpha1/">1.8.0-alpha1</a> with your feedback! A few rough edges have been polished and a few new features have been added.</p>
<p>If you have a <strong>non-production</strong> setup that you would be willing to test any of the new features on, please give it a try and give us <a href="https://github.com/opentofu/opentofu/issues/new/choose" target="_blank" rel="noopener noreferrer">feedback using a GitHub issue</a>, even if it's just telling us that everything went well.</p>
<p>This blog post will go over how to download the new preview release and expand on the features presented in the <a href="https://opentofu.org/blog/help-us-test-opentofu-1-8-0-alpha1/">1.8.0-alpha1 blog post</a>.</p>
<div class="flex flex-col py-2 px-3 not-prose border gap-1 [&amp;+&amp;]:mt-3 [&amp;_a:hover]:text-gray-900 dark:[&amp;_a:hover]:text-gray-50 [&amp;_a>code]:font-bold [&amp;_code]:text-base [&amp;_code]:px-1.5 [&amp;_a]:underline [&amp;_p]:mb-2 bg-yellow-100 border-yellow-500 text-yellow-800 dark:bg-yellow-950 dark:border-yellow-700 dark:text-yellow-100" role="alert"><div class="flex gap-3 font-bold"><span class="flex w-4 fill-current [&amp;>svg]:w-full" aria-hidden="true"><svg viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"></path></svg></span>Warning</div><div class="leading-relaxed"><p>Do not test this release on a production project! It is not a stable release!</p></div></div>
<div class="flex flex-col py-2 px-3 not-prose border gap-1 [&amp;+&amp;]:mt-3 [&amp;_a:hover]:text-gray-900 dark:[&amp;_a:hover]:text-gray-50 [&amp;_a>code]:font-bold [&amp;_code]:text-base [&amp;_code]:px-1.5 [&amp;_a]:underline [&amp;_p]:mb-2 bg-sky-100 border-sky-300 text-sky-800 dark:bg-sky-950 dark:border-sky-700 dark:text-sky-100" role="alert"><div class="flex gap-3 font-bold"><span class="flex w-4 fill-current [&amp;>svg]:w-full" aria-hidden="true"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>Note</div><div class="leading-relaxed"><p>On 2024/07/11, 1.8.0-beta2 was released to address issues present in 1.8.0-beta1.</p></div></div>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="downloading-the-beta-release">Downloading the beta release<a href="https://opentofu.org/blog/opentofu-1-8-0-beta1#downloading-the-beta-release" class="hash-link" aria-label="Direct link to Downloading the beta release" title="Direct link to Downloading the beta release">​</a></h2>
<p>The beta release is available exclusively from the <a href="https://github.com/opentofu/opentofu/releases/tag/v1.8.0-beta2" target="_blank" rel="noopener noreferrer">GitHub Releases page</a>. Please select the appropriate file for your platform. Here are some quick links:</p>
<table><thead><tr><th>Platform/Device</th><th>Download link</th></tr></thead><tbody><tr><td><strong>Desktop Windows computer</strong><br>(64-bit)</td><td><a href="https://github.com/opentofu/opentofu/releases/download/v1.8.0-beta2/tofu_1.8.0-beta2_windows_amd64.zip" target="_blank" rel="noopener noreferrer">tofu_1.8.0-beta2_windows_amd64.zip</a></td></tr><tr><td><strong>MacOS</strong><br>(Macbook M1 or higher; ARM64)</td><td><a href="https://github.com/opentofu/opentofu/releases/download/v1.8.0-beta2/tofu_1.8.0-beta2_darwin_arm64.tar.gz" target="_blank" rel="noopener noreferrer">tofu_1.8.0-beta2_darwin_arm64.tar.gz</a></td></tr><tr><td><strong>MacOS</strong><br>(Macbook pre-M1; AMD64)</td><td><a href="https://github.com/opentofu/opentofu/releases/download/v1.8.0-beta2/tofu_1.8.0-beta2_darwin_amd64.tar.gz" target="_blank" rel="noopener noreferrer">tofu_1.8.0-beta2_darwin_amd64.tar.gz</a></td></tr><tr><td><strong>Intel/AMD Linux computer or server</strong><br>(AMD64)</td><td><a href="https://github.com/opentofu/opentofu/releases/download/v1.8.0-beta2/tofu_1.8.0-beta2_linux_amd64.tar.gz" target="_blank" rel="noopener noreferrer">tofu_1.8.0-beta2_linux_amd64.tar.gz</a></td></tr><tr><td><strong>ARM-based Linux computer<br>or<br>Raspberry Pi 3 or higher</strong><br>(ARM64)</td><td><a href="https://github.com/opentofu/opentofu/releases/download/v1.8.0-beta2/tofu_1.8.0-beta2_linux_arm64.tar.gz" target="_blank" rel="noopener noreferrer">tofu_1.8.0-beta2_linux_arm64.tar.gz</a></td></tr></tbody></table>
<p>For the releases above, please unpack the archive and you should find the <code>tofu</code> binary inside. You can also use the <a href="https://opentofu.org/docs/intro/install/standalone/" target="_blank" rel="noopener noreferrer">standalone installer</a> to download the release with signature verification.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="provider-mocking-in-tofu-test">Provider mocking in <code>tofu test</code><a href="https://opentofu.org/blog/opentofu-1-8-0-beta1#provider-mocking-in-tofu-test" class="hash-link" aria-label="Direct link to provider-mocking-in-tofu-test" title="Direct link to provider-mocking-in-tofu-test">​</a></h2>
<p>Building on the existing ability to override specific data sources, resources, and module calls, <code>tofu test</code> now supports mocking entire provider definitions. This new feature allows you to automatically generate mock values for resources and data sources on a per-provider basis. As an example, consider the following code that spins up an m6i.2xlarge instance on AWS:</p>
<div class="language-hcl codeBlockContainer_APcc theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_m3Ux"><figure><figcaption class="sr-only">Code Block</figcaption><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div><pre tabindex="0" class="prism-code language-hcl codeBlock_qGQc thin-scrollbar" style="color:#F8F8F2;background-color:#282A36" role="code" aria-label="Code Block"><code class="codeBlockLines_p187"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">provider</span><span class="token keyword type variable" style="color:rgb(189, 147, 249);font-style:italic"> "aws" </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">region</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"us-east-1"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">data </span><span class="token keyword type variable" style="color:rgb(189, 147, 249);font-style:italic">"aws_ami"</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"ubuntu"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">most_recent</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token boolean">true</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">filter</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token property">name</span><span class="token plain">   </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"name"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token property">values</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token string" style="color:rgb(255, 121, 198)">"ubuntu/images/hvm-ssd/ubuntu-jammy-24.04-amd64-server-*"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">owners</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token string" style="color:rgb(255, 121, 198)">"099720109477"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">resource </span><span class="token keyword type variable" style="color:rgb(189, 147, 249);font-style:italic">"aws_instance"</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"web"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">ami</span><span class="token plain">           </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> data.aws_ami.ubuntu.id</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">instance_type</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"m6i.2xlarge"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre></figure></div></div>
<p>Instead of querying the AMI ID and spinning up the instance, we can write test code as follows:</p>
<div class="language-hcl codeBlockContainer_APcc theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_m3Ux"><figure><figcaption class="sr-only">Code Block</figcaption><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div><pre tabindex="0" class="prism-code language-hcl codeBlock_qGQc thin-scrollbar" style="color:#F8F8F2;background-color:#282A36" role="code" aria-label="Code Block"><code class="codeBlockLines_p187"><span class="token-line" style="color:#F8F8F2"><span class="token comment" style="color:rgb(98, 114, 164)">// This block will prevent OpenTofu from configuring aws provider.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token comment" style="color:rgb(98, 114, 164)">// All provider's resources and data sources will be mocked.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">mock_</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">provider</span><span class="token keyword type variable" style="color:rgb(189, 147, 249);font-style:italic"> "aws" </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  mock_data </span><span class="token string" style="color:rgb(255, 121, 198)">"aws_ami"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">defaults</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token property">id</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"ami-12345"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">run </span><span class="token string" style="color:rgb(255, 121, 198)">"test"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">assert</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">condition</span><span class="token plain">     </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> aws_instance.web.ami </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"ami-12345"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">error_message</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"Incorrect AMI ID passed to aws_instance.web: </span><span class="token string interpolation punctuation" style="color:rgb(248, 248, 242)">$</span><span class="token string interpolation punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token string interpolation" style="color:rgb(255, 121, 198)">aws_instance</span><span class="token string interpolation punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token string interpolation" style="color:rgb(255, 121, 198)">web</span><span class="token string interpolation punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token string interpolation" style="color:rgb(255, 121, 198)">ami</span><span class="token string interpolation punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token string" style="color:rgb(255, 121, 198)">"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre></figure></div></div>
<p>While this will not fully test the entire provisioning, it will highlight errors that may be caused by incorrectly connecting resources together without the need for an actual AWS account.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="resource-overrides-in-tofu-test">Resource overrides in <code>tofu test</code><a href="https://opentofu.org/blog/opentofu-1-8-0-beta1#resource-overrides-in-tofu-test" class="hash-link" aria-label="Direct link to resource-overrides-in-tofu-test" title="Direct link to resource-overrides-in-tofu-test">​</a></h2>
<p>First introduced in OpenTofu 1.8.0-alpha1, you can now override resources, data sources and entire modules from your tests, allowing you to create similar behavior to mocks in traditional software testing. As an example, consider the following code that spins up an <code>m6i.2xlarge</code> instance on AWS:</p>
<div class="language-hcl codeBlockContainer_APcc theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_m3Ux"><figure><figcaption class="sr-only">Code Block</figcaption><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div><pre tabindex="0" class="prism-code language-hcl codeBlock_qGQc thin-scrollbar" style="color:#F8F8F2;background-color:#282A36" role="code" aria-label="Code Block"><code class="codeBlockLines_p187"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">provider</span><span class="token keyword type variable" style="color:rgb(189, 147, 249);font-style:italic"> "aws" </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">region</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"us-east-1"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">data </span><span class="token keyword type variable" style="color:rgb(189, 147, 249);font-style:italic">"aws_ami"</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"ubuntu"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">most_recent</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token boolean">true</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">filter</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token property">name</span><span class="token plain">   </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"name"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token property">values</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token string" style="color:rgb(255, 121, 198)">"ubuntu/images/hvm-ssd/ubuntu-jammy-24.04-amd64-server-*"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">owners</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token string" style="color:rgb(255, 121, 198)">"099720109477"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">resource </span><span class="token keyword type variable" style="color:rgb(189, 147, 249);font-style:italic">"aws_instance"</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"web"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">ami</span><span class="token plain">           </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> data.aws_ami.ubuntu.id</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">instance_type</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"m6i.2xlarge"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre></figure></div></div>
<p>Instead of querying the AMI ID and spinning up the instance, we can write test code as follows:</p>
<div class="language-hcl codeBlockContainer_APcc theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_m3Ux"><figure><figcaption class="sr-only">Code Block</figcaption><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div><pre tabindex="0" class="prism-code language-hcl codeBlock_qGQc thin-scrollbar" style="color:#F8F8F2;background-color:#282A36" role="code" aria-label="Code Block"><code class="codeBlockLines_p187"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">provider</span><span class="token keyword type variable" style="color:rgb(189, 147, 249);font-style:italic"> "aws" </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">access_key</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"foo"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">secret_key</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"bar"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">skip_credentials_validation</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token boolean">true</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">skip_region_validation</span><span class="token plain">      </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token boolean">true</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">skip_metadata_api_check</span><span class="token plain">     </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token boolean">true</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">skip_requesting_account_id</span><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token boolean">true</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token comment" style="color:rgb(98, 114, 164)"># This block disables refreshing the aws_ami.ubuntu data source</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token comment" style="color:rgb(98, 114, 164)"># and lets you manually specify the values:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">override_data</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">target</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> data.aws_ami.ubuntu</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">values</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">id</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"ami-12345"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">run </span><span class="token string" style="color:rgb(255, 121, 198)">"test"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token comment" style="color:rgb(98, 114, 164)"># This block disables provisioning the aws_instance.web resource:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">override_resource</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">target</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> aws_instance.web</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">values</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token comment" style="color:rgb(98, 114, 164)"># You can add values here.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">assert</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">condition</span><span class="token plain">     </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> aws_instance.web.ami </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"ami-12345"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">error_message</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"Incorrect AMI ID passed to aws_instance.web: </span><span class="token string interpolation punctuation" style="color:rgb(248, 248, 242)">$</span><span class="token string interpolation punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token string interpolation" style="color:rgb(255, 121, 198)">aws_instance</span><span class="token string interpolation punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token string interpolation" style="color:rgb(255, 121, 198)">web</span><span class="token string interpolation punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token string interpolation" style="color:rgb(255, 121, 198)">ami</span><span class="token string interpolation punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token string" style="color:rgb(255, 121, 198)">"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre></figure></div></div>
<p>While this will not fully test the entire provisioning, it will highlight errors that may be caused by incorrectly connecting resources together without the need for an actual AWS account. Similarly, you can use <code>override_module</code> to override an entire module.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="early-variablelocals-evaluation">Early variable/locals evaluation<a href="https://opentofu.org/blog/opentofu-1-8-0-beta1#early-variablelocals-evaluation" class="hash-link" aria-label="Direct link to Early variable/locals evaluation" title="Direct link to Early variable/locals evaluation">​</a></h2>
<p>Introduced in OpenTofu 1.8.0-alpha1, this feature lets you use variables and locals for <strong>backends</strong>, <strong>module sources</strong> and <strong>encryption configuration</strong> as long as they are not dependent on resources, data sources or module outputs. This works even if a local is referencing a variable, for example. This is only the first in a series of improvements that will make the .tf code more flexible with more improvements coming in future releases.</p>
<p>The <code>tofu init</code> command will now consume your <code>.tfvars</code> file and let you specify variables using the <code>-var</code> and <code>-var-file</code> options. Please note that this alpha release will <em>not</em> prompt you for missing variables, which is a feature we will add later. Note, that <code>tofu init</code> will fail if it is missing variables needed for static evaluation.</p>
<p>For example, if you wanted to use the same configuration for your S3 backend and your AWS provider, you can now do this:</p>
<div class="language-hcl codeBlockContainer_APcc theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_m3Ux"><figure><figcaption class="sr-only">Code Block</figcaption><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div><pre tabindex="0" class="prism-code language-hcl codeBlock_qGQc thin-scrollbar" style="color:#F8F8F2;background-color:#282A36" role="code" aria-label="Code Block"><code class="codeBlockLines_p187"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">variable</span><span class="token keyword type variable" style="color:rgb(189, 147, 249);font-style:italic"> "aws_region" </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">default</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"us-east-1"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">terraform</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">backend</span><span class="token keyword type variable" style="color:rgb(189, 147, 249);font-style:italic"> "s3" </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">region</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> var.aws_region</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">provider</span><span class="token keyword type variable" style="color:rgb(189, 147, 249);font-style:italic"> "aws" </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">region</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> var.aws_region</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre></figure></div></div>
<p>You can also use this to manage module versions with both registry references and git URLs.</p>
<div class="language-hcl codeBlockContainer_APcc theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_m3Ux"><figure><figcaption class="sr-only">Code Block</figcaption><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div><pre tabindex="0" class="prism-code language-hcl codeBlock_qGQc thin-scrollbar" style="color:#F8F8F2;background-color:#282A36" role="code" aria-label="Code Block"><code class="codeBlockLines_p187"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">locals</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">aws_module_version</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"5.6.1"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">module</span><span class="token keyword type variable" style="color:rgb(189, 147, 249);font-style:italic"> "webserver" </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">source</span><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"terraform-aws-modules/ec2-instance/aws"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">version</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> local.aws_module_version</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token comment" style="color:rgb(98, 114, 164)">// Other ec2_instance options</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">module</span><span class="token keyword type variable" style="color:rgb(189, 147, 249);font-style:italic"> "db" </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">source</span><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"https://github.com/terraform-aws-modules/terraform-aws-ec2-instance?ref=v</span><span class="token string interpolation punctuation" style="color:rgb(248, 248, 242)">$</span><span class="token string interpolation punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token string interpolation keyword" style="color:rgb(189, 147, 249);font-style:italic">local</span><span class="token string interpolation punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token string interpolation type variable" style="color:rgb(189, 147, 249);font-style:italic">aws_module_version</span><span class="token string interpolation punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token string" style="color:rgb(255, 121, 198)">"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token comment" style="color:rgb(98, 114, 164)">// Other ec2_instance options</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre></figure></div></div>
<p>Finally, here's how you can set up encryption with a passphrase using a variable:</p>
<div class="language-hcl codeBlockContainer_APcc theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_m3Ux"><figure><figcaption class="sr-only">Code Block</figcaption><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div><pre tabindex="0" class="prism-code language-hcl codeBlock_qGQc thin-scrollbar" style="color:#F8F8F2;background-color:#282A36" role="code" aria-label="Code Block"><code class="codeBlockLines_p187"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">variable</span><span class="token keyword type variable" style="color:rgb(189, 147, 249);font-style:italic"> "passphrase" </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">type</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> string</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">terraform</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">encryption</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    key_provider </span><span class="token string" style="color:rgb(255, 121, 198)">"pbkdf2"</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"my_passphrase"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token property">passphrase</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> var.passphrase</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    method </span><span class="token string" style="color:rgb(255, 121, 198)">"aes_gcm"</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"my_method"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token property">keys</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> key_provider.pbkdf2.my_passphrase</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">state</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token property">method</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> method.aes_gcm.my_method</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre></figure></div></div>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="override-files-for-opentofu-keeping-compatibility">Override files for OpenTofu: keeping compatibility<a href="https://opentofu.org/blog/opentofu-1-8-0-beta1#override-files-for-opentofu-keeping-compatibility" class="hash-link" aria-label="Direct link to Override files for OpenTofu: keeping compatibility" title="Direct link to Override files for OpenTofu: keeping compatibility">​</a></h2>
<p>Since we are now adding features to OpenTofu that are not present in Terraform, we want to give module authors the ability to write code for both OpenTofu and Terraform without needing to maintain two copies of their modules. You can now create files named <code>.tofu</code> that are exclusive to OpenTofu. If you create a file named <code>foo.tofu</code>, OpenTofu will ignore the similarly-named <code>foo.tf</code> file. You can use this functionality to put your Terraform-specific code in the <code>.tf</code> file and then override it for OpenTofu in the <code>.tofu</code> file.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="bugfixes-and-improvements">Bugfixes and improvements<a href="https://opentofu.org/blog/opentofu-1-8-0-beta1#bugfixes-and-improvements" class="hash-link" aria-label="Direct link to Bugfixes and improvements" title="Direct link to Bugfixes and improvements">​</a></h2>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="static-variable-planing">Static Variable Planing<a href="https://opentofu.org/blog/opentofu-1-8-0-beta1#static-variable-planing" class="hash-link" aria-label="Direct link to Static Variable Planing" title="Direct link to Static Variable Planing">​</a></h3>
<p>Static variables are now handled correctly when embedded in plan files. This was <a href="https://github.com/opentofu/opentofu/issues/1768" target="_blank" rel="noopener noreferrer">reported as a bug</a> found in 1.8.0-alpha1.</p>
<div class="language-bash codeBlockContainer_APcc theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_m3Ux"><figure><figcaption class="sr-only">Code Block</figcaption><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div><pre tabindex="0" class="prism-code language-bash codeBlock_qGQc thin-scrollbar" style="color:#F8F8F2;background-color:#282A36" role="code" aria-label="Code Block"><code class="codeBlockLines_p187"><span class="token-line" style="color:#F8F8F2"><span class="token plain">tofu plan -out=tofu.tfstate -var="param=value"</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"># Variables are correctly read from the given plan and should not be specified via CLI</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">tofu show tofu.tfstate</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">tofu apply tofu.tfstate</span><br></span></code></pre></figure></div></div>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="improved-provider-error-messages">Improved provider error messages<a href="https://opentofu.org/blog/opentofu-1-8-0-beta1#improved-provider-error-messages" class="hash-link" aria-label="Direct link to Improved provider error messages" title="Direct link to Improved provider error messages">​</a></h3>
<p>Also included in the beta is <a href="https://github.com/opentofu/opentofu/issues/1484" target="_blank" rel="noopener noreferrer">improvements in error messages produced by misconfigured providers</a>. Some defaulted providers which require configuration blocks were able to generate error messages like:</p>
<div class="codeBlockContainer_APcc theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_m3Ux"><figure><figcaption class="sr-only">Code Block</figcaption><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div><pre tabindex="0" class="prism-code language-text codeBlock_qGQc thin-scrollbar" style="color:#F8F8F2;background-color:#282A36" role="code" aria-label="Code Block"><code class="codeBlockLines_p187"><span class="token-line" style="color:#F8F8F2"><span class="token plain">╷</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">│ Error: Insufficient features blocks</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">│</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">│   on &lt;empty&gt; line 0:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">│   (source code not available)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">│</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">│ At least 1 "features" blocks are required.</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">╵</span><br></span></code></pre></figure></div></div>
<p>This error message will now include information about which provider is encountering the specific missing-block validation issue to help the user track it down.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="providing-feedback">Providing feedback<a href="https://opentofu.org/blog/opentofu-1-8-0-beta1#providing-feedback" class="hash-link" aria-label="Direct link to Providing feedback" title="Direct link to Providing feedback">​</a></h2>
<p>Thank you for taking the time to test this preview release. If you have any feedback, please use <a href="https://github.com/opentofu/opentofu/issues/new/choose" target="_blank" rel="noopener noreferrer">a GitHub issue</a> or chat with us on the <a href="https://opentofu.org/slack/" target="_blank" rel="noopener noreferrer">OpenTofu Slack</a>.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Help us test OpenTofu 1.8.0-alpha1]]></title>
            <link>https://opentofu.org/blog/help-us-test-opentofu-1-8-0-alpha1</link>
            <guid>https://opentofu.org/blog/help-us-test-opentofu-1-8-0-alpha1</guid>
            <pubDate>Mon, 24 Jun 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Hey there, OpenTofu community! Since the last OpenTofu release we've been hard at work bringing you a much-needed improvement to the .tf language: the ability to use variables in backends, module sources, and the encryption configuration (early variable/locals evaluation). This is currently the top-voted issue on the OpenTofu GitHub and has, in various forms, been requested for years with OpenTofu's predecessor.]]></description>
            <content:encoded><![CDATA[<p>Hey there, OpenTofu community! Since the last OpenTofu release we've been hard at work bringing you a much-needed improvement to the .tf language: the ability to <strong>use variables in backends, module sources, and the encryption configuration</strong> (<em>early variable/locals evaluation</em>). This is currently the <a href="https://github.com/opentofu/opentofu/issues/1496" target="_blank" rel="noopener noreferrer">top-voted issue on the OpenTofu GitHub</a> and has, in various forms, been requested for years with OpenTofu's predecessor.</p>
<p>Additionally, we are bringing you a feature that lets you use new OpenTofu features while still keeping compatibility with Terraform as well as the ability to override resources and data sources in <code>tofu test</code>. The release also includes a host of smaller improvements and bugfixes to various parts of OpenTofu <a href="https://github.com/opentofu/opentofu/blob/main/CHANGELOG.md" target="_blank" rel="noopener noreferrer">listed in the changelog</a>.</p>
<p>Now we'd like to ask you for help: we have done everything we could to make sure that the new alpha release doesn't break anything, and we need your help to get this release tested. If you have a <strong>non-production</strong> setup that you would be willing to test any of the new features on, please give it a try and give us <a href="https://github.com/opentofu/opentofu/issues/new/choose" target="_blank" rel="noopener noreferrer">feedback using a GitHub issue</a>, even if it's just telling us that everything went well.</p>
<p>This blog post will go over how to download the new preview release and detail how each of the new features works.</p>
<div class="flex flex-col py-2 px-3 not-prose border gap-1 [&amp;+&amp;]:mt-3 [&amp;_a:hover]:text-gray-900 dark:[&amp;_a:hover]:text-gray-50 [&amp;_a>code]:font-bold [&amp;_code]:text-base [&amp;_code]:px-1.5 [&amp;_a]:underline [&amp;_p]:mb-2 bg-yellow-100 border-yellow-500 text-yellow-800 dark:bg-yellow-950 dark:border-yellow-700 dark:text-yellow-100" role="alert"><div class="flex gap-3 font-bold"><span class="flex w-4 fill-current [&amp;>svg]:w-full" aria-hidden="true"><svg viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"></path></svg></span>Warning</div><div class="leading-relaxed"><p>Do not test this release on a production project! It is not a stable release!</p></div></div>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="downloading-the-alpha-release">Downloading the alpha release<a href="https://opentofu.org/blog/help-us-test-opentofu-1-8-0-alpha1#downloading-the-alpha-release" class="hash-link" aria-label="Direct link to Downloading the alpha release" title="Direct link to Downloading the alpha release">​</a></h2>
<p>The alpha release is available exclusively from the <a href="https://github.com/opentofu/opentofu/releases/tag/v1.8.0-alpha1" target="_blank" rel="noopener noreferrer">GitHub Releases page</a>. Please select the appropriate file for your platform. Here are some quick links:</p>
<table><thead><tr><th>Platform/Device</th><th>Download link</th></tr></thead><tbody><tr><td><strong>Desktop Windows computer</strong><br>(64-bit)</td><td><a href="https://github.com/opentofu/opentofu/releases/download/v1.8.0-alpha1/tofu_1.8.0-alpha1_windows_amd64.zip" target="_blank" rel="noopener noreferrer">tofu_1.8.0-alpha1_windows_amd64.zip</a></td></tr><tr><td><strong>MacOS</strong><br>(Macbook M1 or higher; ARM64)</td><td><a href="https://github.com/opentofu/opentofu/releases/download/v1.8.0-alpha1/tofu_1.8.0-alpha1_darwin_arm64.tar.gz" target="_blank" rel="noopener noreferrer">tofu_1.8.0-alpha1_darwin_arm64.tar.gz</a></td></tr><tr><td><strong>MacOS</strong><br>(Macbook pre-M1; AMD64)</td><td><a href="https://github.com/opentofu/opentofu/releases/download/v1.8.0-alpha1/tofu_1.8.0-alpha1_darwin_amd64.tar.gz" target="_blank" rel="noopener noreferrer">tofu_1.8.0-alpha1_darwin_amd64.tar.gz</a></td></tr><tr><td><strong>Intel/AMD Linux computer or server</strong><br>(AMD64)</td><td><a href="https://github.com/opentofu/opentofu/releases/download/v1.8.0-alpha1/tofu_1.8.0-alpha1_linux_amd64.tar.gz" target="_blank" rel="noopener noreferrer">tofu_1.8.0-alpha1_linux_amd64.tar.gz</a></td></tr><tr><td><strong>ARM-based Linux computer<br>or<br>Raspberry Pi 3 or higher</strong><br>(ARM64)</td><td><a href="https://github.com/opentofu/opentofu/releases/download/v1.8.0-alpha1/tofu_1.8.0-alpha1_linux_arm64.tar.gz" target="_blank" rel="noopener noreferrer">tofu_1.8.0-alpha1_linux_arm64.tar.gz</a></td></tr></tbody></table>
<p>For the releases above, please unpack the archive and you should find the <code>tofu</code> binary inside. You can also use the <a href="https://opentofu.org/docs/intro/install/standalone/" target="_blank" rel="noopener noreferrer">standalone installer</a> to download the release with signature verification.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="early-variablelocals-evaluation">Early variable/locals evaluation<a href="https://opentofu.org/blog/help-us-test-opentofu-1-8-0-alpha1#early-variablelocals-evaluation" class="hash-link" aria-label="Direct link to Early variable/locals evaluation" title="Direct link to Early variable/locals evaluation">​</a></h2>
<p>This feature lets you use variables and locals for <strong>backends</strong>, <strong>module sources</strong> and <strong>encryption configuration</strong> as long as they are not dependent on resources, data sources or module outputs. This works even if a local is referencing a variable, for example. This is only the first in a series of improvements that will make the .tf code more flexible with more improvements coming in future releases.</p>
<p>The <code>tofu init</code> command will now consume your <code>.tfvars</code> file and let you specify variables using the <code>-var</code> and <code>-var-file</code> options. Please note that this alpha release will <em>not</em> prompt you for missing variables, which is a feature we will add later. Note, that <code>tofu init</code> will fail if it is missing variables needed for static evaluation.</p>
<p>For example, if you wanted to use the same configuration for your S3 backend and your AWS provider, you can now do this:</p>
<div class="language-hcl codeBlockContainer_APcc theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_m3Ux"><figure><figcaption class="sr-only">Code Block</figcaption><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div><pre tabindex="0" class="prism-code language-hcl codeBlock_qGQc thin-scrollbar" style="color:#F8F8F2;background-color:#282A36" role="code" aria-label="Code Block"><code class="codeBlockLines_p187"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">variable</span><span class="token keyword type variable" style="color:rgb(189, 147, 249);font-style:italic"> "aws_region" </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">default</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"us-east-1"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">terraform</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">backend</span><span class="token keyword type variable" style="color:rgb(189, 147, 249);font-style:italic"> "s3" </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">region</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> var.aws_region</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">provider</span><span class="token keyword type variable" style="color:rgb(189, 147, 249);font-style:italic"> "aws" </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">region</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> var.aws_region</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre></figure></div></div>
<p>You can also use this to manage module versions with both registry references and git URLs.</p>
<div class="language-hcl codeBlockContainer_APcc theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_m3Ux"><figure><figcaption class="sr-only">Code Block</figcaption><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div><pre tabindex="0" class="prism-code language-hcl codeBlock_qGQc thin-scrollbar" style="color:#F8F8F2;background-color:#282A36" role="code" aria-label="Code Block"><code class="codeBlockLines_p187"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">locals</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">aws_module_version</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"5.6.1"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">module</span><span class="token keyword type variable" style="color:rgb(189, 147, 249);font-style:italic"> "webserver" </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">source</span><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"terraform-aws-modules/ec2-instance/aws"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">version</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> local.aws_module_version</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token comment" style="color:rgb(98, 114, 164)">// Other ec2_instance options</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">module</span><span class="token keyword type variable" style="color:rgb(189, 147, 249);font-style:italic"> "db" </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">source</span><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"https://github.com/terraform-aws-modules/terraform-aws-ec2-instance?ref=v</span><span class="token string interpolation punctuation" style="color:rgb(248, 248, 242)">$</span><span class="token string interpolation punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token string interpolation keyword" style="color:rgb(189, 147, 249);font-style:italic">local</span><span class="token string interpolation punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token string interpolation type variable" style="color:rgb(189, 147, 249);font-style:italic">aws_module_version</span><span class="token string interpolation punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token string" style="color:rgb(255, 121, 198)">"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token comment" style="color:rgb(98, 114, 164)">// Other ec2_instance options</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre></figure></div></div>
<p>Finally, here's how you can set up encryption with a passphrase using a variable:</p>
<div class="language-hcl codeBlockContainer_APcc theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_m3Ux"><figure><figcaption class="sr-only">Code Block</figcaption><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div><pre tabindex="0" class="prism-code language-hcl codeBlock_qGQc thin-scrollbar" style="color:#F8F8F2;background-color:#282A36" role="code" aria-label="Code Block"><code class="codeBlockLines_p187"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">variable</span><span class="token keyword type variable" style="color:rgb(189, 147, 249);font-style:italic"> "passphrase" </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">type</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> string</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">terraform</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">encryption</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    key_provider </span><span class="token string" style="color:rgb(255, 121, 198)">"pbkdf2"</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"my_passphrase"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token property">passphrase</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> var.passphrase</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    method </span><span class="token string" style="color:rgb(255, 121, 198)">"aes_gcm"</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"my_method"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token property">keys</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> key_provider.pbkdf2.my_passphrase</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">state</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token property">method</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> method.aes_gcm.my_method</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre></figure></div></div>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="override-files-for-opentofu-keeping-compatibility">Override files for OpenTofu: keeping compatibility<a href="https://opentofu.org/blog/help-us-test-opentofu-1-8-0-alpha1#override-files-for-opentofu-keeping-compatibility" class="hash-link" aria-label="Direct link to Override files for OpenTofu: keeping compatibility" title="Direct link to Override files for OpenTofu: keeping compatibility">​</a></h2>
<p>Since we are now adding features to OpenTofu that are not present in Terraform, we want to give module authors the ability to write code for both OpenTofu and Terraform without needing to maintain two copies of their modules. You can now create files named <code>.tofu</code> that are exclusive to OpenTofu. If you create a file named <code>foo.tofu</code>, OpenTofu will ignore the similarly-named <code>foo.tf</code> file. You can use this functionality to put your Terraform-specific code in the <code>.tf</code> file and then override it for OpenTofu in the <code>.tofu</code> file.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="resource-overrides-in-tofu-test">Resource overrides in <code>tofu test</code><a href="https://opentofu.org/blog/help-us-test-opentofu-1-8-0-alpha1#resource-overrides-in-tofu-test" class="hash-link" aria-label="Direct link to resource-overrides-in-tofu-test" title="Direct link to resource-overrides-in-tofu-test">​</a></h2>
<p>This version also brings an improvement for the <code>tofu test</code> command. You can now override resources, data sources and entire modules from your tests, allowing you to create similar behavior to mocks in traditional software testing. As an example, consider the following code that spins up an <code>m6i.2xlarge</code> instance on AWS:</p>
<div class="language-hcl codeBlockContainer_APcc theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_m3Ux"><figure><figcaption class="sr-only">Code Block</figcaption><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div><pre tabindex="0" class="prism-code language-hcl codeBlock_qGQc thin-scrollbar" style="color:#F8F8F2;background-color:#282A36" role="code" aria-label="Code Block"><code class="codeBlockLines_p187"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">provider</span><span class="token keyword type variable" style="color:rgb(189, 147, 249);font-style:italic"> "aws" </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">region</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"us-east-1"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">data </span><span class="token keyword type variable" style="color:rgb(189, 147, 249);font-style:italic">"aws_ami"</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"ubuntu"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">most_recent</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token boolean">true</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">filter</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token property">name</span><span class="token plain">   </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"name"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token property">values</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token string" style="color:rgb(255, 121, 198)">"ubuntu/images/hvm-ssd/ubuntu-jammy-24.04-amd64-server-*"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">owners</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token string" style="color:rgb(255, 121, 198)">"099720109477"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">resource </span><span class="token keyword type variable" style="color:rgb(189, 147, 249);font-style:italic">"aws_instance"</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"web"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">ami</span><span class="token plain">           </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> data.aws_ami.ubuntu.id</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">instance_type</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"m6i.2xlarge"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre></figure></div></div>
<p>Instead of querying the AMI ID and spinning up the instance, we can write test code as follows:</p>
<div class="language-hcl codeBlockContainer_APcc theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_m3Ux"><figure><figcaption class="sr-only">Code Block</figcaption><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div><pre tabindex="0" class="prism-code language-hcl codeBlock_qGQc thin-scrollbar" style="color:#F8F8F2;background-color:#282A36" role="code" aria-label="Code Block"><code class="codeBlockLines_p187"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">provider</span><span class="token keyword type variable" style="color:rgb(189, 147, 249);font-style:italic"> "aws" </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">access_key</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"foo"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">secret_key</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"bar"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">skip_credentials_validation</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token boolean">true</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">skip_region_validation</span><span class="token plain">      </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token boolean">true</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">skip_metadata_api_check</span><span class="token plain">     </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token boolean">true</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">skip_requesting_account_id</span><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token boolean">true</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token comment" style="color:rgb(98, 114, 164)"># This block disables refreshing the aws_ami.ubuntu data source</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token comment" style="color:rgb(98, 114, 164)"># and lets you manually specify the values:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">override_data</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">target</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> data.aws_ami.ubuntu</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">values</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">id</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"ami-12345"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">run </span><span class="token string" style="color:rgb(255, 121, 198)">"test"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token comment" style="color:rgb(98, 114, 164)"># This block disables provisioning the aws_instance.web resource:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">override_resource</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">target</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> aws_instance.web</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">values</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token comment" style="color:rgb(98, 114, 164)"># You can add values here.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">assert</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">condition</span><span class="token plain">     </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> aws_instance.web.ami </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"ami-12345"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">error_message</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"Incorrect AMI ID passed to aws_instance.web: </span><span class="token string interpolation punctuation" style="color:rgb(248, 248, 242)">$</span><span class="token string interpolation punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token string interpolation" style="color:rgb(255, 121, 198)">aws_instance</span><span class="token string interpolation punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token string interpolation" style="color:rgb(255, 121, 198)">web</span><span class="token string interpolation punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token string interpolation" style="color:rgb(255, 121, 198)">ami</span><span class="token string interpolation punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token string" style="color:rgb(255, 121, 198)">"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre></figure></div></div>
<p>While this will not fully test the entire provisioning, it will highlight errors that may be caused by incorrectly connecting resources together without the need for an actual AWS account. Similarly, you can use <code>override_module</code> to override an entire module.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="providing-feedback">Providing feedback<a href="https://opentofu.org/blog/help-us-test-opentofu-1-8-0-alpha1#providing-feedback" class="hash-link" aria-label="Direct link to Providing feedback" title="Direct link to Providing feedback">​</a></h2>
<p>Thank you for taking the time to test this preview release. If you have any feedback, please use <a href="https://github.com/opentofu/opentofu/issues/new/choose" target="_blank" rel="noopener noreferrer">a GitHub issue</a> or chat with us on the <a href="https://opentofu.org/slack/" target="_blank" rel="noopener noreferrer">OpenTofu Slack</a>.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[OpenTofu 1.7.0 is out with State Encryption, Dynamic Provider-Defined Functions, and more]]></title>
            <link>https://opentofu.org/blog/opentofu-1-7-0</link>
            <guid>https://opentofu.org/blog/opentofu-1-7-0</guid>
            <pubDate>Tue, 30 Apr 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[OpenTofu 1.7.0 is now available with full state encryption, dynamic provider-defined functions, the removed and loopable import blocks, new migration guides, and much more.]]></description>
            <content:encoded><![CDATA[<p>In the last few months <a href="https://opentofu.org/blog/opentofu-is-going-ga/">since our first stable release</a> the OpenTofu community and the core team have worked hand in hand to bring functionality to OpenTofu that has been requested for years. We are proud to announce the immediate availability of <a href="https://github.com/opentofu/opentofu/releases/tag/v1.7.0" target="_blank" rel="noopener noreferrer">OpenTofu 1.7.0</a>, bringing you the following highlights:</p>
<ul>
<li><a href="https://opentofu.org/docs/v1.7/intro/whats-new/#state-encryption"><strong>End-to-end state encryption</strong></a> protects your state file from prying eyes, no matter what storage backend you use. You can provide your encryption passphrase securely using environment variables, or use a key management system such as AWS KMS, GCP KMS, or OpenBao. <em>This feature has been developed in collaboration with Stephan Bartels (Interhyp) and Alex Scheel from the OpenTofu community, whom we would like to thank for their work on this feature.</em></li>
<li><a href="https://opentofu.org/docs/v1.7/intro/whats-new/#provider-defined-functions"><strong>Dynamic provider-defined functions</strong></a> let a provider not only provide resources, but also native functions you can use in your OpenTofu code. What's more, we added an OpenTofu-only feature to let providers dynamically define custom functions based on your configuration. This enhancement allows you to fully integrate other programming languages as <a href="https://www.youtube.com/watch?v=6OXBv0MYalY" target="_blank" rel="noopener noreferrer">shown in our live stream</a>. You can try out this functionality with our experimental <a href="https://github.com/opentofu/terraform-provider-lua" target="_blank" rel="noopener noreferrer">Lua</a> and <a href="https://github.com/opentofu/terraform-provider-go" target="_blank" rel="noopener noreferrer">Go</a> providers.</li>
<li><a href="https://opentofu.org/docs/intro/whats-new/#removed-block"><strong>The removed block</strong></a> lets you mark OpenTofu-created resources for removal from the state file, but still keep the infrastructure you created.</li>
<li><a href="https://opentofu.org/docs/intro/whats-new/#loopable-import-blocks"><strong>Loopable import blocks</strong></a> let you bulk-import resources declaratively in your OpenTofu code, helping with large-scale migrations.</li>
</ul>
<p>As with the previous version, OpenTofu remains a drop-in replacement for its predecessor Terraform™ 1.5 and has easy migration paths from later versions. Check out the overhauled <a href="https://opentofu.org/docs/v1.7/intro/migration/"><strong>migration guides</strong></a> for detailed migration instructions. You can find the full list of changes and comprehensive examples <a href="https://opentofu.org/docs/v1.7/intro/whats-new/">in the documentation</a>.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="the-opentofu-community-grew-significantly">The OpenTofu community grew significantly<a href="https://opentofu.org/blog/opentofu-1-7-0#the-opentofu-community-grew-significantly" class="hash-link" aria-label="Direct link to The OpenTofu community grew significantly" title="Direct link to The OpenTofu community grew significantly">​</a></h2>
<p>Since the first release, the OpenTofu community and adoption have been growing significantly. While we don't believe in tracking our users and don't have accurate numbers, we have seen a constant month-over-month growth in our registry usage since our launch only 4 months ago. Over just the last month our registry usage has more than doubled to well over a million requests per day.</p>
<p><img loading="lazy" alt="A graph showing OpenTofu&amp;#39;s registry usage." src="https://opentofu.org/assets/images/opentofu-registry-april-2024-f9521461bf6bc2583f816431afb75c9f.svg" width="1542" height="620" class="img_ev3q"></p>
<p>Additionally, we had 65 unique contributors for this release alone and have recently reached 20,000 stars on GitHub. Since January, we have seen our community spread the word about OpenTofu, open over 200 new issues and file even more pull requests.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="what-is-opentofu-anyway">What is OpenTofu anyway?<a href="https://opentofu.org/blog/opentofu-1-7-0#what-is-opentofu-anyway" class="hash-link" aria-label="Direct link to What is OpenTofu anyway?" title="Direct link to What is OpenTofu anyway?">​</a></h2>
<p>If you are new to OpenTofu, welcome! We started as a fork of HashiCorp's Terraform™ after its license was changed to the restrictive BUSL alongside a frequently changing licensing FAQ. OpenTofu is an infrastructure-as-code tool that lets you declaratively create cloud infrastructure with thousands of APIs by writing your own code or using one of the tens of thousands of community-provided modules.</p>
<p>For example, you could create an EC2 instance on AWS like this:</p>
<div class="language-hcl codeBlockContainer_APcc theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_m3Ux"><figure><figcaption class="sr-only">Code Block</figcaption><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div><pre tabindex="0" class="prism-code language-hcl codeBlock_qGQc thin-scrollbar" style="color:#F8F8F2;background-color:#282A36" role="code" aria-label="Code Block"><code class="codeBlockLines_p187"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">resource </span><span class="token keyword type variable" style="color:rgb(189, 147, 249);font-style:italic">"aws_instance"</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"web"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">ami</span><span class="token plain">           </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"add AMI ID here"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">instance_type</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"t3.micro"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre></figure></div></div>
<p>OpenTofu's main advantage is that it records any changes to your cloud infrastructure in a state file, which allows it to later modify the same infrastructure, or tear it down if you created it as a test.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="the-future-and-beyond-opentofu-18-is-waiting">The future and beyond: OpenTofu 1.8 is waiting<a href="https://opentofu.org/blog/opentofu-1-7-0#the-future-and-beyond-opentofu-18-is-waiting" class="hash-link" aria-label="Direct link to The future and beyond: OpenTofu 1.8 is waiting" title="Direct link to The future and beyond: OpenTofu 1.8 is waiting">​</a></h2>
<p>OpenTofu is first and foremost a community-driven project. We are looking forward to the continued tradition of working on issues the community deems important. For transparency and to encourage everyone to vote, we have created <a href="https://github.com/opentofu/opentofu/issues/1496" target="_blank" rel="noopener noreferrer">a list of the most upvoted issues</a>.</p>
<p>While much of OpenTofu 1.8 is still in planning, we are currently finalizing a proposal for a feature that lets you <a href="https://github.com/opentofu/opentofu/issues/1042" target="_blank" rel="noopener noreferrer">use variables as module sources, backend configuration, and more</a>. Early evaluation of variables has been requested in over 30 issues so far and is one of the most-requested features in OpenTofu.</p>
<p>If you have a feature you would like to see in OpenTofu, please don't hesitate to <a href="https://github.com/opentofu/opentofu/issues/new/choose" target="_blank" rel="noopener noreferrer">open an issue</a> or <a href="https://opentofu.org/slack/" target="_blank" rel="noopener noreferrer">reach out to us on Slack</a>.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Get ready for OpenTofu 1.7.0-beta1]]></title>
            <link>https://opentofu.org/blog/opentofu-1-7-0-beta1</link>
            <guid>https://opentofu.org/blog/opentofu-1-7-0-beta1</guid>
            <pubDate>Thu, 18 Apr 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[This version includes provider-defined functions and significant improvements from the alpha version.]]></description>
            <content:encoded><![CDATA[<p>This version includes provider-defined functions and significant improvements from the alpha version.</p>
<p>As with the <a href="https://opentofu.org/blog/help-us-test-opentofu-1-7-0-alpha1/">alpha version</a>, we did everything we could to test this version and would like to ask for the help of the community to help us test this version on <strong>non-production</strong> workloads. <a href="https://github.com/opentofu/opentofu/releases/tag/v1.7.0-beta1" target="_blank" rel="noopener noreferrer">Grab your copy on GitHub</a> and let us know what you think using <a href="https://github.com/opentofu/opentofu/issues/new/choose" target="_blank" rel="noopener noreferrer">a GitHub issue</a>.</p>
<div class="flex flex-col py-2 px-3 not-prose border gap-1 [&amp;+&amp;]:mt-3 [&amp;_a:hover]:text-gray-900 dark:[&amp;_a:hover]:text-gray-50 [&amp;_a>code]:font-bold [&amp;_code]:text-base [&amp;_code]:px-1.5 [&amp;_a]:underline [&amp;_p]:mb-2 bg-yellow-100 border-yellow-500 text-yellow-800 dark:bg-yellow-950 dark:border-yellow-700 dark:text-yellow-100" role="alert"><div class="flex gap-3 font-bold"><span class="flex w-4 fill-current [&amp;>svg]:w-full" aria-hidden="true"><svg viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"></path></svg></span>Warning</div><div class="leading-relaxed"><p>Do not test this release on a production project! It is not a stable release!</p></div></div>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="downloading-the-beta-release">Downloading the beta release<a href="https://opentofu.org/blog/opentofu-1-7-0-beta1#downloading-the-beta-release" class="hash-link" aria-label="Direct link to Downloading the beta release" title="Direct link to Downloading the beta release">​</a></h2>
<p>The beta release is available exclusively from the <a href="https://github.com/opentofu/opentofu/releases/tag/v1.7.0-beta1" target="_blank" rel="noopener noreferrer">GitHub Releases page</a>. Please select the appropriate file for your platform. Here are some quick links:</p>
<table><thead><tr><th>Platform/Device</th><th>Download link</th></tr></thead><tbody><tr><td><strong>Desktop Windows computer</strong><br>(64-bit)</td><td><a href="https://github.com/opentofu/opentofu/releases/download/v1.7.0-beta1/tofu_1.7.0-beta1_windows_amd64.zip" target="_blank" rel="noopener noreferrer">tofu_1.7.0-beta1_windows_amd64.zip</a></td></tr><tr><td><strong>MacOS</strong><br>(Macbook M1 or higher; ARM64)</td><td><a href="https://github.com/opentofu/opentofu/releases/download/v1.7.0-beta1/tofu_1.7.0-beta1_darwin_arm64.tar.gz" target="_blank" rel="noopener noreferrer">tofu_1.7.0-beta1_darwin_arm64.tar.gz</a></td></tr><tr><td><strong>MacOS</strong><br>(Macbook pre-M1 or lower; AMD64)</td><td><a href="https://github.com/opentofu/opentofu/releases/download/v1.7.0-beta1/tofu_1.7.0-beta1_darwin_amd64.tar.gz" target="_blank" rel="noopener noreferrer">tofu_1.7.0-beta1_darwin_amd64.tar.gz</a></td></tr><tr><td><strong>Intel/AMD Linux computer or server</strong><br>(AMD64)</td><td><a href="https://github.com/opentofu/opentofu/releases/download/v1.7.0-beta1/tofu_1.7.0-beta1_linux_amd64.tar.gz" target="_blank" rel="noopener noreferrer">tofu_1.7.0-beta1_linux_amd64.tar.gz</a></td></tr><tr><td><strong>ARM-based Linux computer<br>or<br>Raspberry Pi 3 or higher</strong><br>(ARM64)</td><td><a href="https://github.com/opentofu/opentofu/releases/download/v1.7.0-beta1/tofu_1.7.0-beta1_linux_arm64.tar.gz" target="_blank" rel="noopener noreferrer">tofu_1.7.0-beta1_linux_arm64.tar.gz</a></td></tr></tbody></table>
<p>For the releases above, please unpack the archive and you should find the <code>tofu</code> binary inside. You can also use the <a href="https://opentofu.org/docs/intro/install/standalone/" target="_blank" rel="noopener noreferrer">standalone installer</a> to download the release with signature verification.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="provider-defined-functions">Provider-defined functions<a href="https://opentofu.org/blog/opentofu-1-7-0-beta1#provider-defined-functions" class="hash-link" aria-label="Direct link to Provider-defined functions" title="Direct link to Provider-defined functions">​</a></h2>
<p>The new Terraform Plugin SDK added support for provider-defined functions that you can use directly in OpenTofu. This is a significant improvement over using data sources as provider-defined functions don't increase the size of your state file and require less code to write.</p>
<p>If you want to test provider-defined functions, you can use the <a href="https://library.tf/providers/northwood-labs/corefunc/latest" target="_blank" rel="noopener noreferrer">corefunc</a> provider by <a href="https://github.com/skyzyx" target="_blank" rel="noopener noreferrer">Ryan Parman</a>:</p>
<div class="language-hcl codeBlockContainer_APcc theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_m3Ux"><figure><figcaption class="sr-only">Code Block</figcaption><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div><pre tabindex="0" class="prism-code language-hcl codeBlock_qGQc thin-scrollbar" style="color:#F8F8F2;background-color:#282A36" role="code" aria-label="Code Block"><code class="codeBlockLines_p187"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">terraform</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">required_providers</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">corefunc</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token property">source</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"northwood-labs/corefunc"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token property">version</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"1.4.0"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">provider</span><span class="token keyword type variable" style="color:rgb(189, 147, 249);font-style:italic"> "corefunc" </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">output</span><span class="token keyword type variable" style="color:rgb(189, 147, 249);font-style:italic"> "test" </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">value</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> provider::corefunc::str_snake(</span><span class="token string" style="color:rgb(255, 121, 198)">"Hello world!"</span><span class="token plain">)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token comment" style="color:rgb(98, 114, 164)"># Prints: hello_world</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre></figure></div></div>
<div class="flex flex-col py-2 px-3 not-prose border gap-1 [&amp;+&amp;]:mt-3 [&amp;_a:hover]:text-gray-900 dark:[&amp;_a:hover]:text-gray-50 [&amp;_a>code]:font-bold [&amp;_code]:text-base [&amp;_code]:px-1.5 [&amp;_a]:underline [&amp;_p]:mb-2 bg-sky-100 border-sky-300 text-sky-800 dark:bg-sky-950 dark:border-sky-700 dark:text-sky-100" role="alert"><div class="flex gap-3 font-bold"><span class="flex w-4 fill-current [&amp;>svg]:w-full" aria-hidden="true"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>Note</div><div class="leading-relaxed"><p>If you are interested in a detailed breakdown of this functionality and some of the new unique features OpenTofu brings in this area, <a href="https://www.youtube.com/watch?v=6OXBv0MYalY" target="_blank" rel="noopener noreferrer">join our live stream on April 24</a>.</p></div></div>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="loopable-import-blocks">Loopable import blocks<a href="https://opentofu.org/blog/opentofu-1-7-0-beta1#loopable-import-blocks" class="hash-link" aria-label="Direct link to Loopable import blocks" title="Direct link to Loopable import blocks">​</a></h2>
<p>We made several improvements to the declarative import blocks, most prominently you can now use the <code>for_each</code> instruction on the block. We have prepared a <a href="https://opentofu.org/docs/language/import/#importing-multiple-resources">full documentation</a> for this feature.</p>
<p>In previous OpenTofu versions, you could already use the <code>import</code> block to declaratively import resources, for example:</p>
<div class="language-hcl codeBlockContainer_APcc theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_m3Ux"><figure><figcaption class="sr-only">Code Block</figcaption><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div><pre tabindex="0" class="prism-code language-hcl codeBlock_qGQc thin-scrollbar" style="color:#F8F8F2;background-color:#282A36" role="code" aria-label="Code Block"><code class="codeBlockLines_p187"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">resource </span><span class="token keyword type variable" style="color:rgb(189, 147, 249);font-style:italic">"random_id"</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"test_id"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">byte_length</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token number">8</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">import</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">to</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> random_id.test_id</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">id</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"Y2FpOGV1Mkk"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">output</span><span class="token keyword type variable" style="color:rgb(189, 147, 249);font-style:italic"> "id" </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">value</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> random_id.test_id.b64_url</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre></figure></div></div>
<p>In this new version you can now also declaratively import resources in a loop:</p>
<div class="language-hcl codeBlockContainer_APcc theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_m3Ux"><figure><figcaption class="sr-only">Code Block</figcaption><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div><pre tabindex="0" class="prism-code language-hcl codeBlock_qGQc thin-scrollbar" style="color:#F8F8F2;background-color:#282A36" role="code" aria-label="Code Block"><code class="codeBlockLines_p187"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">variable</span><span class="token keyword type variable" style="color:rgb(189, 147, 249);font-style:italic"> "server_ids" </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">type</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> list(string)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">resource </span><span class="token keyword type variable" style="color:rgb(189, 147, 249);font-style:italic">"random_id"</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"test_id"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">byte_length</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token number">8</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">count</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token number">2</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">import</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">to</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> random_id.test_id</span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token plain">tonumber(each.key)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">id</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> each.value</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">for_each</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    for idx, item in var.server_ids: </span><span class="token property">idx</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain">&gt; item</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">output</span><span class="token keyword type variable" style="color:rgb(189, 147, 249);font-style:italic"> "id" </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">value</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> random_id.test_id.*.b64_url</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre></figure></div></div>
<p>The example above will let you specify some random IDs from a variable, and let others be automatically generated.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="state-encryption">State encryption<a href="https://opentofu.org/blog/opentofu-1-7-0-beta1#state-encryption" class="hash-link" aria-label="Direct link to State encryption" title="Direct link to State encryption">​</a></h2>
<p>State encryption is one of the flagship features of this release. We have prepared a <a href="https://opentofu.org/docs/language/state/encryption/">full documentation</a> for this feature. Since the alpha release we overhauled the migration process from unencrypted to encrypted state files and the rollback mechanism to make the syntax more explicit.</p>
<p>Before you test this feature, please <strong>make a backup</strong> of your state file. You can then add the following block to enable state encryption:</p>
<div class="language-hcl codeBlockContainer_APcc theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_m3Ux"><figure><figcaption class="sr-only">Code Block</figcaption><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div><pre tabindex="0" class="prism-code language-hcl codeBlock_qGQc thin-scrollbar" style="color:#F8F8F2;background-color:#282A36" role="code" aria-label="Code Block"><code class="codeBlockLines_p187"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">terraform</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">encryption</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    key_provider </span><span class="token string" style="color:rgb(255, 121, 198)">"pbkdf2"</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"my_passphrase"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token comment" style="color:rgb(98, 114, 164)">## Enter a passphrase here:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token property">passphrase</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">""</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    method </span><span class="token string" style="color:rgb(255, 121, 198)">"aes_gcm"</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"my_method"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token property">keys</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> key_provider.pbkdf2.my_passphrase</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token comment" style="color:rgb(98, 114, 164)">## Remove this after the migration:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    method </span><span class="token string" style="color:rgb(255, 121, 198)">"unencrypted"</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"migration"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">state</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token property">method</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> method.aes_gcm.my_method</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token comment" style="color:rgb(98, 114, 164)">## Remove the fallback block after migration:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      fallback</span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token property">method</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> method.unencrypted.migration</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token comment" style="color:rgb(98, 114, 164)">## Enable this after migration:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token comment" style="color:rgb(98, 114, 164)">#enforced = true</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre></figure></div></div>
<p>You can migrate back using the following syntax:</p>
<div class="language-hcl codeBlockContainer_APcc theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_m3Ux"><figure><figcaption class="sr-only">Code Block</figcaption><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div><pre tabindex="0" class="prism-code language-hcl codeBlock_qGQc thin-scrollbar" style="color:#F8F8F2;background-color:#282A36" role="code" aria-label="Code Block"><code class="codeBlockLines_p187"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">terraform</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">encryption</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    key_provider </span><span class="token string" style="color:rgb(255, 121, 198)">"pbkdf2"</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"my_passphrase"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token comment" style="color:rgb(98, 114, 164)">## Enter a passphrase here:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token property">passphrase</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">""</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    method </span><span class="token string" style="color:rgb(255, 121, 198)">"aes_gcm"</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"my_method"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token property">keys</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> key_provider.pbkdf2.my_passphrase</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    method </span><span class="token string" style="color:rgb(255, 121, 198)">"unencrypted"</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"migration"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">state</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token property">method</span><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> method.unencrypted.migration</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token property">enforced</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token boolean">false</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      fallback</span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token property">method</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> method.aes_gcm.my_method</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre></figure></div></div>
<p>If you have access to an AWS, GCP account, or an OpenBao/MPL-licensed HashiCorp Vault installation, you can also <a href="https://opentofu.org/docs/language/state/encryption/#key-providers">test these key providers</a>.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="removed-block">Removed block<a href="https://opentofu.org/blog/opentofu-1-7-0-beta1#removed-block" class="hash-link" aria-label="Direct link to Removed block" title="Direct link to Removed block">​</a></h2>
<p>The removed block lets you remove a resource from the state file but keep it on the infrastructure. We have prepared a <a href="https://opentofu.org/docs/language/resources/syntax/#removing-resources">full documentation</a> for this feature. You can test it by creating a resource first:</p>
<div class="language-hcl codeBlockContainer_APcc theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_m3Ux"><figure><figcaption class="sr-only">Code Block</figcaption><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div><pre tabindex="0" class="prism-code language-hcl codeBlock_qGQc thin-scrollbar" style="color:#F8F8F2;background-color:#282A36" role="code" aria-label="Code Block"><code class="codeBlockLines_p187"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">resource </span><span class="token keyword type variable" style="color:rgb(189, 147, 249);font-style:italic">"local_file"</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"test"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">content</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"Hello world!"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">filename</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"test.txt"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre></figure></div></div>
<p>After applying, you can replace the resource with a removed block:</p>
<div class="language-hcl codeBlockContainer_APcc theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_m3Ux"><figure><figcaption class="sr-only">Code Block</figcaption><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div><pre tabindex="0" class="prism-code language-hcl codeBlock_qGQc thin-scrollbar" style="color:#F8F8F2;background-color:#282A36" role="code" aria-label="Code Block"><code class="codeBlockLines_p187"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">removed</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">from</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> local_file.test</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre></figure></div></div>
<p>After the next apply, you will see that the <code>local_file.test</code> resource no longer exists in your state file, but the <code>test.txt</code> file should still exist on your disk. You can now remove the removed block safely.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="built-in-function-changes">Built-in function changes<a href="https://opentofu.org/blog/opentofu-1-7-0-beta1#built-in-function-changes" class="hash-link" aria-label="Direct link to Built-in function changes" title="Direct link to Built-in function changes">​</a></h2>
<p>This release also contains several new functions and changes to existing functions:</p>
<ul>
<li>New function: <a href="https://opentofu.org/docs/language/functions/templatestring/">templatestring</a></li>
<li>New function: <a href="https://opentofu.org/docs/language/functions/base64gunzip/">base64gunzip</a></li>
<li>New function: <a href="https://opentofu.org/docs/language/functions/cidrcontains/">cidrcontains</a></li>
<li>New function: <a href="https://opentofu.org/docs/language/functions/urldecode/">urldecode</a></li>
<li>New function: <a href="https://opentofu.org/docs/language/functions/issensitive/">issensitive</a></li>
<li><a href="https://opentofu.org/docs/language/functions/nonsensitive/">nonsensitive</a> no longer returns an error when the applied values are not sensitive.</li>
<li><a href="https://opentofu.org/docs/language/functions/templatefile/">templatefile</a> now supports recursion up to a depth of 1024.</li>
</ul>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="cli-changes">CLI changes<a href="https://opentofu.org/blog/opentofu-1-7-0-beta1#cli-changes" class="hash-link" aria-label="Direct link to CLI changes" title="Direct link to CLI changes">​</a></h2>
<p>There are also several changes to the CLI:</p>
<ul>
<li><code>tofu init</code> now supports the <code>-json</code> flag for JSON output.</li>
<li><code>tofu plan</code> now has a <code>-concise</code> flag to shorten the plan output.</li>
<li><code>tofu console</code> now works on Solaris and AIX.</li>
<li>The CLI now supports the XDG directory specification.</li>
<li>Aliases for:<!-- -->
<ul>
<li><code>state list</code> → <code>state ls</code></li>
<li><code>state mv</code> → <code>state move</code></li>
<li><code>state rm</code> → <code>state remove</code></li>
</ul>
</li>
</ul>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="testing-feature-changes">Testing feature changes<a href="https://opentofu.org/blog/opentofu-1-7-0-beta1#testing-feature-changes" class="hash-link" aria-label="Direct link to Testing feature changes" title="Direct link to Testing feature changes">​</a></h2>
<ul>
<li>Tofu now reads the <code>.tfvars</code> file from the tests folder.</li>
</ul>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="providing-feedback">Providing feedback<a href="https://opentofu.org/blog/opentofu-1-7-0-beta1#providing-feedback" class="hash-link" aria-label="Direct link to Providing feedback" title="Direct link to Providing feedback">​</a></h2>
<p>Thank you for taking the time to test this preview release. If you have any feedback, please use <a href="https://github.com/opentofu/opentofu/issues/new/choose" target="_blank" rel="noopener noreferrer">a GitHub issue</a> or chat with us on the <a href="https://opentofu.org/slack/" target="_blank" rel="noopener noreferrer">OpenTofu Slack</a>.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Our Response to Hashicorp's Cease and Desist Letter]]></title>
            <link>https://opentofu.org/blog/our-response-to-hashicorps-cease-and-desist</link>
            <guid>https://opentofu.org/blog/our-response-to-hashicorps-cease-and-desist</guid>
            <pubDate>Thu, 11 Apr 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[On April 3rd, we received a Cease and Desist letter from HashiCorp regarding our implementation of the "removed" block in OpenTofu, claiming copyright infringement on the part of one of our core developers. We were also made aware of an article posted that same day with the same accusations. We have investigated these claims and are publishing the C&D letter, our response and the source code origin document resulting from our investigation.]]></description>
            <content:encoded><![CDATA[<p>On April 3rd, we received a Cease and Desist letter from HashiCorp regarding our implementation of the "removed" block in OpenTofu, claiming copyright infringement on the part of one of our core developers. We were also made aware of an article posted that same day with the same accusations. We have investigated these claims and are publishing the C&amp;D letter, our response and the source code origin document resulting from our investigation.</p>
<p><strong>The OpenTofu team vehemently disagrees with any suggestion that it misappropriated, mis-sourced, or otherwise misused HashiCorp’s BSL code. All such statements have zero basis in facts.</strong></p>
<p>HashiCorp has made claims of copyright infringement in a cease &amp; desist letter. These claims are <strong>completely unsubstantiated</strong>.</p>
<p>The code in question can be clearly shown to have been copied from older code under the MPL-2.0 license. HashiCorp seems to have copied the same code itself when they implemented their version of this feature. All of this is easily visible in our detailed SCO analysis, as well as their own comments which indicate this.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="documents">Documents<a href="https://opentofu.org/blog/our-response-to-hashicorps-cease-and-desist#documents" class="hash-link" aria-label="Direct link to Documents" title="Direct link to Documents">​</a></h2>
<ul>
<li><a href="https://opentofu.github.io/legal-documents/2024-04-03%20HashiCorp%20C%26D/OpenTofu%20C&amp;D%20-%20Redacted.pdf" target="_blank" rel="noopener noreferrer">HashiCorp's C&amp;D Letter</a></li>
<li><a href="https://opentofu.github.io/legal-documents/2024-04-03%20HashiCorp%20C%26D/OpenTofu%20C&amp;D%20Response%20-%20Redacted.pdf" target="_blank" rel="noopener noreferrer">Our Response</a></li>
<li>Source Code Origin Document: [<a href="https://opentofu.github.io/legal-documents/2024-04-03%20HashiCorp%20C%26D/SCO.html" target="_blank" rel="noopener noreferrer">HTML</a>, <a href="https://opentofu.github.io/legal-documents/2024-04-03%20HashiCorp%20C%26D/SCO.pdf" target="_blank" rel="noopener noreferrer">PDF</a>] <strong>⇐ For the detailed code analysis, see here.</strong></li>
</ul>
<p><em>To prevent further harassment of individual people, we have redacted any personal information from these documents.</em></p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="conclusion">Conclusion<a href="https://opentofu.org/blog/our-response-to-hashicorps-cease-and-desist#conclusion" class="hash-link" aria-label="Direct link to Conclusion" title="Direct link to Conclusion">​</a></h2>
<p>Despite these events, we have managed to carry out significant development on OpenTofu 1.7, including state encryption, “for_each” implementation for “import” blocks, as well as the all-new <strong>provider-defined functions</strong> supported by the recently released provider plugin protocol.</p>
<p>On that note, we will be releasing a new pre-release version next week, and we are eager to gather feedback from the community.</p>
<p>— The OpenTofu Team</p>
<hr>
<small><p><em>The image in this blog post contains code licensed under the BUSL-1.1 by HashiCorp. However, for the purposes of this post we are making non-commercial, transformative fair use under <a href="https://www.govinfo.gov/content/pkg/USCODE-2022-title17/html/USCODE-2022-title17-chap1-sec107.htm" target="_blank" rel="noopener noreferrer">17 U.S. Code § 107</a>. <br> You can read more about fair use on the <a href="https://www.copyright.gov/fair-use/" target="_blank" rel="noopener noreferrer">website of the US Copyright Office</a>.</em></p></small>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Help us test OpenTofu 1.7.0-alpha1]]></title>
            <link>https://opentofu.org/blog/help-us-test-opentofu-1-7-0-alpha1</link>
            <guid>https://opentofu.org/blog/help-us-test-opentofu-1-7-0-alpha1</guid>
            <pubDate>Mon, 18 Mar 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Hey there, OpenTofu community! Over the last few months we've been hard at work to bring new features, such as the state encryption and the removed block, as well as compatibility improvements to you. A few days ago we released the first preview version of these improvements as OpenTofu 1.7.0-alpha1.]]></description>
            <content:encoded><![CDATA[<p>Hey there, OpenTofu community! Over the last few months we've been hard at work to bring new features, such as the <strong>state encryption</strong> and the <strong>removed block</strong>, as well as compatibility improvements to you. A few days ago we released the first preview version of these improvements as <a href="https://github.com/opentofu/opentofu/releases/tag/v1.7.0-alpha1" target="_blank" rel="noopener noreferrer">OpenTofu 1.7.0-alpha1</a>.</p>
<p>We have done everything we could to make sure that the new alpha release doesn't break anything, and we need your help to get this release tested. If you have a <strong>non-production</strong> setup that you would be willing to test any of the new features on, please give it a try and give us <a href="https://github.com/opentofu/opentofu/issues/new/choose" target="_blank" rel="noopener noreferrer">feedback using a GitHub issue</a>, even if it's just telling us that everything went well.</p>
<p>This blog post will go over how to download the new preview release and detail how each of the new features works.</p>
<div class="flex flex-col py-2 px-3 not-prose border gap-1 [&amp;+&amp;]:mt-3 [&amp;_a:hover]:text-gray-900 dark:[&amp;_a:hover]:text-gray-50 [&amp;_a>code]:font-bold [&amp;_code]:text-base [&amp;_code]:px-1.5 [&amp;_a]:underline [&amp;_p]:mb-2 bg-yellow-100 border-yellow-500 text-yellow-800 dark:bg-yellow-950 dark:border-yellow-700 dark:text-yellow-100" role="alert"><div class="flex gap-3 font-bold"><span class="flex w-4 fill-current [&amp;>svg]:w-full" aria-hidden="true"><svg viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"></path></svg></span>Warning</div><div class="leading-relaxed"><p>Do not test this release on a production project! It is not a stable release!</p></div></div>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="downloading-the-alpha-release">Downloading the alpha release<a href="https://opentofu.org/blog/help-us-test-opentofu-1-7-0-alpha1#downloading-the-alpha-release" class="hash-link" aria-label="Direct link to Downloading the alpha release" title="Direct link to Downloading the alpha release">​</a></h2>
<p>The alpha release is available exclusively from the <a href="https://github.com/opentofu/opentofu/releases/tag/v1.7.0-alpha1" target="_blank" rel="noopener noreferrer">GitHub Releases page</a>. Please select the appropriate file for your platform. Here are some quick links:</p>
<table><thead><tr><th>Platform/Device</th><th>Download link</th></tr></thead><tbody><tr><td><strong>Desktop Windows computer</strong><br>(64-bit)</td><td><a href="https://github.com/opentofu/opentofu/releases/download/v1.7.0-alpha1/tofu_1.7.0-alpha1_windows_amd64.zip" target="_blank" rel="noopener noreferrer">tofu_1.7.0-alpha1_windows_amd64.zip</a></td></tr><tr><td><strong>MacOS</strong><br>(Macbook M1 or higher; ARM64)</td><td><a href="https://github.com/opentofu/opentofu/releases/download/v1.7.0-alpha1/tofu_1.7.0-alpha1_darwin_arm64.tar.gz" target="_blank" rel="noopener noreferrer">tofu_1.7.0-alpha1_darwin_arm64.tar.gz</a></td></tr><tr><td><strong>MacOS</strong><br>(Macbook pre-M1 or lower; AMD64)</td><td><a href="https://github.com/opentofu/opentofu/releases/download/v1.7.0-alpha1/tofu_1.7.0-alpha1_darwin_amd64.tar.gz" target="_blank" rel="noopener noreferrer">tofu_1.7.0-alpha1_darwin_amd64.tar.gz</a></td></tr><tr><td><strong>Intel/AMD Linux computer or server</strong><br>(AMD64)</td><td><a href="https://github.com/opentofu/opentofu/releases/download/v1.7.0-alpha1/tofu_1.7.0-alpha1_linux_amd64.tar.gz" target="_blank" rel="noopener noreferrer">tofu_1.7.0-alpha1_linux_amd64.tar.gz</a></td></tr><tr><td><strong>ARM-based Linux computer<br>or<br>Raspberry Pi 3 or higher</strong><br>(ARM64)</td><td><a href="https://github.com/opentofu/opentofu/releases/download/v1.7.0-alpha1/tofu_1.7.0-alpha1_linux_arm64.tar.gz" target="_blank" rel="noopener noreferrer">tofu_1.7.0-alpha1_linux_arm64.tar.gz</a></td></tr></tbody></table>
<p>For the releases above, please unpack the archive and you should find the <code>tofu</code> binary inside. You can also use the <a href="https://opentofu.org/docs/intro/install/standalone/" target="_blank" rel="noopener noreferrer">standalone installer</a> to download the release with signature verification.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="state-encryption">State encryption<a href="https://opentofu.org/blog/help-us-test-opentofu-1-7-0-alpha1#state-encryption" class="hash-link" aria-label="Direct link to State encryption" title="Direct link to State encryption">​</a></h2>
<p>State encryption is one of the flagship features of this release. We have prepared a <a href="https://opentofu.org/docs/language/state/encryption/">full documentation</a> for this feature.</p>
<p>To test this feature, please make a backup of your state file and then add the following configuration:</p>
<div class="language-hcl codeBlockContainer_APcc theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_m3Ux"><figure><figcaption class="sr-only">Code Block</figcaption><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div><pre tabindex="0" class="prism-code language-hcl codeBlock_qGQc thin-scrollbar" style="color:#F8F8F2;background-color:#282A36" role="code" aria-label="Code Block"><code class="codeBlockLines_p187"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">terraform</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">encryption</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    key_provider </span><span class="token string" style="color:rgb(255, 121, 198)">"pbkdf2"</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"my_passphrase"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token property">passphrase</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">""</span><span class="token plain"> </span><span class="token comment" style="color:rgb(98, 114, 164)"># Enter a passphrase here</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    method </span><span class="token string" style="color:rgb(255, 121, 198)">"aes_gcm"</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"my_method"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token property">keys</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> key_provider.pbkdf2.my_passphrase</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">state</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token property">method</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> method.aes_gcm.my_method</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      fallback</span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"> </span><span class="token comment" style="color:rgb(98, 114, 164)"># Remove after the migration is complete.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre></figure></div></div>
<p>You can migrate from an encrypted state file to an unencrypted one like this:</p>
<div class="language-hcl codeBlockContainer_APcc theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_m3Ux"><figure><figcaption class="sr-only">Code Block</figcaption><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div><pre tabindex="0" class="prism-code language-hcl codeBlock_qGQc thin-scrollbar" style="color:#F8F8F2;background-color:#282A36" role="code" aria-label="Code Block"><code class="codeBlockLines_p187"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">terraform</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">encryption</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    key_provider </span><span class="token string" style="color:rgb(255, 121, 198)">"pbkdf2"</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"my_passphrase"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token property">passphrase</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">""</span><span class="token plain"> </span><span class="token comment" style="color:rgb(98, 114, 164)"># Enter a passphrase here</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    method </span><span class="token string" style="color:rgb(255, 121, 198)">"aes_gcm"</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"my_method"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token property">keys</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> key_provider.pbkdf2.my_passphrase</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">state</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token comment" style="color:rgb(98, 114, 164)"># Leave this block empty apart from the fallback block.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      fallback</span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token property">method</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> method.aes_gcm.my_method</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre></figure></div></div>
<p>If you have access to an AWS account, you can also test the <a href="https://opentofu.org/docs/language/state/encryption/#aws-kms">AWS Key-Management Service</a> key provider. (Please note the <a href="https://aws.amazon.com/kms/pricing/" target="_blank" rel="noopener noreferrer">AWS KMS pricing</a>.)</p>
<div class="flex flex-col py-2 px-3 not-prose border gap-1 [&amp;+&amp;]:mt-3 [&amp;_a:hover]:text-gray-900 dark:[&amp;_a:hover]:text-gray-50 [&amp;_a>code]:font-bold [&amp;_code]:text-base [&amp;_code]:px-1.5 [&amp;_a]:underline [&amp;_p]:mb-2 bg-sky-100 border-sky-300 text-sky-800 dark:bg-sky-950 dark:border-sky-700 dark:text-sky-100" role="alert"><div class="flex gap-3 font-bold"><span class="flex w-4 fill-current [&amp;>svg]:w-full" aria-hidden="true"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>Note</div><div class="leading-relaxed"><p>The OpenTofu core developers would like to thank Stephan Bartels (Interhyp) and Alex Scheel for their extensive work on this feature.</p></div></div>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="removed-block">Removed block<a href="https://opentofu.org/blog/help-us-test-opentofu-1-7-0-alpha1#removed-block" class="hash-link" aria-label="Direct link to Removed block" title="Direct link to Removed block">​</a></h2>
<p>The removed block lets you remove a resource from the state file but keep it on the infrastructure. We have prepared a <a href="https://opentofu.org/docs/language/resources/syntax/#removing-resources">full documentation</a> for this feature. You can test it by creating a resource first:</p>
<div class="language-hcl codeBlockContainer_APcc theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_m3Ux"><figure><figcaption class="sr-only">Code Block</figcaption><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div><pre tabindex="0" class="prism-code language-hcl codeBlock_qGQc thin-scrollbar" style="color:#F8F8F2;background-color:#282A36" role="code" aria-label="Code Block"><code class="codeBlockLines_p187"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">resource </span><span class="token keyword type variable" style="color:rgb(189, 147, 249);font-style:italic">"local_file"</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"test"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">content</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"Hello world!"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">filename</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"test.txt"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre></figure></div></div>
<p>After applying, you can replace the resource with a removed block:</p>
<div class="language-hcl codeBlockContainer_APcc theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_m3Ux"><figure><figcaption class="sr-only">Code Block</figcaption><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div><pre tabindex="0" class="prism-code language-hcl codeBlock_qGQc thin-scrollbar" style="color:#F8F8F2;background-color:#282A36" role="code" aria-label="Code Block"><code class="codeBlockLines_p187"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">removed</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">from</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> local_file.test</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre></figure></div></div>
<p>After the next apply, you will see that the local_file.test resource no longer exists in your state file, but the <code>test.txt</code> file should still exist on your disk. You can now remove the <code>removed</code> block safely.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="built-in-function-changes">Built-in function changes<a href="https://opentofu.org/blog/help-us-test-opentofu-1-7-0-alpha1#built-in-function-changes" class="hash-link" aria-label="Direct link to Built-in function changes" title="Direct link to Built-in function changes">​</a></h2>
<p>This release also contains several new functions and changes to existing functions:</p>
<ul>
<li>New function: <a href="https://opentofu.org/docs/language/functions/templatestring/">templatestring</a></li>
<li>New function: <a href="https://opentofu.org/docs/language/functions/base64gunzip/">base64gunzip</a></li>
<li>New function: <a href="https://opentofu.org/docs/language/functions/cidrcontains/">cidrcontains</a></li>
<li>New function: <a href="https://opentofu.org/docs/language/functions/urldecode/">urldecode</a></li>
<li>New function: <a href="https://opentofu.org/docs/language/functions/issensitive/">issensitive</a></li>
<li><a href="https://opentofu.org/docs/language/functions/nonsensitive/">nonsensitive</a> no longer returns an error when the applied values are not sensitive.</li>
<li><a href="https://opentofu.org/docs/language/functions/templatefile/">templatefile</a> now supports recursion up to a depth of 1024.</li>
</ul>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="cli-changes">CLI changes<a href="https://opentofu.org/blog/help-us-test-opentofu-1-7-0-alpha1#cli-changes" class="hash-link" aria-label="Direct link to CLI changes" title="Direct link to CLI changes">​</a></h2>
<p>There are also several changes to the CLI:</p>
<ul>
<li><code>tofu plan</code> now has a <code>-concise</code> flag to shorten the plan output.</li>
<li><code>tofu console</code> now works on Solaris and AIX.</li>
<li>The CLI now supports the XDG directory specification.</li>
<li>Aliases for <code>state list</code> → <code>state ls</code>, <code>state mv</code> → <code>state move</code>, <code>state rm</code> → <code>state remove</code>.</li>
</ul>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="providing-feedback">Providing feedback<a href="https://opentofu.org/blog/help-us-test-opentofu-1-7-0-alpha1#providing-feedback" class="hash-link" aria-label="Direct link to Providing feedback" title="Direct link to Providing feedback">​</a></h2>
<p>Thank you for taking the time to test this preview release. If you have any feedback, please use <a href="https://github.com/opentofu/opentofu/issues/new/choose" target="_blank" rel="noopener noreferrer">a GitHub issue</a> or chat with us on the <a href="https://opentofu.org/slack/" target="_blank" rel="noopener noreferrer">OpenTofu Slack</a>.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[OpenTofu is going GA]]></title>
            <link>https://opentofu.org/blog/opentofu-is-going-ga</link>
            <guid>https://opentofu.org/blog/opentofu-is-going-ga</guid>
            <pubDate>Wed, 10 Jan 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Today is a big day for OpenTofu! After four months of work, we're releasing the first stable release of OpenTofu, a community-driven open source fork of Terraform. OpenTofu, a Linux Foundation project, is now production-ready. It’s a drop-in replacement for Terraform, and you can easily migrate to it by following our migration guide.]]></description>
            <content:encoded><![CDATA[<p>Today is a big day for OpenTofu! After four months of work, we're releasing the <a href="https://github.com/opentofu/opentofu/releases/tag/v1.6.0" target="_blank" rel="noopener noreferrer"><strong>first stable release of OpenTofu</strong></a>, a community-driven open source fork of Terraform. OpenTofu, a Linux Foundation project, is now production-ready. It’s a drop-in replacement for Terraform, and you can easily migrate to it by following our <a href="https://opentofu.org/docs/intro/migration" target="_blank" rel="noopener noreferrer">migration guide</a>.</p>
<p>Roni Frantchi wrote a <a href="https://opentofu.org/blog/opentofu-release-candidate-is-out" target="_blank" rel="noopener noreferrer">great article</a> prior to the holidays, describing our road so far and up to the release candidate. It’s an excellent resource to learn more about how we got to where we are now.</p>
<p>I’ll be focusing on the now, and what we are up to in the near future.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="new-features">New Features<a href="https://opentofu.org/blog/opentofu-is-going-ga#new-features" class="hash-link" aria-label="Direct link to New Features" title="Direct link to New Features">​</a></h2>
<p>Starting with the release itself, OpenTofu 1.6.0 comes with a bunch of new stuff:</p>
<ul>
<li>The testing feature lets you test your OpenTofu configurations and lets module authors test those modules. It’s a great stability improvement and is now fully integrated with the core of OpenTofu.</li>
<li>The S3 state backend was updated and includes many new authentication methods. Crucially, it still works with S3-compatible object storage.</li>
<li>We have a new provider and module registry, which follows a Homebrew-like architecture and is fully based on a git repository. Hosted on CloudFlare R2, it’s snappy and highly-available. Publishing a new provider or module is now just a pull request away!</li>
</ul>
<p>And many many more! Minor improvements, bug fixes, performance improvements, the changelog is huge! Just <a href="https://github.com/opentofu/opentofu/blob/v1.6/CHANGELOG.md" target="_blank" rel="noopener noreferrer">check it out</a>, if you want all the details!</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="the-value-of-open-source">The Value of Open Source<a href="https://opentofu.org/blog/opentofu-is-going-ga#the-value-of-open-source" class="hash-link" aria-label="Direct link to The Value of Open Source" title="Direct link to The Value of Open Source">​</a></h2>
<p>OpenTofu would be far from where it is without its active community support. The <a href="https://opentofu.org/slack" target="_blank" rel="noopener noreferrer">OpenTofu Slack community</a> is growing and thriving. We’ve had almost 60 contributors help make OpenTofu great over the past few months.</p>
<p>Open-source is all about collaboration without borders, across the community, to the benefit of all.</p>
<p>Just to name an example, an <a href="https://github.com/opentofu/opentofu/issues/874" target="_blank" rel="noopener noreferrer">RFC for client-side state encryption</a>, a headline feature we wanted to have in OpenTofu, has been submitted by a community member - the same one who was trying to bring it to Terraform for years. Over the span of <strong>multiple months</strong> they worked to polish the PoC and RFC, involving many community members in the discussions. This RFC has recently been accepted and we’re collaborating with the RFC author to get it into OpenTofu 1.7. Thank you!</p>
<p>When we were working on the registry, we had multiple RFCs submitted. We consulted numerous people all over the industry, including authors of previous similar registries like Homebrew, so that we could get the registry right on the first attempt. So far it has indeed been a success - it’s fast to <code>tofu init</code>, community members have already successfully submitted providers, and the whole thing is very cheap to run.</p>
<p>As an open-source project, OpenTofu also benefits from sponsorships from many companies and projects. Other than the companies who started the initiative and are supporting OpenTofu with dedicated full-time engineers, we also had Cloudflare support us with hosting the registry, and BuildKite supported us with hosting release artifacts.</p>
<p>This, and all the other discussions, issues, proposals, contributions - you name it - are the value of open-source, and what we believe will set OpenTofu apart long-term.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="whats-next">What’s Next?<a href="https://opentofu.org/blog/opentofu-is-going-ga#whats-next" class="hash-link" aria-label="Direct link to What’s Next?" title="Direct link to What’s Next?">​</a></h2>
<p>It took us a while to come out with this initial release. There has been a lot of one-time work that needed to be done to get this project set up for success. But that work is now done, and we’re ready to dive right into new development, with big new features ahead!</p>
<p>First, and we know that this is important to many, we’re aiming to maintain a reasonable amount of compatibility with Terraform where it makes sense. We’re not going to be pushing for big DSL changes, we’re not going to be pushing for provider protocol changes, nothing of the sort. We’ll keep the migration path both ways easy for the foreseeable future.</p>
<p><strong>The biggest change coming soon</strong>, slated for 1.7, is the client-side state encryption. Asked for by many and for a long time now, it will let you encrypt both your state files and plan files end to end. This is valuable to projects working in a regulated environment, and ones going for maximum security. You can find the tracking issue <a href="https://github.com/opentofu/opentofu/issues/1030" target="_blank" rel="noopener noreferrer">here</a>.</p>
<p>Initially, we’ll add support for user-provided keys and a couple of widely-used key management services. Long-term, depending on the usage we see and how the community responds, we might be introducing a plugin system so you can bring arbitrary key management services to it.</p>
<p><a href="https://github.com/opentofu/opentofu/issues/874" target="_blank" rel="noopener noreferrer"><img src="https://opentofu.org/img/blog/opentofu-is-going-ga-client-side-state-encryption.png" alt="A screenshot of the client-side state encryption RFC GitHub issue" width="50%"></a></p>
<p><strong>Parameterizable backends, providers, and modules</strong> have been a very common community request, e.g. parameterizing module versions using variables, maybe even instantiating providers using for_each parameters on a static list of values. This is something we’re looking into and hope to introduce an answer for eventually.</p>
<p><a href="https://github.com/opentofu/opentofu/issues/1042" target="_blank" rel="noopener noreferrer"><img src="https://opentofu.org/img/blog/opentofu-is-going-ga-eval-constants.png" alt="A screenshot of the const evaluation RFC GitHub issue" width="100%"></a></p>
<p>Other than that, we’ve seen many requests for <strong>adding new state backends</strong> - and that makes sense. After all, OpenTofu is really about the ecosystem it integrates with. However, instead of bringing it all to the core of OpenTofu, we’re looking into introducing a plugin system to state backends, similar to providers. <strong>Third-party extensibility is something we see as a selling feature of OpenTofu</strong>, and we want to continue improving on that.</p>
<p><a href="https://github.com/opentofu/opentofu/issues/382" target="_blank" rel="noopener noreferrer"><img src="https://opentofu.org/img/blog/opentofu-is-going-ga-backends-as-plugins.png" alt="A screenshot of the state backend plugins RFC GitHub issue" width="45%"></a></p>
<p>Those are big improvements, but there are also numerous smaller improvements we’ll be introducing, many of them being suggestions or even full-blown contributions from the community. If there’s something you’re missing in OpenTofu, make sure to <a href="https://github.com/opentofu/opentofu/issues/new/choose" target="_blank" rel="noopener noreferrer">submit an issue</a>, we’d love to hear about it!</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="take-it-for-a-spin">Take it for a spin!<a href="https://opentofu.org/blog/opentofu-is-going-ga#take-it-for-a-spin" class="hash-link" aria-label="Direct link to Take it for a spin!" title="Direct link to Take it for a spin!">​</a></h2>
<p>Most crucially, with today’s release, OpenTofu is ready for prime time. In other words, it’s time to install it, and start porting your stuff over!</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[OpenTofu Release Candidate Is Out, GA Set for Jan 10th]]></title>
            <link>https://opentofu.org/blog/opentofu-release-candidate-is-out</link>
            <guid>https://opentofu.org/blog/opentofu-release-candidate-is-out</guid>
            <pubDate>Tue, 19 Dec 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[OpenTofu v1.6.0-rc1, the final stage before the first stable release, is out today. It follows the quick succession of its alpha and beta versions, on the road to an expected General Availability release on January 10, 2024, right after the holidays.]]></description>
            <content:encoded><![CDATA[<p><a href="https://github.com/opentofu/opentofu/releases/tag/v1.6.0-rc1" target="_blank" rel="noopener noreferrer">OpenTofu v1.6.0-rc1</a>, the final stage before the first stable release, is out today. It follows the quick succession of its <a href="https://github.com/opentofu/opentofu/releases/tag/v1.6.0-alpha1" target="_blank" rel="noopener noreferrer">alpha</a> and <a href="https://github.com/opentofu/opentofu/releases/tag/v1.6.0-beta1" target="_blank" rel="noopener noreferrer">beta</a> versions, on the road to an expected General Availability release on January 10, 2024, right after the holidays.</p>
<p>This release includes bug fixes, stability improvements, and updates to documentation. Importantly, this version highlights the stability of our new <a href="https://github.com/opentofu/opentofu/issues/741" target="_blank" rel="noopener noreferrer">public registry</a>, which debuted with the v1.6.0-beta1 release three weeks ago, and has been extensively tested by us and the early adopters from the OpenTofu community.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="from-idea-to-release-candidate-in-4-months">From Idea to Release Candidate in 4 Months<a href="https://opentofu.org/blog/opentofu-release-candidate-is-out#from-idea-to-release-candidate-in-4-months" class="hash-link" aria-label="Direct link to From Idea to Release Candidate in 4 Months" title="Direct link to From Idea to Release Candidate in 4 Months">​</a></h2>
<p>The OpenTofu journey has been a whirlwind, spanning from a proposition to a release candidate in just four months.</p>
<p>This is a major milestone for us, but also a bittersweet moment. Looking back on the beginning of our journey, there was hope that HashiCorp <a href="https://opentofu.org/manifesto" target="_blank" rel="noopener noreferrer">would hear our appeal</a>, reverse its decision and restore balance to the ecosystem.</p>
<p>Yet, here we are … and everything that transpired after those initial weeks of surprise, hope, and disappointment can only be characterized as a case study of collaboration. Peers, community, and competitors all united to work together to preserve an open-source option for Infrastructure-as-Code.</p>
<p>To recap, here are the major milestones so far:</p>
<p><img loading="lazy" alt="An animated graphic visualizing the history of OpenTofu. August 10, 2023: Terraform shifts to Business Source License. August 15: OpenTF manifesto goes live. August 25: OpenTF is announced. August 31: Manifesto surges to 30k GitHub stars. September 5: OpenTF repo goes public. September 20: OpenTF joins the Linux Foundation as OpenTofu. October 4: Alpha released. November 29: Beta released. December 20: Stable release candidate. January 10, 2024: General availability." src="https://opentofu.org/assets/images/opentofu-release-candidate-is-out-history-05af1566e1c9bad743fa7d83d11c3dc4.svg" width="770" height="545" class="img_ev3q"></p>
<p>As of December 18th, OpenTofu had surpassed <a href="https://tooomm.github.io/github-release-stats/?username=opentofu&amp;repository=opentofu" target="_blank" rel="noopener noreferrer">31,000 downloads</a>, had 60 committers, and had seen over 1,000 pull requests and issues. The project’s main repository has also amassed over 16,450 GitHub stars on top of the 36,200+ GitHub stars for the <a href="https://github.com/opentofu/manifesto" target="_blank" rel="noopener noreferrer">manifesto</a>.</p>
<p>Now, with that out of the way, let’s talk shop.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="the-registry-challenge">The Registry Challenge<a href="https://opentofu.org/blog/opentofu-release-candidate-is-out#the-registry-challenge" class="hash-link" aria-label="Direct link to The Registry Challenge" title="Direct link to The Registry Challenge">​</a></h2>
<p>From the moment the <a href="https://opentofu.org/blog/the-opentofu-fork-is-now-available/" target="_blank" rel="noopener noreferrer">OpenTF fork was announced</a>, it was evident that a new public registry would be needed—an open-source substitute for the Terraform one, which is no longer accessible for non-Terraform projects following the <a href="https://www.techtarget.com/searchitoperations/news/366555192/Terraform-Registry-TOS-change-stokes-open-source-ire" target="_blank" rel="noopener noreferrer">TOS changes</a>.</p>
<p>Similar to its predecessor in function, this new registry would have to be a highly available package resolution service for all providers and modules used by OpenTofu. Additionally, it had to meet other specific criteria, including:</p>
<ul>
<li>The registry had to be as self-sufficient as possible and require as little maintenance as possible.</li>
<li>Anticipating increasing demand, it needed to be built for high availability and perform well at scale.</li>
<li>It should smoothly transition from HashiCorp's registry, following the 'drop-in replacement' approach.</li>
<li>Whatever we went with, it had to be open-source.</li>
</ul>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="brewing-together">Brewing Together<a href="https://opentofu.org/blog/opentofu-release-candidate-is-out#brewing-together" class="hash-link" aria-label="Direct link to Brewing Together" title="Direct link to Brewing Together">​</a></h2>
<p><a href="https://brew.sh/" target="_blank" rel="noopener noreferrer">Homebrew</a> is the de facto standard package manager on macOS – just as <a href="https://docs.alpinelinux.org/user-handbook/0.1a/Working/apk.html" target="_blank" rel="noopener noreferrer">APK</a> or <a href="https://en.wikipedia.org/wiki/RPM_Package_Manager" target="_blank" rel="noopener noreferrer">RPM</a> is to Linux or <a href="https://chocolatey.org/" target="_blank" rel="noopener noreferrer">Chocolatey/Winget</a> is to Windows. Its simple nature, open-source package database at its core, and efficiency for packaging applications inspired something similar that would be ideal for our needs, while its popularity served as evidence of its scalability.</p>
<p>As we were discussing this, Homebrew lead <a href="https://github.com/MikeMcQuaid" target="_blank" rel="noopener noreferrer">Mike McQuaid</a>, who has been working on that project for more than 14 years, took notice of our conversation and joined the fray, contributing helpful insights about the repository structure:</p>
<p><a href="https://github.com/opentofu/opentofu/issues/741#issuecomment-1777544250" target="_blank" rel="noopener noreferrer"><img loading="lazy" alt="A screenshot of Mike McQuaid’s comments, contributing to the discussion about using Homebrew as a model for OpenTofu’s public registry." src="https://opentofu.org/assets/images/opentofu-release-candidate-is-out-mike-mcquaid-26b95e0f0282ff8820a342dce7e008fd.png" width="1840" height="1236" class="img_ev3q"></a></p>
<p>For me, this experience highlighted the importance of the Open Source concept and reminded me that without its inherently collaborative nature, engagements like that would be few and far between.</p>
<p>This instinctive and uninhibited camaraderie is what Open Source is all about.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="implementation">Implementation<a href="https://opentofu.org/blog/opentofu-release-candidate-is-out#implementation" class="hash-link" aria-label="Direct link to Implementation" title="Direct link to Implementation">​</a></h2>
<p>Amongst other things, Mike’s advice for us was to fragment the repo, to improve performance:</p>
<blockquote>
<p>“We went through a ‘sharding’ process recently so that we have formulae/casks in our largest repositories split into subdirectories…The ‘git’ performance is dramatically better in this format.”</p>
</blockquote>
<p>Following up on it, we built the registry (<a href="https://registry.opentofu.org/" target="_blank" rel="noopener noreferrer">https://registry.opentofu.org</a>) as a collection of alphabetized subdirectories broken down by namespace. These were hydrated with information from all providers and modules currently available on GitHub, each with its own JSON file with metadata and other specifics.</p>
<p>Importantly, using static files and hosting them on a Cloudflare R2 public bucket also lets us take full advantage of its CDN capabilities, ensuring performance and high availability with over 94% cache hit rates (on that note, huge THANKS to CloudFlare for sponsoring this project!).</p>
<p><img loading="lazy" alt="A screenshot of the Cloudflare dashboard showing 30-day numbers: 7.21k unique visitors, 518k total requests, 92.13% cached, 15 GB total data served and 14 GB data cached." src="https://opentofu.org/assets/images/opentofu-release-candidate-is-out-stats-3bae36b8a9d087d2f8309bc63d427058.png" width="1738" height="1258" class="img_ev3q"></p>
<p>Outside of our own tests, the four most requested files were:</p>
<ul>
<li><code>/.well-known/terraform.json</code></li>
<li><code>/v1/providers/hashicorp/null/versions</code></li>
<li><code>/v1/providers/hashicorp/template/versions</code></li>
<li><code>/v1/providers/hashicorp/aws/versions</code></li>
</ul>
<p>With the registry live, we set up a <a href="https://github.com/opentofu/registry/actions/workflows/bump-versions.yml" target="_blank" rel="noopener noreferrer">GitHub Action</a> to scan for updates to indexed resources. We also introduced an <a href="https://github.com/opentofu/registry/commit/74bfbcf9435433c70c9f923a36aa9d0b16ec2f5a" target="_blank" rel="noopener noreferrer">IssueOps process</a> for adding new providers. With it in place, new submissions would be auto-processed and auto-validated when they go into the registry, with Issues providing context and transparency.</p>
<p><img loading="lazy" alt="A screenshot of the form allowing the addition of a new provider to the OpenTofu registry. The form fields are the provider name and DCO checkbox." src="https://opentofu.org/assets/images/opentofu-release-candidate-is-out-issueops-dbb4e961f51e73f70d1ed1fd9e28b3c2.png" width="904" height="406" class="img_ev3q"></p>
<p>We’re currently exploring a dedicated UI for package and documentation browsing.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="next-stop-jan-10th">Next Stop: Jan 10th<a href="https://opentofu.org/blog/opentofu-release-candidate-is-out#next-stop-jan-10th" class="hash-link" aria-label="Direct link to Next Stop: Jan 10th" title="Direct link to Next Stop: Jan 10th">​</a></h2>
<p>With the holidays in full swing, we decided to roll out a release candidate first and schedule the GA for January 10th. Meanwhile, you can already start testing OpenTofu by simply following the <a href="https://opentofu.org/docs/intro/install/" target="_blank" rel="noopener noreferrer">directions provided here</a>. It is a drop-in replacement so Terraform users will feel right at home, which is the whole idea.</p>
<p>If you are interested in contributing to the project, please check out these <a href="https://github.com/opentofu/opentofu/blob/main/CONTRIBUTING.md" target="_blank" rel="noopener noreferrer">contribution guidelines</a>, and don’t forget to join our <a href="https://opentofu.org/slack/" target="_blank" rel="noopener noreferrer">Slack community</a>.</p>
<p>Happy holidays!</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="ps">P.S.<a href="https://opentofu.org/blog/opentofu-release-candidate-is-out#ps" class="hash-link" aria-label="Direct link to P.S." title="Direct link to P.S.">​</a></h3>
<p>While concluding the work on this post, and the upcoming release, we learned that Mitchell Hashimoto, HashiCorp’s legendary co-founder, <a href="https://www.hashicorp.com/blog/mitchell-reflects-as-he-departs-hashicorp" target="_blank" rel="noopener noreferrer">announced that he will leave the company</a> after 11 years.</p>
<p>Mitchell’s work on projects such as Vagrant, Consul, Vault, and of course Terraform is a source of inspiration for us and many others within the Open Source community.</p>
<p>The entire OpenTofu team extends its heartfelt gratitude to Mitchell for all of his numerous contributions, as we eagerly anticipate learning about the next steps in his already remarkable journey.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[What We Learned While Working on OpenTofu's New Test Feature]]></title>
            <link>https://opentofu.org/blog/what-we-learned-while-working-on-opentofus-new-test-feature</link>
            <guid>https://opentofu.org/blog/what-we-learned-while-working-on-opentofus-new-test-feature</guid>
            <pubDate>Mon, 30 Oct 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[Jumping into a newly forked project can be a difficult task, maybe even frightening! Now, think about jumping into a production-ready project with nine years of legacy code base there. On top of that, you have the task of taking one of the project’s new features from experimental to production-ready.]]></description>
            <content:encoded><![CDATA[<p>Jumping into a newly forked project can be a difficult task, maybe even frightening! Now, think about jumping into a production-ready project with nine years of legacy code base there. On top of that, you have the task of taking one of the project’s new features from experimental to production-ready.</p>
<p>This is our journey with the OpenTofu testing feature.</p>
<p>It’s an interesting introduction to what’s going on behind the scenes at OpenTofu, as we work on our own pipelines. In this case, we are taking raw, experimental code and turning it into something that keeps up with (and possibly outperforms) Terraform v1.6.0 with the drop-in replacement, OpenTofu v1.6.alpha.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="the-feature">The Feature<a href="https://opentofu.org/blog/what-we-learned-while-working-on-opentofus-new-test-feature#the-feature" class="hash-link" aria-label="Direct link to The Feature" title="Direct link to The Feature">​</a></h2>
<p>As part of <a href="https://www.hashicorp.com/blog/hashicorp-adopts-business-source-license" target="_blank" rel="noopener noreferrer">HashiCorp Terraform License</a> changes, we joined the <a href="https://opentofu.org/" target="_blank" rel="noopener noreferrer">OpenTofu initiative</a>. And one of our first tasks is to get OpenTofu up-to-date with the upcoming Terraform 1.6.0, which means getting the testing feature from experimental to production-ready.</p>
<p>At the time of the fork, the testing feature did already exist in the codebase. However, it was still in an experimental state, without any documentation as to how the feature worked, and without much test coverage on the test feature’s own capabilities.</p>
<p>That meant we had to figure out the purpose of what seemed like a WIP testing feature, the pros and cons of this approach, and figure out what was missing to get the feature out of “development hell”</p>
<p>We started out mapping the feature by doing a few different things:</p>
<p>First, we read previous tests to understand how the feature behaves in different scenarios. Next, we thoroughly read through its code to get its ins and outs. Then, we tried it out ourselves to get a feel of using the new testing capability.</p>
<p>These are important, as you don’t want to just jump in and start changing code based on what you think it should look like. You need to understand the architecture and intent of the original implementer, so that the code you write complements it, rather than fighting it.</p>
<p>After this effort, we had a full grasp of the testing feature. It was a framework built to help the users test out their configuration in modules in an end-to-end manner, per module. It makes sure the modules act as expected in common cases, while predictably and safely responding to failure conditions, like a misconfiguration.</p>
<p>The testing feature introduces <code>*.tftest.hcl</code> files. These 1) describe your testing suite and 2) support a specific subset of HCL blocks. The most important block there is the new <code>run</code> block, which constitutes a test run.</p>
<p>When executing <code>tofu test</code>, each <code>run</code> block executes a <code>tofu plan</code> or <code>tofu apply</code> behind the scenes, running your module with the configuration specified for the test, and actually creating resources in your cloud (in the case of <code>apply</code>).</p>
<p>After each run, it performs validations; i.e., it makes sure that 1) all assertions pass, 2) none of the checks are failing, and 3) the <code>plan</code>/<code>apply</code> has finished successfully.</p>
<p>After tofu is done performing all the runs and tests, it attempts to destroy all the resources that were created as part of that <code>tofu test</code> run.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="how-did-we-approach-it">How did we approach it?<a href="https://opentofu.org/blog/what-we-learned-while-working-on-opentofus-new-test-feature#how-did-we-approach-it" class="hash-link" aria-label="Direct link to How did we approach it?" title="Direct link to How did we approach it?">​</a></h2>
<p>Throughout our initial testing and code reading, we made a list of feature behaviors that were not covered with tests in the codebase, and also listed behaviors that we felt had the potential to not work properly.</p>
<p>We mostly relied on the code we read, and our knowledge of legacy Terraform and prior issues. For most of those, we ended up creating <a href="https://github.com/opentofu/opentofu/issues/8#issuecomment-1697596854" target="_blank" rel="noopener noreferrer">pull requests</a>, adding test coverage, or actually fixing bugs.</p>
<p>During our time testing out the feature, we encountered some bugs, and came up with some suggestions to actually improve the feature on top of what was already in the pre-forked codebase. Below are some examples of such bugs that we ended up fixing:</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="bug-1-sensitive-value-in-run-block">Bug 1: Sensitive Value in <code>run</code> block<a href="https://opentofu.org/blog/what-we-learned-while-working-on-opentofus-new-test-feature#bug-1-sensitive-value-in-run-block" class="hash-link" aria-label="Direct link to bug-1-sensitive-value-in-run-block" title="Direct link to bug-1-sensitive-value-in-run-block">​</a></h3>
<p><strong>Bug description</strong>: <code>tofu test</code> crashes when evaluating a sensitive value inside a <code>run</code> block’s assertions.</p>
<p>While playing around with our manual QA scenarios, we found out that running <code>tofu test</code> can, in a certain scenario, crash the program. Specifically, this happens when the configuration includes a <code>run</code> block that has an assertion, and that assertion itself relies on a sensitive value (see the code sample below for main.tftest.hcl).</p>
<p>This isn’t ideal, as a crash in <code>tofu test</code> means that there are now resources in your cloud, for which tofu has no recollection.</p>
<p>You could achieve this crash by running the following configuration:</p>
<p><strong>main.tf:</strong></p>
<div class="language-hcl codeBlockContainer_APcc theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_m3Ux"><figure><figcaption class="sr-only">Code Block</figcaption><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div><pre tabindex="0" class="prism-code language-hcl codeBlock_qGQc thin-scrollbar" style="color:#F8F8F2;background-color:#282A36" role="code" aria-label="Code Block"><code class="codeBlockLines_p187"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">terraform</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">required_providers</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">aws</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token property">source</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"hashicorp/aws"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token property">version</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"5.14.0"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">resource </span><span class="token keyword type variable" style="color:rgb(189, 147, 249);font-style:italic">"aws_secretsmanager_secret"</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"my_secret"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">name</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"my_secret"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">resource </span><span class="token keyword type variable" style="color:rgb(189, 147, 249);font-style:italic">"aws_secretsmanager_secret_version"</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"my_secret_version"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">secret_id</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> aws_secretsmanager_secret.my_secret.id</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">secret_string</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"secret_value"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre></figure></div></div>
<p><strong>main.tftest.hcl:</strong></p>
<div class="language-hcl codeBlockContainer_APcc theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_m3Ux"><figure><figcaption class="sr-only">Code Block</figcaption><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div><pre tabindex="0" class="prism-code language-hcl codeBlock_qGQc thin-scrollbar" style="color:#F8F8F2;background-color:#282A36" role="code" aria-label="Code Block"><code class="codeBlockLines_p187"><span class="token-line" style="color:#F8F8F2"><span class="token plain">run </span><span class="token string" style="color:rgb(255, 121, 198)">"secret_test"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">	</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">assert</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">		</span><span class="token property">condition</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> aws_secretsmanager_secret_version.my_secret_version.secret_string </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"secret_value"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">		</span><span class="token property">error_message</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"bad secret"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">	</span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre></figure></div></div>
<p>Running this configuration with <code>tofu test</code> would actually crash tofu. <code>aws_secretsmanager_secret_version.my_secret_version.secret_string</code> is a sensitive value, and OpenTofu crashed while attempting to evaluate if it was <code>true</code> or <code>false</code>. (You can follow the <a href="https://github.com/opentofu/opentofu/issues/254" target="_blank" rel="noopener noreferrer">thread on GitHub</a>).</p>
<p>Debugging this was a simple manner of running the CLI in a debugger (using the <a href="https://github.com/opentofu/opentofu/blob/main/scripts/debug-opentofu" target="_blank" rel="noopener noreferrer"><code>debug-opentofu</code> script</a> which uses <a href="https://github.com/derekparker/delve" target="_blank" rel="noopener noreferrer">delve</a> for debugging), then following the code and the crash stack trace in order to figure out the source of the issue. Finally, in order to figure out how to fix the issue, we checked how this issue was solved for other types of conditions in the codebase.</p>
<p>The issue stemmed from how the evaluation of values in HCL works, using the <a href="https://pkg.go.dev/github.com/zclconf/go-cty/cty" target="_blank" rel="noopener noreferrer"><code>go-cty</code> library</a>. We won’t get into too much detail about how this evaluation works, but certain values can be “marked” with additional information (such as marking the value as sensitive), and certain actions cannot be made on marked values, causing this panic.</p>
<p>This is intentional, to make sure that the code authors always handle those marks explicitly, instead of relying on some (potentially unwanted) implicit behavior.</p>
<p>In this case, simply unmarking the value prior to checking the boolean value of it was the way to go: <code>resultVal, _ = resultVal.Unmark()</code>. You can see the full code <a href="https://github.com/opentofu/opentofu/pull/263" target="_blank" rel="noopener noreferrer">here</a>.</p>
<p>It’s interesting to note that this issue had already occurred for other such conditions before in the legacy codebase, such as the <a href="https://github.com/hashicorp/terraform/pull/30659" target="_blank" rel="noopener noreferrer"><code>precondition</code> block</a> or for a <a href="https://github.com/hashicorp/terraform/pull/27412" target="_blank" rel="noopener noreferrer"><code>variable</code>’s custom validation rules</a> which have similar behavior.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="bug-2-null-output-reference">Bug 2: Null Output Reference<a href="https://opentofu.org/blog/what-we-learned-while-working-on-opentofus-new-test-feature#bug-2-null-output-reference" class="hash-link" aria-label="Direct link to Bug 2: Null Output Reference" title="Direct link to Bug 2: Null Output Reference">​</a></h3>
<p><strong>Bug description:</strong> <code>tofu test</code> crashes when referencing a <code>null</code> output.</p>
<p>Similarly to the previous bug, we went over our manual QA scenarios and found a scenario where <code>tofu test</code> crashes: When a <code>run</code> condition references an <code>output</code> that has a <code>null</code> value.</p>
<p>You could achieve this crash by running the following configuration (More info <a href="https://github.com/opentofu/opentofu/issues/257" target="_blank" rel="noopener noreferrer">here</a>):</p>
<p><strong>main.tftest.hcl:</strong></p>
<div class="language-hcl codeBlockContainer_APcc theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_m3Ux"><figure><figcaption class="sr-only">Code Block</figcaption><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div><pre tabindex="0" class="prism-code language-hcl codeBlock_qGQc thin-scrollbar" style="color:#F8F8F2;background-color:#282A36" role="code" aria-label="Code Block"><code class="codeBlockLines_p187"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">output</span><span class="token keyword type variable" style="color:rgb(189, 147, 249);font-style:italic"> "my_output" </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">value</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> null</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">run </span><span class="token string" style="color:rgb(255, 121, 198)">"test_run"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">assert</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">condition</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> output.my_output !</span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"something"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token property">error_message</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"good"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre></figure></div></div>
<p>For this one, after some debug work, we found out that this is due to tofu not serializing <code>null</code> outputs as actual outputs. They will not appear as outputs in the state, for example.</p>
<p>However, for the <code>tofu test</code> feature, the assertions had to evaluate those <code>null</code> outputs as having <code>nil</code> value, even though those outputs are not serialized.</p>
<p>The code was as follows:</p>
<div class="language-go codeBlockContainer_APcc theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_m3Ux"><figure><figcaption class="sr-only">Code Block</figcaption><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div><pre tabindex="0" class="prism-code language-go codeBlock_qGQc thin-scrollbar" style="color:#F8F8F2;background-color:#282A36" role="code" aria-label="Code Block"><code class="codeBlockLines_p187"><span class="token-line" style="color:#F8F8F2"><span class="token plain">output </span><span class="token operator">:=</span><span class="token plain"> d</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">Evaluator</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">State</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">OutputValue</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">addr</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">Absolute</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">d</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">ModulePath</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">val </span><span class="token operator">:=</span><span class="token plain"> output</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">Value</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">if</span><span class="token plain"> val </span><span class="token operator">==</span><span class="token plain"> cty</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">NilVal </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">   </span><span class="token comment" style="color:rgb(98, 114, 164)">// Not evaluated yet?</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">   val </span><span class="token operator">=</span><span class="token plain"> cty</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">DynamicVal</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">if</span><span class="token plain"> output</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">Sensitive </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">   val </span><span class="token operator">=</span><span class="token plain"> val</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">Mark</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">marks</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">Sensitive</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">return</span><span class="token plain"> val</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> diags</span><br></span></code></pre></figure></div></div>
<p><code>OutputValue</code> returns <code>nil</code> if no output was found in the address, including the case where the output value was <code>null</code> and therefore was not serialized. So, for the fix, we made sure we return a <code>nil</code> value in this case</p>
<div class="language-go codeBlockContainer_APcc theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_m3Ux"><figure><figcaption class="sr-only">Code Block</figcaption><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div><pre tabindex="0" class="prism-code language-go codeBlock_qGQc thin-scrollbar" style="color:#F8F8F2;background-color:#282A36" role="code" aria-label="Code Block"><code class="codeBlockLines_p187"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">if</span><span class="token plain"> output </span><span class="token operator">==</span><span class="token plain"> </span><span class="token boolean">nil</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">   </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">return</span><span class="token plain"> cty</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">NilVal</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> diags</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre></figure></div></div>
<p>You can see the full code <a href="https://github.com/opentofu/opentofu/pull/267" target="_blank" rel="noopener noreferrer">here</a></p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="other-test-feature-improvements-and-suggestions">Other Test Feature Improvements and Suggestions<a href="https://opentofu.org/blog/what-we-learned-while-working-on-opentofus-new-test-feature#other-test-feature-improvements-and-suggestions" class="hash-link" aria-label="Direct link to Other Test Feature Improvements and Suggestions" title="Direct link to Other Test Feature Improvements and Suggestions">​</a></h3>
<p>Other than those crash fixes, we found it mostly lacking in test coverage (which makes sense, it was still in alpha). For the testing feature, we saw a bunch of scenarios not being covered by any kind of test, and bug fixes were also often missing test coverage.</p>
<p>As a consequence, we’ve added many new test cases to the integration test suite of the testing feature. We felt higher test coverage was quintessential for an open-source project that will be widely used, considering most of its existing codebase is already pretty old. More info on those test cases can be found <a href="https://github.com/opentofu/opentofu/issues/8#issuecomment-1697596854" target="_blank" rel="noopener noreferrer">here</a>.</p>
<p>Also, we’ve started creating issues for suggestions to better stabilize the feature. For example, a failure during the resource cleanup at the end of a <code>tofu test</code> run might fail, causing resources to still exist in your cloud provider. If such a scenario happens, OpenTofu simply lists the names of the resources (in HCL) that have not been deleted properly.</p>
<p>This is probably not good enough, as it could be very hard to find those resources later inside your cloud provider without further information. So, we’ve suggested to at least print out the IDs of those resources, so you can find them more easily in your cloud provider for deletion.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="what-weve-learned">What we’ve learned<a href="https://opentofu.org/blog/what-we-learned-while-working-on-opentofus-new-test-feature#what-weve-learned" class="hash-link" aria-label="Direct link to What we’ve learned" title="Direct link to What we’ve learned">​</a></h2>
<p>This blog walked through what we learned while working on and troubleshooting OpenTofu’s new testing feature. We used code debugging and black box testing to build out the feature’s functionality for the alpha release of OpenTofu.</p>
<p>Through this adventure we’ve had, of learning the code of a mid-development feature and stabilizing it, we’ve gotten more familiar with the codebase and how to debug it. Beyond that, we’ve learned how to completely build the specs of a feature just by reading the code and playing around with it.</p>
<p>It’s also given us a new appreciation for the criticality of testing for open-source projects of this scale (both for documentation, and for making sure a feature works in the long run), and we intend to increase the coverage in the project as we go.</p>
<p>Of course, this is only a small example of the work put in, but it gives you an idea of how we have gone about creating something new for OpenTofu. It will not only maintain parity with past features of open source Terraform, but keep pace with newer features, and even go beyond just serving as a drop-in replacement for Terraform, developing capabilities that it can call its own.</p>
<p>Please check out <a href="https://opentofu.org/" target="_blank" rel="noopener noreferrer">OpenTofu version 1.6.alpha</a>, plus our blog on <a href="https://www.env0.com/blog/opentofu-alpha-launches-try-it-out-in-just-3-clicks" target="_blank" rel="noopener noreferrer">getting OpenTofu started</a> and installed.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[OpenTofu’s New Office Hours]]></title>
            <link>https://opentofu.org/blog/opentofus-new-office-hours</link>
            <guid>https://opentofu.org/blog/opentofus-new-office-hours</guid>
            <pubDate>Tue, 10 Oct 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[OpenTofu is introducing new office hours, open to everyone.]]></description>
            <content:encoded><![CDATA[<p>OpenTofu is introducing new office hours, open to everyone.</p>
<p>These sessions will be held every two weeks over a Zoom. Expect to see developers and regular contributors, with a rotation of different contributors over time. To accommodate everyone, we’ll adjust the timings each session, catering to different time zones.</p>
<p>The next office hour is this <strong>Wednesday at 10am PT</strong>. For all future dates, subscribe to our Google calendar by <a href="https://calendar.google.com/calendar/render?cid=c_3f2dd3c1fe0ef4e93ef3fc456ca2dd219a2e8fd85f6b40750af16c3df370bf93@group.calendar.google.com" target="_blank" rel="noopener noreferrer">clicking this link</a>, or importing the following URL:</p>
<div class="codeBlockContainer_APcc theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_m3Ux"><figure><figcaption class="sr-only">Code Block</figcaption><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div><pre tabindex="0" class="prism-code language-text codeBlock_qGQc thin-scrollbar" style="color:#F8F8F2;background-color:#282A36" role="code" aria-label="Code Block"><code class="codeBlockLines_p187"><span class="token-line" style="color:#F8F8F2"><span class="token plain">c_3f2dd3c1fe0ef4e93ef3fc456ca2dd219a2e8fd85f6b40750af16c3df370bf93@group.calendar.google.com</span><br></span></code></pre></figure></div></div>
<p>... or downloading the attached ICS file:</p>
<!-- -->
<!-- -->
<a href="https://opentofu.org/OpenTofu-Events-Calendar.ics" target="_blank" rel="noopener noreferrer" class="border font-bold h-12 px-6 flex items-center hover:no-underline transition-colors border-gray-200 dark:border-gray-800 text-gray-900 dark:text-gray-50 bg-transparent hover:border-gray-900 dark:hover:border-gray-50 hover:text-gray-900 dark:hover:text-gray-50 aria-selected:border-gray-900 dark:aria-selected:border-gray-50 inline-flex"><p>Download the ICS file</p></a>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Why should I care about OpenTofu?]]></title>
            <link>https://opentofu.org/blog/why-should-i-care-about-opentofu</link>
            <guid>https://opentofu.org/blog/why-should-i-care-about-opentofu</guid>
            <pubDate>Mon, 25 Sep 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[TL;DR having options is good strategy, OpenTofu is your insurance policy and competition makes things great.]]></description>
            <content:encoded><![CDATA[<p>TL;DR having options is good strategy, OpenTofu is your insurance policy and competition makes things great.</p>
<p>Over the last few weeks we received overwhelming support from people all over the world. We have also received criticism for the decisions we've been making. We are very happy to see that people care about the project so deeply that they are willing to share their feelings with us. Please keep doing that!</p>
<p>There's been one particular line of criticism that questions the very premise of our project, and that's the one I'd like to address in this post. It's the line of criticism that goes like this: "The license change does not affect me, so why should I care?".</p>
<p>It is not my intention at this point to convince you that the license change affects you now or will affect you in the future. Maybe it does, maybe it doesn't. Maybe it will, maybe it won't. I don't know, you don't know, and only the future will tell. What I will argue though is that the very existence of this project positively affects you, and that's why you should care.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="si-vis-pacem-para-bellum-or-why-having-options-is-good">Si vis pacem, para bellum or why having options is good<a href="https://opentofu.org/blog/why-should-i-care-about-opentofu#si-vis-pacem-para-bellum-or-why-having-options-is-good" class="hash-link" aria-label="Direct link to Si vis pacem, para bellum or why having options is good" title="Direct link to Si vis pacem, para bellum or why having options is good">​</a></h2>
<p>During my Google days, I worked for a few years as an SRE on tape storage. We operated a significant number of large LTO libraries in many data centers across the world. The best available solution at the time came from Oracle, hands down. Their hardware was great, their software was best in class, their support was always helpful and competent. And yet we would still go to great lengths to support a much, much smaller vendor who offered at least a resemblance of an alternative.</p>
<p>In similar vein we used multiple vendors for each and every hardware and software component we depended on. This was a crucial step in de-risking our supply chain. This was a pragmatic thing to do on many levels - it protected us from technical failures and changing business strategies, gave us a better position in negotiations, and fostered healthy competition among suppliers we depended on.</p>
<p>When the news of the HashiCorp license change broke out, some folks were quick to dismiss Terraform entirely and declare their vocal support for alternatives like Pulumi. And don't get me wrong, Pulumi is a great technology, and I support them with all my heart. In fact, Spacelift was the first vendor to offer an integration with Pulumi, way before they built their Cloud offering.</p>
<p>And while using Pulumi for any new projects is surely a viable alternative, you probably still have thousands upon thousands of lines of Terraform that currently drive the value of your business. Rewriting all of it in Pulumi (or Crossplane, or Winglang - all great products BTW) may be lots of fun for the team but the practical utility of that for your business is limited.</p>
<p>In similar vein, tapes were never the only offline storage option for Google. We could have used optical (like <a href="https://www.pcworld.com/article/443619/facebook-puts-10000-bluray-discs-in-lowpower-storage-system.html" target="_blank" rel="noopener noreferrer">Meta did</a>), or slow spinning drives like what we thought Glacier did. But each of these solutions would require building new capabilities in terms of software, human expertise and processes. All of that was an order of magnitude more expensive and disruptive than just supporting multiple vendors' tape libraries.</p>
<p>OpenTofu promises to be compatible with legacy Terraform, promises better governance and better features than the current commercial offering. But even taking all that aside, you should still support OpenTofu (or some other viable fork if one appears) if you care about your existing investment in the Terraform ecosystem. Because having options is always better than not having options. It's a smart, mature, pragmatic approach.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="competition-is-good">Competition is good<a href="https://opentofu.org/blog/why-should-i-care-about-opentofu#competition-is-good" class="hash-link" aria-label="Direct link to Competition is good" title="Direct link to Competition is good">​</a></h2>
<p>After our acceptance to the Linux Foundation another line of criticism appeared - that somehow OpenTofu is a "fuck capitalism" project. This could not be farther away from the truth. It's a project supported by a number of companies who often compete with HashiCorp for at least part of their business. Most of us took VC funding at one point or another, we all run sales teams, we all generate revenue and yes, we fiercely compete with one another. While obviously challenging for us, this competition is great for our customers because it keeps us on our toes, makes us innovate all the time, grows the market, drives the prices down and the quality up.</p>
<p>Even if you are a happy user of commercial HashiCorp products, you might want to give some credit to folks at competing companies who collectively came up with ideas and improvements in technology, process and pricing. Some of these found their way back to Terraform Cloud / Enterprise and vastly improved the user experience. If you - like me - had a chance to use TFC/TFE before the dawn of TACOs (some time around 2020) then you've probably noticed the amazing progress they've made in terms of functionality, product design and overall stability. And I'm happy to take credit for at least some of that.</p>
<p>The license change that prompted our response now introduced the same element of competition to the CLI layer where HashiCorp previously enjoyed its uncontested status as an obviously privileged (primus inter pares) but otherwise benevolent guardian of the ecosystem.</p>
<p>The outcome of this is easy to predict for anyone familiar with the basics of the market economy. At the very minimum, the incentive to further tighten the license restrictions is greatly diminished or even entirely removed. In a more optimistic scenario, the legacy product will improve, the support quality will improve, there will be quicker bug fixes, quicker PR reviews and new exciting features will flow from both sides. Suddenly the commercial vendor has a new reason to care, and we're hoping to see an increased level of effort, leading to value add for the entire community. And hopefully for HashiCorp, too, uncomfortable as it may be in the beginning. Fast forward a year or two, I will be happy to take credit for at least some of that.</p>
<p>And this is why you <em>should</em> care. Regardless of your position (or the lack thereof) on the BSL drama. Regardless of your sympathy for HashiCorp or Spacelift. Regardless of whether you stay or migrate. And regardless of whether you like tofu or not.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[The OpenTofu fork is now available!]]></title>
            <link>https://opentofu.org/blog/the-opentofu-fork-is-now-available</link>
            <guid>https://opentofu.org/blog/the-opentofu-fork-is-now-available</guid>
            <pubDate>Tue, 05 Sep 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[Four weeks ago, HashiCorp switched Terraform from an open source license to the Business Source License (BSL); three weeks ago, we released the OpenTofu manifesto, asking HashiCorp to switch back to an open source license; two weeks ago, with no response from HashiCorp, we created a private fork of Terraform and said we'd make it public in 1-2 weeks; and today, as promised, we're happy to announce that the OpenTofu repository is now publicly available at github.com/opentofu/opentofu!]]></description>
            <content:encoded><![CDATA[<p>Four weeks ago, HashiCorp switched Terraform from an open source license to the Business Source License (BSL); three weeks ago, we released the <a href="https://opentofu.org/manifesto/">OpenTofu manifesto</a>, asking HashiCorp to switch back to an open source license; two weeks ago, with no response from HashiCorp, we <a href="https://opentofu.org/blog/opentofu-announces-fork-of-terraform/">created a private fork of Terraform</a> and said we'd make it public in 1-2 weeks; and today, as promised, we're happy to announce that <strong>the OpenTofu repository is now publicly available at</strong> <a href="https://github.com/opentofu/opentofu" target="_blank" rel="noopener noreferrer">github.com/opentofu/opentofu</a>!</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="working-in-the-open">Working in the open<a href="https://opentofu.org/blog/the-opentofu-fork-is-now-available#working-in-the-open" class="hash-link" aria-label="Direct link to Working in the open" title="Direct link to Working in the open">​</a></h3>
<p>Our goal with OpenTofu is to create a project that is truly open source, community-driven, and impartial. To that end, going forward, we'll be developing OpenTofu in the open. We had to do some work on the repo and the OpenTofu foundation in private to get everything ready for public consumption, but now that that's done, and the OpenTofu repo is publicly available, you'll be able to see everything we're working on—and start to participate yourself!</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="what-opentofu-currently-does-and-doesnt-support">What OpenTofu currently does and doesn't support<a href="https://opentofu.org/blog/the-opentofu-fork-is-now-available#what-opentofu-currently-does-and-doesnt-support" class="hash-link" aria-label="Direct link to What OpenTofu currently does and doesn't support" title="Direct link to What OpenTofu currently does and doesn't support">​</a></h3>
<p>Currently, OpenTofu supports local testing and development: you can build the code, run the tests, build <code>tofu</code> binaries, and so on. That means you can now start experimenting with OpenTofu and contributing back via Issues, PRs, and RFCs.</p>
<p>However, a few items are not done yet, and as a result, official OpenTofu releases are <em>not</em> yet available. To understand what's left to do before the releases are available, let's take a look at the roadmap.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="an-open-roadmap-the-path-to-stable-opentofu-releases">An open roadmap: the path to stable OpenTofu releases<a href="https://opentofu.org/blog/the-opentofu-fork-is-now-available#an-open-roadmap-the-path-to-stable-opentofu-releases" class="hash-link" aria-label="Direct link to An open roadmap: the path to stable OpenTofu releases" title="Direct link to An open roadmap: the path to stable OpenTofu releases">​</a></h3>
<p>A key part of working in the open is making our roadmap open. So here's a quick snapshot of what we already got done, what's in progress now, and what's coming up in the future, all with the initial goal of getting to the first stable OpenTofu release (for a more detailed and up-to-date look at the roadmap, see the <a href="https://github.com/opentofu/opentofu/milestones" target="_blank" rel="noopener noreferrer">milestones and issues in the OpenTofu repo</a>).</p>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="-what-we-already-got-done">✅ What we already got done<a href="https://opentofu.org/blog/the-opentofu-fork-is-now-available#-what-we-already-got-done" class="hash-link" aria-label="Direct link to ✅ What we already got done" title="Direct link to ✅ What we already got done">​</a></h4>
<ul>
<li><strong>Publish the OpenTofu manifesto</strong>. We published the OpenTofu manifesto at <a href="https://opentofu.org/manifesto/">opentofu.org</a>.</li>
<li><strong>Wait on HashiCorp's response</strong>. We reached out to HashiCorp publicly and privately and requested a response by August 25th.</li>
<li><strong>Start working on the OpenTofu fork</strong>. With no response from HashiCorp, we created the OpenTofu fork, and started working on it in private.</li>
<li><strong>Apply to join the Linux Foundation</strong>. We want OpenTofu to be part of an impartial, community-driven foundation, so we submitted all the paperwork to join the Linux Foundation.</li>
<li><strong>Open up community Slack discussions</strong>. We created the <a href="https://opentofu.org/slack" target="_blank" rel="noopener noreferrer">OpenTofu Community Slack</a> to give the community a way to have discussions, provide feedback, ask questions, etc.</li>
<li><strong>Prepare the OpenTofu repo for collaboration</strong>. Rename everything to OpenTofu; pick steering committee members; define <a href="https://github.com/opentofu/opentofu/blob/main/CONTRIBUTING.md" target="_blank" rel="noopener noreferrer">contribution guidelines</a>; get CI / CD and testing working; etc.</li>
<li><strong>Release the OpenTofu repo</strong>. As per this announcement, we are making the OpenTofu repo public at <a href="https://github.com/opentofu/opentofu" target="_blank" rel="noopener noreferrer">github.com/opentofu/opentofu</a>!</li>
</ul>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="-whats-currently-in-progress">🔄 What's currently in progress<a href="https://opentofu.org/blog/the-opentofu-fork-is-now-available#-whats-currently-in-progress" class="hash-link" aria-label="Direct link to 🔄 What's currently in progress" title="Direct link to 🔄 What's currently in progress">​</a></h4>
<ul>
<li><strong>Create initial OpenTofu Registry</strong>. HashiCorp recently made some (unannounced) <a href="https://github.com/opentofu/roadmap/issues/24#issuecomment-1699535216" target="_blank" rel="noopener noreferrer">changes</a> to the terms of the Terraform Registry, saying it may only be used with Terraform. To unblock the alpha release, we are launching an initial OpenTofu Registry. We'll develop the official OpenTofu Registry solution via an official RFC process later.</li>
<li><strong>Release process</strong>. Put in place a process for creating OpenTofu releases.</li>
<li><strong>Alpha release</strong>. Once the above items are done, we will create the first OpenTofu release. This will be an alpha release, meant for testing by the community.</li>
</ul>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="-whats-coming-soon">⏳ What's coming soon<a href="https://opentofu.org/blog/the-opentofu-fork-is-now-available#-whats-coming-soon" class="hash-link" aria-label="Direct link to ⏳ What's coming soon" title="Direct link to ⏳ What's coming soon">​</a></h4>
<ul>
<li><strong>Create an official OpenTofu Registry via an RFC process</strong>. Go through an RFC process to create the official OpenTofu Registry solution (replacing the initial solution).</li>
<li><strong>Stable release</strong>. Create the first stable OpenTofu release. This is meant for production usage, as a drop in replacement for Terraform, so we'll only do this release after sufficient testing and community feedback.</li>
</ul>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="join-the-opentofu-community">Join the OpenTofu community<a href="https://opentofu.org/blog/the-opentofu-fork-is-now-available#join-the-opentofu-community" class="hash-link" aria-label="Direct link to Join the OpenTofu community" title="Direct link to Join the OpenTofu community">​</a></h3>
<p>The response from the community so far has been incredible. In just a few weeks, more than 130 companies and 680 individuals have pledged support to the <a href="https://opentofu.org/manifesto/">OpenTofu manifesto</a>, and the <a href="https://github.com/opentofu/manifesto" target="_blank" rel="noopener noreferrer">OpenTofu manifesto repo</a> has gotten more than 33,000 stars! By comparison, the Terraform repo took nearly 10 years to reach 38,000 stars:</p>
<p><img loading="lazy" alt="OpenTofu has gotten over 33,000 stars in GitHub in just a few weeks" src="https://opentofu.org/assets/images/star-history-202395-f2b98ff4298df690858907f5c40e36c9.png" width="1832" height="1276" class="img_ev3q"></p>
<p>This sort of growth is unprecedented, and we're humbled by all of your support. As per the roadmap in the previous section, we're working hard on getting OpenTofu to the point where we can start doing official releases.</p>
<p>In the meantime, you can follow our progress at <a href="https://github.com/opentofu/opentofu" target="_blank" rel="noopener noreferrer">github.com/opentofu/opentofu</a>, contribute to the project by following the <a href="https://github.com/opentofu/opentofu/blob/main/CONTRIBUTING.md" target="_blank" rel="noopener noreferrer">contribution guidelines</a>, and provide feedback in the <a href="https://opentofu.org/slack" target="_blank" rel="noopener noreferrer">OpenTofu Community Slack</a>. We are thrilled to be working with the whole community in making OpenTofu a truly open, community-driven project!</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="faq">FAQ<a href="https://opentofu.org/blog/the-opentofu-fork-is-now-available#faq" class="hash-link" aria-label="Direct link to FAQ" title="Direct link to FAQ">​</a></h3>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="where-can-i-find-the-opentofu-repo">Where can I find the OpenTofu repo?<a href="https://opentofu.org/blog/the-opentofu-fork-is-now-available#where-can-i-find-the-opentofu-repo" class="hash-link" aria-label="Direct link to Where can I find the OpenTofu repo?" title="Direct link to Where can I find the OpenTofu repo?">​</a></h4>
<p>The OpenTofu repo is now available at <a href="https://github.com/opentofu/opentofu" target="_blank" rel="noopener noreferrer">github.com/opentofu/opentofu</a>.</p>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="where-can-i-find-opentofu-releases">Where can I find OpenTofu releases?<a href="https://opentofu.org/blog/the-opentofu-fork-is-now-available#where-can-i-find-opentofu-releases" class="hash-link" aria-label="Direct link to Where can I find OpenTofu releases?" title="Direct link to Where can I find OpenTofu releases?">​</a></h4>
<p>Releases are not yet available. See our <a href="https://opentofu.org/blog/the-opentofu-fork-is-now-available#an-open-roadmap-the-path-to-stable-opentofu-releases">open roadmap</a> for the work remaining.</p>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="when-will-a-stable-opentofu-release-be-available">When will a stable OpenTofu release be available?<a href="https://opentofu.org/blog/the-opentofu-fork-is-now-available#when-will-a-stable-opentofu-release-be-available" class="hash-link" aria-label="Direct link to When will a stable OpenTofu release be available?" title="Direct link to When will a stable OpenTofu release be available?">​</a></h4>
<p>See our <a href="https://opentofu.org/blog/the-opentofu-fork-is-now-available#an-open-roadmap-the-path-to-stable-opentofu-releases">open roadmap</a> for the work remaining to get to a stable release. Contributions are very welcome!</p>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="why-is-it-taking-so-long">Why is it taking so long?<a href="https://opentofu.org/blog/the-opentofu-fork-is-now-available#why-is-it-taking-so-long" class="hash-link" aria-label="Direct link to Why is it taking so long?" title="Direct link to Why is it taking so long?">​</a></h4>
<p>It has only been a couple weeks! And there is a lot to do, including technical, legal, process, and other changes. See our <a href="https://opentofu.org/blog/the-opentofu-fork-is-now-available#an-open-roadmap-the-path-to-stable-opentofu-releases">open roadmap</a> for what we've gotten done already, what's currently in progress, and what's coming up next.</p>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="will-i-be-able-to-use-opentofu-as-a-drop-in-replacement-for-legacy-terraform">Will I be able to use OpenTofu as a drop-in replacement for legacy Terraform?<a href="https://opentofu.org/blog/the-opentofu-fork-is-now-available#will-i-be-able-to-use-opentofu-as-a-drop-in-replacement-for-legacy-terraform" class="hash-link" aria-label="Direct link to Will I be able to use OpenTofu as a drop-in replacement for legacy Terraform?" title="Direct link to Will I be able to use OpenTofu as a drop-in replacement for legacy Terraform?">​</a></h4>
<p>Yes.</p>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="will-opentofu-work-with-all-the-providers-and-modules-terraform-works-with">Will OpenTofu work with all the providers and modules Terraform works with?<a href="https://opentofu.org/blog/the-opentofu-fork-is-now-available#will-opentofu-work-with-all-the-providers-and-modules-terraform-works-with" class="hash-link" aria-label="Direct link to Will OpenTofu work with all the providers and modules Terraform works with?" title="Direct link to Will OpenTofu work with all the providers and modules Terraform works with?">​</a></h4>
<p>Yes.</p>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="what-will-be-the-first-release-of-opentofu">What will be the first release of OpenTofu?<a href="https://opentofu.org/blog/the-opentofu-fork-is-now-available#what-will-be-the-first-release-of-opentofu" class="hash-link" aria-label="Direct link to What will be the first release of OpenTofu?" title="Direct link to What will be the first release of OpenTofu?">​</a></h4>
<p>The first release will be 1.6.0-alpha, forked from the most recent commit that was still MPL-licensed.</p>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="how-can-i-contribute-to-opentofu">How can I contribute to OpenTofu?<a href="https://opentofu.org/blog/the-opentofu-fork-is-now-available#how-can-i-contribute-to-opentofu" class="hash-link" aria-label="Direct link to How can I contribute to OpenTofu?" title="Direct link to How can I contribute to OpenTofu?">​</a></h4>
<p>Please see the <a href="https://github.com/opentofu/opentofu/blob/main/CONTRIBUTING.md" target="_blank" rel="noopener noreferrer">contribution guidelines</a>!</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[OpenTofu Announces Fork of Terraform]]></title>
            <link>https://opentofu.org/blog/opentofu-announces-fork-of-terraform</link>
            <guid>https://opentofu.org/blog/opentofu-announces-fork-of-terraform</guid>
            <pubDate>Fri, 25 Aug 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[Two weeks ago, HashiCorp announced they are changing the license to all their core products, including Terraform, to the Business Source License (BSL). In an attempt to keep Terraform open source, we published the OpenTofu manifesto, and the community response was huge! Over 100 companies, 10 projects, and 400 individuals pledged their time and resources to keep Terraform open-source. The GitHub repository for the manifesto already has over 4k stars, and the number is growing quickly!]]></description>
            <content:encoded><![CDATA[<p>Two weeks ago, HashiCorp announced they are changing the license to all their core products, including Terraform, to the Business Source License (BSL). In an attempt to keep Terraform open source, we published the <a href="https://opentofu.org/manifesto/">OpenTofu manifesto</a>, and the community response was huge! Over 100 companies, 10 projects, and 400 individuals pledged their time and resources to keep Terraform open-source. The <a href="https://github.com/opentofu/manifesto" target="_blank" rel="noopener noreferrer">GitHub repository</a> for the manifesto already has over 4k stars, and the number is growing quickly!</p>
<p>The manifesto outlined the intent of the OpenTofu initiative in two steps — the first was to appeal to HashiCorp to return Terraform to the community and revert the license change they were making for this project. The second, in case the license was not reverted, was to fork the Terraform project as OpenTofu.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="the-time-is-now">The time is now!<a href="https://opentofu.org/blog/opentofu-announces-fork-of-terraform#the-time-is-now" class="hash-link" aria-label="Direct link to The time is now!" title="Direct link to The time is now!">​</a></h3>
<p>Since no reversal has been done, and no intent to do one has been communicated, we’re proud to announce that <strong>we have created a fork of Terraform called OpenTofu</strong>. Many engineers across a number of companies, sometimes even competing companies, have been working together over the last week to make this possible. It’s been an incredible experience, really!</p>
<p>As outlined in our manifesto, we are keeping OpenTofu:</p>
<ul>
<li><strong>Truly open source</strong> - under a well-known and widely-accepted license that companies can trust, that won't suddenly change in the future</li>
<li><strong>Community-driven</strong> - so that the community governs the project for the community, where pull requests are regularly reviewed and accepted on their merit, and changes are proposed through a public RFC process</li>
<li><strong>Impartial</strong> - so that valuable features and fixes are accepted based on their value to the community, regardless of their impact on any particular vendor</li>
<li><strong>Layered and modular</strong> - with a programmer-friendly project structure to encourage building on top, enabling a new vibrant ecosystem of tools and integrations</li>
<li><strong>Backwards-compatible</strong> - so that the existing code can drive value for years to come</li>
</ul>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="becoming-part-of-a-foundation">Becoming part of a foundation<a href="https://opentofu.org/blog/opentofu-announces-fork-of-terraform#becoming-part-of-a-foundation" class="hash-link" aria-label="Direct link to Becoming part of a foundation" title="Direct link to Becoming part of a foundation">​</a></h3>
<p><strong>We completed all documents required for OpenTofu to become part of the Linux Foundation</strong> with the end goal of having <strong>OpenTofu as part of the Cloud Native Computing Foundation</strong>. By making a foundation responsible for the project, we will ensure the tool stays truly open-source and vendor-neutral.</p>
<p>If Terraform wasn’t open-source from the beginning, many of the tools that you are using right now for your Terraform workflows simply wouldn’t exist, thus, we believe the future for Terraform is OpenTofu, developed fully in the open.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="roadmap">Roadmap<a href="https://opentofu.org/blog/opentofu-announces-fork-of-terraform#roadmap" class="hash-link" aria-label="Direct link to Roadmap" title="Direct link to Roadmap">​</a></h3>
<p>As previously outlined, we’ve been working on this fork for several days already, with over 10 engineers across multiple companies working on it.</p>
<p><strong>In short, here’s the current status:</strong></p>
<ul>
<li>Almost done with the repository-wide rename to OpenTofu</li>
<li>Selected initial steering committee members</li>
<li>Performed initial adjustments and cleanup of community documents.</li>
<li>Got CI/CD pipelines and multiple testing harnesses of end-to-end and snapshot tests to work and be green, to make sure that we stay backwards-compatible.</li>
</ul>
<p><strong>Expect the repository to be published very soon</strong>, once we’re officially part of a foundation and have some basic community guardrails and processes in place.</p>
<p><strong>You might wonder why we already started work on this project so early?</strong> It’s quite simple, really. If HashiCorp were to reverse their decision, worst case we’d just lose a week of work. But if, and that is what indeed happened, HashiCorp wasn’t to reverse their decision, we didn’t want to lose any time, so that <strong>we could have a working OpenTofu 1.6.0 release ready for you as soon as possible</strong>. And that’s why we started work on this over a week ago.</p>
<p>In the spirit of being as open as possible, <strong>we’ve created a</strong> <a href="https://github.com/opentofu/roadmap/milestones" target="_blank" rel="noopener noreferrer">public repository tracking our progress towards important milestones</a>. You can subscribe to the issues there to be notified as soon as the fork is public. If you have any questions, feel free to create additional issues on that repository - we’ll try to respond as quickly as possible.</p>]]></content:encoded>
        </item>
    </channel>
</rss>