I Can’t Believe It’s Not S3: Storing Your Terraform State in Cloudflare R2
Or other S3 compatible services.
Why? Storing your state remotely is almost always necessary and there are often times where R2 is more accessible than S3.
TL;DR
Create a new R2 bucket.
Add this backend configuration to your
terraform
block, substituting your own values.
terraform {
backend "s3" {
endpoint = "https://<ACCOUNT-ID>.r2.cloudflarestorage.com"
force_path_style = true
bucket = "<BUCKET-NAME>"
key = "<MY-KEY>"
region = "us-east-1"
skip_credentials_validation = true
}
}
Grab some credentials from the API tokens dashboard and assign the relevant values to the
AWS_ACCESS_KEY_ID
andAWS_SECRET_ACCESS_KEY
environment variables.Run
terraform init
to complete the process. You will get prompted to migrate your state if you already have some elsewhere.
Explanation
force_path_style
Instead of using the traditional S3 URL style of https://<BUCKET>.<HOST>
we want to use R2’s style of https://<HOST>/<BUCKET>
region
Even though your actual R2 region may be set differently, Terraform won’t accept anything other than recognised S3 regions, so we set it to the default us-east-1. Good thing is Cloudflare can handle this as part of their S3 compatibility.
skip_credentials_validation
Typically, Terraform will perform some validation of the credentials you’ve provided. Cloudflare doesn’t support this, so we need to disable it. Note that as far as I’m aware this doesn’t reduce security.