<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[TheOpsDev Engineering Blog]]></title><description><![CDATA[Join me as I learn about platform engineering, and system architecture. This blog shares insights, best practices, and trends to help build scalable and efficient systems.]]></description><link>https://blog.theops.dev</link><image><url>https://cdn.hashnode.com/res/hashnode/image/upload/v1736210267172/13aad556-0ce5-446e-ad22-d0093373e1a8.png</url><title>TheOpsDev Engineering Blog</title><link>https://blog.theops.dev</link></image><generator>RSS for Node</generator><lastBuildDate>Wed, 08 Apr 2026 12:59:56 GMT</lastBuildDate><atom:link href="https://blog.theops.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[How to Use DigitalOcean's Spaces as a Remote State Backend for IaC]]></title><description><![CDATA[I recently started building a remote homelab within Digital Ocean’s cloud space and I wanted to see if I could leverage their “Spaces Object Storage” as a compatible remote backend for OpenTofu. At this point I have been using OpenTofu’s “local” back...]]></description><link>https://blog.theops.dev/how-to-use-digitaloceans-spaces-as-a-remote-state-backend-for-iac</link><guid isPermaLink="true">https://blog.theops.dev/how-to-use-digitaloceans-spaces-as-a-remote-state-backend-for-iac</guid><category><![CDATA[opentofu]]></category><category><![CDATA[S3]]></category><category><![CDATA[remotestate]]></category><dc:creator><![CDATA[Christian Herrera]]></dc:creator><pubDate>Sat, 25 Jan 2025 07:56:32 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1737786580305/2d6c44ad-d2c7-489b-be26-d0828f7cdfc8.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I recently started building a remote homelab within Digital Ocean’s cloud space and I wanted to see if I could leverage their <strong>“</strong><a target="_blank" href="https://www.digitalocean.com/products/spaces"><strong>Spaces Object Storage</strong></a><strong>”</strong> as a compatible remote backend for OpenTofu. At this point I have been using OpenTofu’s <a target="_blank" href="https://opentofu.org/docs/language/settings/backends/local/"><strong>“local”</strong></a> backend setup to manage my state file but this isn’t a sustainable method nor actually used in professional setting. So lets migrate our local state over to a remote object storage.</p>
<h2 id="heading-prerequisites"><strong>Prerequisites:</strong></h2>
<ol>
<li><p>Using <code>=&gt;1.6</code> OpenTofu version</p>
</li>
<li><p>Create your Digital Ocean account and project</p>
</li>
<li><p>Create a Spaces storage bucket (<a target="_blank" href="https://docs.digitalocean.com/products/spaces/how-to/create/">click here for instructions</a>)</p>
</li>
<li><p>Create a Spaces access key (<a target="_blank" href="https://docs.digitalocean.com/products/spaces/how-to/manage-access/#access-keys">click here for instructions</a>)</p>
</li>
</ol>
<h2 id="heading-approach">Approach</h2>
<p>Spaces Object Storage is an S3 compatible object storage service. With this in mind we are going to reuse OpenTofu’s S3 backend support and extend it to a Spaces storage bucket. If you have have completed the required prerequisites, we can proceed forward.</p>
<h2 id="heading-instructions">Instructions</h2>
<h3 id="heading-set-up-required-environment-variables">Set up required Environment Variables</h3>
<p>Using environment variables is the recommended way to provide your Spaces access key. Other methods, such as <code>tofu init -backend-config</code> or hardcoding values, may expose secrets in your <code>.terraform</code> folder and plan files.</p>
<p>OpenTofu’s S3 backend leverages <code>AWS_</code> prefixed environment variables for configuration. We will use these same variables but supply our Spaces access key values in place of AWS values.</p>
<pre><code class="lang-rego">export AWS_ACCESS_KEY_ID=<span class="hljs-string">"&lt;your_access_key&gt;"</span>
export AWS_SECRET_ACCESS_KEY=<span class="hljs-string">"&lt;your_secret_key&gt;"</span>
</code></pre>
<p>Replace the <code>&lt;your_access_key&gt;</code> and <code>&lt;your_secret_key&gt;</code> placeholders with your actual values.</p>
<h3 id="heading-setup-s3-backend-configuration">Setup S3 Backend Configuration</h3>
<p>Here is an example of my remote backend configuration. It uses OpenTofu’s <code>S3</code> backend with DigitalOcean Spaces bucket values.</p>
<pre><code class="lang-rego">terraform <span class="hljs-punctuation">{
</span>  required_version = <span class="hljs-string">"~&gt; 1.9.0"</span>

  backend <span class="hljs-string">"s3"</span> <span class="hljs-punctuation">{
</span>    endpoints = <span class="hljs-punctuation">{
</span>      s3 = <span class="hljs-string">"&lt;spaces_bucket_region&gt;.digitaloceanspaces.com"</span>
    <span class="hljs-punctuation">}
</span>
    bucket = <span class="hljs-string">"&lt;spaces_bucket_name&gt;"</span>
    key    = <span class="hljs-string">"&lt;path/and/state/file/name&gt;"</span>

    <span class="hljs-comment"># Deactivate a few AWS-specific checks</span>
    skip_credentials_validation = <span class="hljs-variable">true</span>
    skip_requesting_account_id  = <span class="hljs-variable">true</span>
    skip_metadata_api_check     = <span class="hljs-variable">true</span>
    skip_region_validation      = <span class="hljs-variable">true</span>
    skip_s3_checksum            = <span class="hljs-variable">true</span>
    region                      = <span class="hljs-string">"us-east-1"</span>
  <span class="hljs-punctuation">}
</span><span class="hljs-punctuation">}</span>
</code></pre>
<p><strong>Values required:</strong></p>
<ol>
<li><p><code>S3</code> : Replace <code>&lt;spaces_bucket_region&gt;</code> with the region of the bucket you created.</p>
</li>
<li><p><code>bucket</code> : Replace <code>&lt;spaces_bucket_name&gt;</code> with the name of your bucket.</p>
</li>
<li><p><code>key</code> : Update <code>&lt;path/and/state/file/name&gt;</code> with path and file name you would like to store your OpenTofu state under. If the path does not exist OpenTofu will create it when your initialize your IaC space.</p>
</li>
</ol>
<h2 id="heading-migrate-or-initialize-your-state">Migrate or Initialize your State</h2>
<p>At this point you should be ready to start using your newly setup remote state in DigitalOcean</p>
<p><strong>Migrate local state to remote</strong></p>
<pre><code class="lang-rego">tofu init -migrate-state
</code></pre>
<p><strong>Initialize empty OpenTofu space</strong></p>
<pre><code class="lang-rego">tofu init
</code></pre>
<h2 id="heading-reference">Reference</h2>
<ul>
<li><a target="_blank" href="https://github.com/opentofu/opentofu/tree/main/internal/backend/remote-state/s3">https://github.com/opentofu/opentofu/tree/main/internal/backend/remote-state/s3</a></li>
</ul>
]]></content:encoded></item><item><title><![CDATA[OpenTofu vs. Terraform]]></title><description><![CDATA[Introduction
In this article, we will be reviewing the key differences between OpenTofu and Terraform, two popular infrastructure-as-code (IaC) tools used for provisioning and managing cloud resources. While both tools share a similar foundation, Ope...]]></description><link>https://blog.theops.dev/opentofu-vs-terraform</link><guid isPermaLink="true">https://blog.theops.dev/opentofu-vs-terraform</guid><category><![CDATA[opentofu]]></category><category><![CDATA[Terraform]]></category><category><![CDATA[#IaC]]></category><category><![CDATA[Cloud Engineering ]]></category><dc:creator><![CDATA[Christian Herrera]]></dc:creator><pubDate>Thu, 16 Jan 2025 05:36:49 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1737006770056/91f4d39b-bc97-4608-8b08-b4e0736177ee.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction">Introduction</h2>
<p>In this article, we will be reviewing the key differences between <a target="_blank" href="https://opentofu.org/"><strong>OpenTofu</strong></a> and <a target="_blank" href="https://www.hashicorp.com/products/terraform"><strong>Terraform</strong></a>, two popular infrastructure-as-code (IaC) tools used for provisioning and managing cloud resources. While both tools share a similar foundation, OpenTofu emerged as a response to HashiCorp’s 2023 licensing changes to Terraform, offering a fully open-source alternative.</p>
<h2 id="heading-why-was-opentofu-created">Why was OpenTofu Created?</h2>
<p>In August 2023, HashiCorp announced that it would change the license of Terraform from the Mozilla Public License (MPL 2.0) to a Business Source License (BSL). The BSL change sparked a backlash from the open-source community and Terraform users.</p>
<p>In response to these concerns, a group of developers, including former contributors to Terraform, decided to fork Terraform and create an open-source version with a completely permissive license. This fork became OpenTofu. More information can be found under <a target="_blank" href="https://opentofu.org/manifesto/">OpenTofu’s Manifesto</a>.</p>
<h2 id="heading-what-are-the-differences">What are the differences?</h2>
<h3 id="heading-compatibility">Compatibility</h3>
<p>As of version 1.6, OpenTofu maintains compatibility with Terraform 1.6, allowing for a straightforward migration process. OpenTofu is committed to continuing to support Terraform 1.x releases. More information can be found <a target="_blank" href="https://opentofu.org/docs/language/v1-compatibility-promises/">here</a>.</p>
<h3 id="heading-development-amp-community">Development &amp; Community</h3>
<ul>
<li><p><strong>Terraform:</strong> Development is primarily driven by HashiCorp, with feature implementation and roadmap decisions made internally. <a target="_blank" href="https://github.com/hashicorp/terraform">https://github.com/hashicorp/terraform</a></p>
</li>
<li><p><strong>OpenTofu:</strong> Emphasizes community involvement, allowing contributors to influence feature development and prioritization. This collaborative approach aims to address user needs more responsively. <a target="_blank" href="https://github.com/opentofu/opentofu">https://github.com/opentofu/opentofu</a></p>
</li>
</ul>
<h3 id="heading-comparison">Comparison</h3>
<p>This table was pulled from <a target="_blank" href="https://spacelift.io/blog/opentofu-vs-terraform">Spacelift.io</a></p>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>Feature</strong></td><td><strong>OpenTofu</strong></td><td><strong>Terraform</strong></td></tr>
</thead>
<tbody>
<tr>
<td>Language</td><td>HCL</td><td>HCL</td></tr>
<tr>
<td>State Management</td><td>✅ Yes</td><td>✅ Yes</td></tr>
<tr>
<td>State Encryption</td><td>✅ Yes</td><td>❌ No</td></tr>
<tr>
<td>Early Variable Evaluation</td><td>✅ Yes</td><td>❌ No</td></tr>
<tr>
<td>Provider Functions</td><td>✅ Yes</td><td>✅ Yes</td></tr>
<tr>
<td>Community Driven</td><td>✅ Yes, there is an <a target="_blank" href="https://github.com/opentofu/opentofu/issues/1496">issue ranking system</a> <a target="_blank" href="https://github.com/opentofu/opentofu/issues/1496">you can influence.</a></td><td>❌ No</td></tr>
</tbody>
</table>
</div><h2 id="heading-examples">Examples</h2>
<h3 id="heading-init">Init</h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1737004829436/ec7b3809-13ad-4156-b9ed-ea2679f9244c.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-plan">Plan</h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1737005187827/c92e2d7e-058d-4099-9c95-41f07b46a80d.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-apply">Apply</h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1737005320764/2721dca6-c0d2-4c2f-9ef1-1c6230724248.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-reference">Reference</h2>
<ul>
<li><p><a target="_blank" href="https://opentofu.org/blog/">https://opentofu.org/blog/</a></p>
</li>
<li><p><a target="_blank" href="https://www.hashicorp.com/blog/products/terraform">https://www.hashicorp.com/blog/products/terraform</a></p>
</li>
<li><p><a target="_blank" href="https://www.hashicorp.com/license-faq">https://www.hashicorp.com/license-faq</a></p>
</li>
<li><p><a target="_blank" href="https://opentofu.org/docs/language/v1-compatibility-promises/">https://opentofu.org/docs/language/v1-compatibility-promises/</a></p>
</li>
</ul>
]]></content:encoded></item></channel></rss>