Hi everyone ![]()
I’ve been experimenting with storing Terraform state directly in an OCI registry, and I’ve just published the result:
It uses the ORAS protocol, so in theory you can use it with GHCR, Docker Hub, Harbor, Zot, or pretty much any OCI-compatible registry.
The interesting part is that it doesn’t need a separate state backend. If you’re already running an OCI registry, you can just use it for your Terraform state as well.
For example:
terraform {
required_providers {
oras = {
source = "registry.terraform.io/vmvarela/oras"
version = "~> 0.1"
}
}
state_store "oras_oci" {
provider = oras
url = "oci://ghcr.io/myorg/infra-tfstate"
lock_ttl = "15m"
max_versions = 10
}
}
provider "oras" {}
There’s one important catch though: this is experimental and currently only works with Terraform 1.17 alpha builds, using the pluggable state storage experiment:
export TF_ENABLE_PLUGGABLE_STATE_STORAGE=1
export GHCR_TOKEN=ghp_xxxxxxxxxxxx
terraform init
terraform apply
Internally, workspaces are mapped to OCI tags (state-<workspace> and stver-<workspace>-vN). Locking uses generation-based optimistic concurrency, with a TTL to deal with stale locks. Older state versions can also be pruned automatically.
A few limitations at the moment:
-
Terraform 1.17 alpha only
-
GHCR pruning needs
delete:packages -
No migration command yet —
terraform state pull/terraform state pushcan be used to move existing state
I’ve also included a runnable local example using Zot over plain HTTP.
This is very much an experiment at this point, so I’m particularly interested in feedback from people playing with Terraform’s pluggable state storage.
Would you actually use an OCI registry as a Terraform state backend? And if not, what’s missing?