# How to Use DigitalOcean's Spaces as a Remote State Backend for IaC

I recently started building a remote homelab within Digital Ocean’s cloud space and I wanted to see if I could leverage their **“**[**Spaces Object Storage**](https://www.digitalocean.com/products/spaces)**”** as a compatible remote backend for OpenTofu. At this point I have been using OpenTofu’s [**“local”**](https://opentofu.org/docs/language/settings/backends/local/) backend setup to manage my state file but this isn’t a sustainable method nor actually used in professional setting. So lets migrate our local state over to a remote object storage.

## **Prerequisites:**

1. Using `=>1.6` OpenTofu version
    
2. Create your Digital Ocean account and project
    
3. Create a Spaces storage bucket ([click here for instructions](https://docs.digitalocean.com/products/spaces/how-to/create/))
    
4. Create a Spaces access key ([click here for instructions](https://docs.digitalocean.com/products/spaces/how-to/manage-access/#access-keys))
    

## Approach

Spaces Object Storage is an S3 compatible object storage service. With this in mind we are going to reuse OpenTofu’s S3 backend support and extend it to a Spaces storage bucket. If you have have completed the required prerequisites, we can proceed forward.

## Instructions

### Set up required Environment Variables

Using environment variables is the recommended way to provide your Spaces access key. Other methods, such as `tofu init -backend-config` or hardcoding values, may expose secrets in your `.terraform` folder and plan files.

OpenTofu’s S3 backend leverages `AWS_` prefixed environment variables for configuration. We will use these same variables but supply our Spaces access key values in place of AWS values.

```rego
export AWS_ACCESS_KEY_ID="<your_access_key>"
export AWS_SECRET_ACCESS_KEY="<your_secret_key>"
```

Replace the `<your_access_key>` and `<your_secret_key>` placeholders with your actual values.

### Setup S3 Backend Configuration

Here is an example of my remote backend configuration. It uses OpenTofu’s `S3` backend with DigitalOcean Spaces bucket values.

```rego
terraform {
  required_version = "~> 1.9.0"

  backend "s3" {
    endpoints = {
      s3 = "<spaces_bucket_region>.digitaloceanspaces.com"
    }

    bucket = "<spaces_bucket_name>"
    key    = "<path/and/state/file/name>"

    # Deactivate a few AWS-specific checks
    skip_credentials_validation = true
    skip_requesting_account_id  = true
    skip_metadata_api_check     = true
    skip_region_validation      = true
    skip_s3_checksum            = true
    region                      = "us-east-1"
  }
}
```

**Values required:**

1. `S3` : Replace `<spaces_bucket_region>` with the region of the bucket you created.
    
2. `bucket` : Replace `<spaces_bucket_name>` with the name of your bucket.
    
3. `key` : Update `<path/and/state/file/name>` with path and file name you would like to store your OpenTofu state under. If the path does not exist OpenTofu will create it when your initialize your IaC space.
    

## Migrate or Initialize your State

At this point you should be ready to start using your newly setup remote state in DigitalOcean

**Migrate local state to remote**

```rego
tofu init -migrate-state
```

**Initialize empty OpenTofu space**

```rego
tofu init
```

## Reference

* [https://github.com/opentofu/opentofu/tree/main/internal/backend/remote-state/s3](https://github.com/opentofu/opentofu/tree/main/internal/backend/remote-state/s3)
