DEV Community

Cover image for Store your OpenTofu State in GitHub Container Registry (GHCR)
Victor M. Varela
Victor M. Varela

Posted on

Store your OpenTofu State in GitHub Container Registry (GHCR)

When OpenTofu 1.10 announced OCI support for providers, many thought: "What about state?" Until now, nothing. So I created a fork that solves this gap.

The Problem

153 MB of tfstate in S3 + DynamoDB for locking = overkill for many projects. If your team already has:

  • OCI registry used (such as GHCR)
  • GitHub Actions to deploy terraform code

Why add another service and cost?

The Solution: ORAS Backend

My project adds a native oras backend:

terraform {
  backend "oras" {
    repository  = "ghcr.io/org/project-state"
    compression = "gzip"

    versioning {
      enabled      = true
      max_versions = 5
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Features

✅ Stores state as OCI artifacts (content-addressable)
✅ Distributed locking (no DynamoDB needed)
✅ Configurable versioning and retention
✅ Uses tofu login and Docker credentials
✅ Compatible with OpenTofu's native encryption
✅ Works with any OCI registry (GHCR, ECR, ACR, Docker Hub, Harbor)

Installation

# Installs as `tofu-oras`
curl -sSL https://raw.githubusercontent.com/vmvarela/opentofu/develop/install.sh | sh
Enter fullscreen mode Exit fullscreen mode

Use Cases

Perfect for:

  • Startups with lean infra-as-code
  • Personal/side projects with free GHCR
  • Air-gapped environments (registry mirror)
  • Teams already invested in OCI ecosystem
  • Multi-cloud projects

Quick Test

git clone https://github.com/vmvarela/opentofu
cd opentofu
go build -o tofu-oras ./cmd/tofu
Enter fullscreen mode Exit fullscreen mode

Full documentation: ORAS Backend README

Example with Encryption

terraform {
  backend "oras" {
    repository = "ghcr.io/my-org/tf-state"
  }

  encryption {
    key_provider "pbkdf2" "main" {
      passphrase = var.state_passphrase
    }
    method "aes_gcm" "main" {
      key_provider = key_provider.pbkdf2.main
    }
    state {
      method = method.aes_gcm.main
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Next Steps

If the community shows interest, I can:

  • Improve test coverage
  • Add more examples for different use cases
  • Test with other OCI registries besides GHCR

Feedback Wanted

What do you think? Would you store state in OCI registries instead of S3, etc? What features would you need to adopt this?

Repo: github.com/vmvarela/opentofu

Top comments (0)