---
title: "Store Terraform State on Backblaze S3"
date: 2022-09-04T20:47:53+02:00
authors:
  - robert-kaussow
tags:
  - Sysadmin
  - Automation
resources:
  - name: feature
    src: "images/feature.jpg"
    params:
      anchor: Center
      credits: >
        [Wesley Tingey](https://unsplash.com/@wesleyphotography) on
        [Unsplash](https://unsplash.com/s/photos/file)
---

Terraform is an open source infrastructure-as-code tool for creating, modifying, and extending infrastructure in a secure and predictable way. Terraform needs to store a state about the managed infrastructure and configuration. This state is used by Terraform to map real-world resources to your configuration and track metadata. By default, this state is stored in a local file, but it can also be stored remotely.

Terraform supports multiple remote backend provider including S3. I already use Backblaze for backups and have had good experiences with it. Since Backblaze also provides an S3 Compatible API, I wanted to use it for Terraform. How to use S3 as a state backend is well [documented](https://developer.hashicorp.com/terraform/language/settings/backends/s3), but as it's focused on Amazon S3 there are a few things to take care of. A basic working configuration will look like this:

```Terraform
terraform {
  backend "s3" {
    bucket                      = "my-bucket"
    key                         = "state.json"
    skip_credentials_validation = true
    skip_region_validation      = true
    endpoint                    = "https://s3.us-west-004.backblazeb2.com"
    region                      = "us-west-004"
    access_key                  = "0041234567899990000000004"
    secret_key                  = "K001abcdefgklmnopqrstuvw"
  }
}
```

It is required to enable `skip_credentials_validation` and `skip_region_validation` because Backblaze uses a different format for these values and the validation only covers Amazon S3. For security reasons, I would recommend setting at least the `access_key` and `secret_key` parameters as environment variables instead of writing them to the Terraform file. For the credentials, it is required to create an App Key on Backblaze. After creating the Key the `keyName` need to be used as `access_key` and `applicationKey` as `secret_key`.

That's basically all. If you want to go a step further, it is possible to save the state encrypted with [Server-Side Encryption](https://www.backblaze.com/b2/docs/server_side_encryption.html) (SSE). There are two options available. The first is `SSE-B2`, where the key is managed and stored by Backblaze, which is quiet simple to configure. The second option is to use customer managed keys. Using this option, an AES-256 and base64 encoded key is used. To generate a proper key, the command `openssl rand -base64 32` can be used.

To enable encryption in the Terraform Provider, the configuration must be extended:

```Terraform
terraform {
  backend "s3" {
    ...
    encrypt                     = true
    sse_customer_key            = "fsRb1SXBjiUqBM0rw/YqvDixScWnDCZsK7BhnPTc93Y="
  }
}
```
