Terraform remote state backup with Digital Ocean Spaces

Aniruddha Chakraborty
2 min readJan 8, 2023

We all are so used to AWS nowadays, so terraform decides to make it a default to use AWS as terraform backup backend. Not everyone uses AWS in their daily lives, for cost-effectiveness people choose Digital Ocean. We’re are one of them.

As I maintain the whole infrastructure myself as an SRE it’s my job to do as much automation as possible. After converting our whole infrastructure to IAC. I’ve got a little bit worried about the state file that terraforms creates and is modified every time I change something in the infrastructure. As I was writing an automation script for terraform script deployment as multiple people started to work on IAC, I found our Digital Ocean is a bit different. You kind of have to trick terraform into believing that it is still using AWS as a backend.

First, create a bucket & then generate the DigitalOcean API key & Secret to use on terraform. You can go to API on DigitalOcean and create those like those shown below.

Then, install AWS CLI on your machine. Then you have to create a profile

aws configure --profile digitalocean

Put key & secret. It will create a profile of the DigitalOcean with its access keys.

Then change AWS_PROFILE to your created “Digital Ocean” Profile.

export AWS_PROFILE=digitalocean

Then, just like shown in the code you have to add a backend code block.

There are a few things you might need to notice:

  • where the region is from AWS because terraform doesn’t recognize DigitalOcean regions, even after adding endpoints.
  • You don’t need to use the original URL that is given in the bucket. You can just use the part after the bucket name.
  • The bucket name should be the one you want to put the state files in.
terraform {
required_providers {
digitalocean = {
source = "digitalocean/digitalocean"
version = "~> 2.0"
backend "s3" {
endpoint = "sgp1.digitaloceanspaces.com"
key = "terraform.tfstate"
bucket = "bucketname"
region = "ap-southeast-1"
skip_credentials_validation = true
skip_metadata_api_check = true

And that’s it. This is nothing complicated but just you need to where you need to do the changes in order to make this thing work. Adios!



Aniruddha Chakraborty

Passionate Distributed Systems Engineer. Proficient writing code in Go,Node.js, Typescript, Python, and PHP.