--- 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=" } } ```