Store Terraform State on Backblaze S3 Credits: Wesley Tingey on Unsplash

Store Terraform State on Backblaze S3

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, 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 {
  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 (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 {
  backend "s3" {
    ...
    encrypt                     = true
    sse_customer_key            = "fsRb1SXBjiUqBM0rw/YqvDixScWnDCZsK7BhnPTc93Y="
  }
}