Skip to main content

Backend Type: oras

Stores state snapshots as OCI artifacts in a configurable OCI repository.

This backend supports state locking.

Example Configuration

terraform {
backend "oras" {
repository = "registry.example.com/my-org/tofu-state"
}
}

Data Source Configuration

data "terraform_remote_state" "example" {
backend = "oras"

config = {
repository = "registry.example.com/my-org/tofu-state"
}
}

Authentication

This backend uses OpenTofu's standard OCI registry credentials mechanism.

By default, OpenTofu can obtain credentials from:

  • Explicit oci_credentials blocks in the OpenTofu CLI configuration.
  • Docker-style configuration files written by tools like docker login (for example ~/.docker/config.json).

To configure and understand the precedence rules, see OCI Registry Credentials.

Example: GitHub Container Registry (GHCR)

If you authenticate with Docker, OpenTofu can typically reuse those credentials:

docker login ghcr.io

If you want to disable all ambient credentials discovery and require explicit oci_credentials only, configure:

oci_default_credentials {
discover_ambient_credentials = false
}

Workspaces

This backend supports multiple workspaces by storing each workspace's state under a different OCI tag within the same repository.

State Locking

When locking is enabled, OpenTofu creates a lock marker in the OCI repository before writing state. Lock information is stored as OCI artifact metadata so other clients can detect an existing lock and report who is holding it.

note

Some OCI registries do not support deleting manifests via the OCI Distribution API. In that case, OpenTofu will still unlock successfully, but the repository might retain additional historical lock artifacts.

Configuration Variables

Warning

We recommend using environment variables to supply credentials and other sensitive data. If you use -backend-config or hardcode these values directly in your configuration, OpenTofu will include these values in both the .terraform subdirectory and in plan files. Refer to Credentials and Sensitive Data for details.

The following configuration options are supported:

  • repository / TF_BACKEND_ORAS_REPOSITORY - (Required) OCI repository reference where OpenTofu will store state, for example: registry.example.com/org/repo.
  • insecure - (Optional) Whether to skip TLS certificate verification when communicating with the registry. Defaults to false.
  • ca_file - (Optional) Path to a PEM-encoded CA bundle to trust when communicating with the registry.
  • retry_max / TF_BACKEND_ORAS_RETRY_MAX - (Optional) Number of retries for transient registry requests. Defaults to 2.
  • retry_wait_min / TF_BACKEND_ORAS_RETRY_WAIT_MIN - (Optional) Minimum wait (seconds) between retry attempts. Defaults to 1.
  • retry_wait_max / TF_BACKEND_ORAS_RETRY_WAIT_MAX - (Optional) Maximum wait (seconds) between retry attempts. Defaults to 30.
  • compression - (Optional) State compression. Supported values: none (default) and gzip.
  • lock_ttl / TF_BACKEND_ORAS_LOCK_TTL - (Optional) Lock TTL in seconds. If set, stale locks older than this are automatically cleared. 0 (default) disables.
  • rate_limit / TF_BACKEND_ORAS_RATE_LIMIT - (Optional) Maximum registry requests per second. 0 (default) disables rate limiting.
  • rate_limit_burst / TF_BACKEND_ORAS_RATE_LIMIT_BURST - (Optional) Maximum burst size for registry requests when rate limiting is enabled. 0 (default) means 1.

State Versioning

You can keep a limited number of historical state versions for audit and recovery.

terraform {
backend "oras" {
repository = "registry.example.com/my-org/tofu-state"
versioning {
enabled = true
max_versions = 10
}
}
}

State Compression

terraform {
backend "oras" {
repository = "registry.example.com/my-org/tofu-state"
compression = "gzip"
}
}

Lock TTL (Stale Lock Cleanup)

If you occasionally hit "zombie" locks (for example after a crash), configure lock_ttl to automatically clear locks older than the TTL.

terraform {
backend "oras" {
repository = "registry.example.com/my-org/tofu-state"
lock_ttl = 300
}
}

Rate Limiting

Some registries (for example Docker Hub or GHCR) may throttle bursty clients. You can apply client-side pacing:

terraform {
backend "oras" {
repository = "registry.example.com/my-org/tofu-state"
rate_limit = 5
rate_limit_burst = 2
}
}

State Encryption

If you enable state encryption, OpenTofu encrypts state data on the client before uploading it to the OCI registry. This backend stores the resulting bytes and does not perform encryption itself.