<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Iain Earl</title>
    <description>The latest articles on DEV Community by Iain Earl (@itmecho).</description>
    <link>https://dev.to/itmecho</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F767023%2F76020305-8bd0-406c-90d4-0e963f068f7a.jpeg</url>
      <title>DEV Community: Iain Earl</title>
      <link>https://dev.to/itmecho</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/itmecho"/>
    <language>en</language>
    <item>
      <title>Setting up Linode Object Storage as a Terraform backend</title>
      <dc:creator>Iain Earl</dc:creator>
      <pubDate>Fri, 03 Dec 2021 22:29:16 +0000</pubDate>
      <link>https://dev.to/itmecho/setting-up-linode-object-storage-as-a-terraform-backend-1ocb</link>
      <guid>https://dev.to/itmecho/setting-up-linode-object-storage-as-a-terraform-backend-1ocb</guid>
      <description>&lt;p&gt;In this post, we'll go through the setup process for configuring &lt;a href="https://www.linode.com/products/object-storage/" rel="noopener noreferrer"&gt;Linode Object Storage&lt;/a&gt; as a remote backend for your &lt;a href="https://www.terraform.io" rel="noopener noreferrer"&gt;terraform&lt;/a&gt; state. This enables you to have your state stored remotely, allowing you to safely store your terraform configuration publicly without worrying about leaking sensitive information through the state.&lt;/p&gt;

&lt;p&gt;Whilst terraform doesn't directly support Linode as a backend, Linode Object Storage is S3 compatible which means that with only a few extra settings, we can use it as an &lt;a href="https://www.terraform.io/docs/language/settings/backends/s3.html" rel="noopener noreferrer"&gt;S3 backend&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating the Bucket
&lt;/h2&gt;

&lt;p&gt;Now we could just go into the Linode dashboard and create the bucket manually but we're going to use terraform so why not use that to create the bucket as well! This means that the state for the bucket will need to be committed to the repository but that should be fine as we don't need to store any sensitive information to create it.&lt;/p&gt;

&lt;p&gt;In the folder where you want to create your terraform configuration, create a new folder to hold this initial terraform code and &lt;code&gt;cd&lt;/code&gt; into it. I'll call mine &lt;code&gt;init-state&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ~/src/infra/terraform
&lt;span class="nb"&gt;mkdir &lt;/span&gt;init-state
&lt;span class="nb"&gt;cd &lt;/span&gt;init-state
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we need to add the terraform code to create the bucket. This is pretty simple but can be extended to add extra configuration such as lifecycle rules or versioning.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt; &lt;br&gt;
At the time of writing this article, the current terraform version is &lt;code&gt;1.0.11&lt;/code&gt;. If you're using a newer version, it's possible that the syntax/format could have changed so make sure you're using the correct syntax for your version.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;First off, we create our &lt;code&gt;main.tf&lt;/code&gt; file, setup the terraform provider configuration, and register the provider. We'll be using the &lt;a href="https://registry.terraform.io/providers/linode/linode/latest" rel="noopener noreferrer"&gt;Linode provider&lt;/a&gt;. Make sure to use the latest version of the provider which at the time of writing is &lt;code&gt;1.25.0&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight terraform"&gt;&lt;code&gt;&lt;span class="k"&gt;terraform&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;required_providers&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;linode&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;source&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"linode/linode"&lt;/span&gt;
      &lt;span class="nx"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"1.25.0"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;provider&lt;/span&gt; &lt;span class="s2"&gt;"linode"&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can lookup the storage cluster you want to use, I'm using Frankfurt, DE as it's currently the only European region that supports object storage.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight terraform"&gt;&lt;code&gt;&lt;span class="k"&gt;data&lt;/span&gt; &lt;span class="s2"&gt;"linode_object_storage_cluster"&lt;/span&gt; &lt;span class="s2"&gt;"primary"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"eu-central-1"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, we can define our bucket and give it a name! The name must be unique across all Linode object storage, not just in your account.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight terraform"&gt;&lt;code&gt;&lt;span class="k"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"linode_object_storage_bucket"&lt;/span&gt; &lt;span class="s2"&gt;"tf_state"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;cluster&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;linode_object_storage_cluster&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;primary&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;
  &lt;span class="nx"&gt;label&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"my-tf-state"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All together, this is what we have:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight terraform"&gt;&lt;code&gt;&lt;span class="k"&gt;terraform&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;required_providers&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;linode&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;source&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"linode/linode"&lt;/span&gt;
      &lt;span class="nx"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"1.25.0"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;provider&lt;/span&gt; &lt;span class="s2"&gt;"linode"&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

&lt;span class="k"&gt;data&lt;/span&gt; &lt;span class="s2"&gt;"linode_object_storage_cluster"&lt;/span&gt; &lt;span class="s2"&gt;"primary"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"eu-central-1"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"linode_object_storage_bucket"&lt;/span&gt; &lt;span class="s2"&gt;"tf_state"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;cluster&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;linode_object_storage_cluster&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;primary&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;
  &lt;span class="nx"&gt;label&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"my-tf-state"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There's one last thing we need to do before we can apply our config and create the bucket, and that is to generate a Linode API token. To do that, go to the &lt;a href="https://cloud.linode.com/profile/tokens" rel="noopener noreferrer"&gt;API Tokens page&lt;/a&gt; and click the &lt;code&gt;Create a Personal Access Token&lt;/code&gt; button in the top right. Give it a name, an expiry, and some permissions. You should limit the permissions to what you plan on managing with terraform. For the sake of this guide, I set everything to Read/Write.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd66jyugtw4tvq3xi0nzh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd66jyugtw4tvq3xi0nzh.png" alt="Personal Access Token Create Screen"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now click &lt;code&gt;Create Token&lt;/code&gt; and copy the token that displays on the screen. Make sure you save the token somewhere safe like a password manager as once you close the popup, you won't be able to see the token again.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiflvkmtaoorzykgr7v1h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiflvkmtaoorzykgr7v1h.png" alt="Personal Access Token Display Popup"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For the Linode provider to access this token, you can just run the terraform commands and it will prompt for the token. If you don't want to enter it each time, you can set the &lt;code&gt;LINODE_TOKEN&lt;/code&gt; environment variable instead with the token as the value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;LINODE_TOKEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;paste-token-here&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We should now be ready to initalize terraform and apply the bucket configuration!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;terraform init
terraform apply
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This should download the Linode provider and then output a plan which looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Terraform will perform the following actions:

  # linode_object_storage_bucket.state will be created
  + resource "linode_object_storage_bucket" "state" {
      + acl          = "private"
      + cluster      = "eu-central-1"
      + cors_enabled = true
      + id           = (known after apply)
      + label        = "my-tf-state"
      + versioning   = (known after apply)
    }

Plan: 1 to add, 0 to change, 0 to destroy.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you're happy with the output, go ahead and type &lt;code&gt;yes&lt;/code&gt; to create the bucket!&lt;/p&gt;

&lt;p&gt;Before you commit everything to your repo, make sure to add &lt;code&gt;.terraform&lt;/code&gt; to your &lt;code&gt;.gitignore&lt;/code&gt; as it contains ephemeral data like the downloaded Linode provider which shouldn't be stored in your version control system.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configure Storage Access
&lt;/h2&gt;

&lt;p&gt;For terraform to be able to use the bucket as a backend, it needs access keys to allow it to read and write to the bucket. To create these keys, go to the &lt;a href="https://cloud.linode.com/object-storage/access-keys" rel="noopener noreferrer"&gt;Access Keys page&lt;/a&gt; and click the &lt;code&gt;Create Access Key&lt;/code&gt; button. In the panel that opens, give the key a label, enable limited access, and allow Read/Write access to your state bucket:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foqkljfifj3rg84kug5ru.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foqkljfifj3rg84kug5ru.png" alt="Create Access Token screen"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click the &lt;code&gt;Create Access Key&lt;/code&gt; button and you should see your keys. As with the API Token from the last section, once you dismiss the popup you can't access the keys again so make sure you have stored them somewhere safe!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb756ypa71yemilhbr747.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb756ypa71yemilhbr747.png" alt="Access Key display screen"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now to enable terraform to read these keys without having to store them in the code, you can either store them in environment variables &lt;code&gt;AWS_ACCESS_KEY_ID&lt;/code&gt; and &lt;code&gt;AWS_SECRET_ACCESS_KEY&lt;/code&gt;, or in the AWS shared credentials configuration. I will go over the latter as the former is the same process as the API token.&lt;/p&gt;

&lt;p&gt;The AWS shared credentials configuration consists of two files, &lt;code&gt;~/.aws/config&lt;/code&gt; and &lt;code&gt;~/.aws/credentials&lt;/code&gt;. The first file defines a profile which holds some general configuration like the output format and the default region. The second file contains the keys.&lt;/p&gt;

&lt;p&gt;Let's start with the profile. Create &lt;code&gt;~/.aws/config&lt;/code&gt; and define the &lt;code&gt;linode-s3&lt;/code&gt; profile. Having a separate profile means that if you have existing AWS profiles, this won't cause you any conflicts. You should set the &lt;code&gt;region&lt;/code&gt; setting to the region you chose when you created your state bucket:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="nn"&gt;[profile linode-s3]&lt;/span&gt;
&lt;span class="py"&gt;output&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;text&lt;/span&gt;
&lt;span class="py"&gt;region&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;eu-central-1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next we need to create the &lt;code&gt;~/.aws/credentials&lt;/code&gt; file. This should set the credentials for the &lt;code&gt;linode-s3&lt;/code&gt; profile. I would recommend restricting the permission on this file to &lt;code&gt;600&lt;/code&gt; which only allows read/write access to the owner of the file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="nn"&gt;[linode-s3]&lt;/span&gt;
&lt;span class="py"&gt;aws_access_key_id&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;access-key&amp;gt;&lt;/span&gt;
&lt;span class="py"&gt;aws_secret_access_key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;secret-key&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With these files in place, we should be ready for the last step, configuring the terraform backend!&lt;/p&gt;

&lt;h2&gt;
  
  
  Configure Terraform
&lt;/h2&gt;

&lt;p&gt;To configure the terraform backend, we should change to the directory where you want to store your terraform code and create a file named &lt;code&gt;backend.tf&lt;/code&gt;. It isn't required to be in it's own file but it does help to keep your code nicely organised. This file should contain the following terraform block:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight terraform"&gt;&lt;code&gt;&lt;span class="k"&gt;terraform&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;backend&lt;/span&gt; &lt;span class="s2"&gt;"s3"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;endpoint&lt;/span&gt;                    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"eu-central-1.linodeobjects.com"&lt;/span&gt;
    &lt;span class="nx"&gt;profile&lt;/span&gt;                     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"linode-s3"&lt;/span&gt;
    &lt;span class="nx"&gt;skip_credentials_validation&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
    &lt;span class="nx"&gt;bucket&lt;/span&gt;                      &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"my-tf-state"&lt;/span&gt;
    &lt;span class="nx"&gt;key&lt;/span&gt;                         &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"infra/state.json"&lt;/span&gt;
    &lt;span class="nx"&gt;region&lt;/span&gt;                      &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"eu-central-1"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This defines an &lt;code&gt;s3&lt;/code&gt; backend and points it to the Linode object storage endpoint for your chosen region, which in this example is &lt;code&gt;eu-central-1&lt;/code&gt;. Next we tell terraform to load the credentials from the &lt;code&gt;linode-s3&lt;/code&gt; profile we created in the AWS config files. It's important to set &lt;code&gt;skip_credentials_validation&lt;/code&gt; to &lt;code&gt;true&lt;/code&gt; as otherwise terraform will reach out to AWS STS to try to validate the access keys which will obviously fail. Finally we set the bucket name, key, and region. The key is the path in the bucket to the terraform state file.&lt;/p&gt;

&lt;p&gt;The last thing to do is initialise terraform with the new backend. Once that's done, you should be ready to create some resources with terraform and be safe in the knowledge that your state file is stored in a private Linode bucket!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;&lt;br&gt;
Terraform will still store a local copy of the state on your machine to make it easier to work with. &lt;strong&gt;It is VERY important to make sure you add the &lt;code&gt;.terraform&lt;/code&gt; directory to your &lt;code&gt;.gitignore&lt;/code&gt;&lt;/strong&gt; as otherwise this state file could be accidentally committed and all of our hard work will be for nothing!&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;terraform init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can test it out by creating a Linode resource and running &lt;code&gt;terraform apply&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight terraform"&gt;&lt;code&gt;&lt;span class="k"&gt;terraform&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;required_providers&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;linode&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;source&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"linode/linode"&lt;/span&gt;
      &lt;span class="nx"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"1.25.0"&lt;/span&gt; &lt;span class="c1"&gt;# Current latest version as of 2021-12-03&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;provider&lt;/span&gt; &lt;span class="s2"&gt;"linode"&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

&lt;span class="k"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"root_password"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt;        &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;
  &lt;span class="nx"&gt;description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Password for the root user"&lt;/span&gt;
  &lt;span class="nx"&gt;sensitive&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"linode_instance"&lt;/span&gt; &lt;span class="s2"&gt;"my_server"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;label&lt;/span&gt;           &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"my-server"&lt;/span&gt;
  &lt;span class="nx"&gt;image&lt;/span&gt;           &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"linode/debian11"&lt;/span&gt;
  &lt;span class="nx"&gt;region&lt;/span&gt;          &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"eu-west"&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt;            &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"g6-nanode-1"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;You should now be set up and ready to start creating your terraform resources with the state being safe in your remote Linode bucket. Hopefully you've learned a little about the benefits of storing your state using a remote backend and are inspired to play around with some infrastructure as code!&lt;/p&gt;

&lt;p&gt;It's worth noting that using Linode as a remote backend doesn't limit you to only managing Linode resources with your new setup. You can go ahead and use any of the official or community providers found on the &lt;a href="https://registry.terraform.io/" rel="noopener noreferrer"&gt;terraform registry&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Have fun learning and playing with terraform!&lt;/p&gt;

</description>
      <category>linode</category>
      <category>terraform</category>
    </item>
  </channel>
</rss>
