Skip to content

Using Object Storage as a Terraform Backend

By default, Terraform stores its state on the local disk of the developer or operator. This approach limits collaboration, risks data loss, and hinders automation.

Read more about what Terraform state is and why it exists here. Terraform supports various backends that allow you to store state in external systems. In this tutorial, we'll be setting up our Terraform project to use S3 compatible object storage as backend state storage.

0. Requirements

This tutorial expects you to have set up the openstack command line tool. See Getting Started -> How to use the Openstack CLI for a detailed guide.

1. Cloud Resources

Create an object storage container to host the statefiles and ec2-compatible credentials to access this container programmatically:

openstack container create tf-state
openstack ec2 credentials create

The latter command will output the access credentials and secret we'll plug into our terraform backend configuration in the next step.

2. Terraform Code

What follows is a bare minimum Terraform configuration to get you started on your LeafCloud. Pay special attention to the backend block, which is where the credentials we generated in our last step are to be plugged in.

terraform {
required_version = ">= 0.14.0"
  required_providers {
    openstack = {
      source  = "terraform-provider-openstack/openstack"
      version = "~> 1.53.0"
    }
  }
}

provider "openstack" {
  auth_url    = "https://create.leaf.cloud:5000"
  region      = "europe-nl"
  use_octavia = true # support octavia loadbalancer
  tenant_id   = "project ID: see create.leaf.cloud/project/api_access -> view credentials"
}

terraform {
  backend "s3" {
    bucket                      = "tf-state"
    key                         = "cool-site/terraform.tfstate"
    region                      = "required-but-not-used"
    access_key                  = "$$ access credential $$"
    secret_key                  = "$$ secret $$"
    skip_credentials_validation = true
    skip_requesting_account_id  = true
    skip_s3_checksum            = true
    skip_region_validation      = true # Region is not required for Openstack S3 Swift
    use_path_style              = true # Prevent using the bucketname as the hostname
    endpoints = {
      s3  = "https://leafcloud.store"
      sts = "https://leafcloud.store"
    }
  }
}

Once you have this in an updated main.tf file, you should be able to run terraform init in the repository and get started managing your LeafCloud infrastructure using Terraform!

Credential Management

For simplicity, we've explicitly defined the access credentials (access_key and secret_key) in the Terraform backend block. However, storing credentials in plaintext —especially in a Terraform file that may end up in a Git repository— is a poor security practice.

Instead, credentials should be provided externally such as through environment variables (AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY), which are automatically recognized by the S3 backend provider.