Skip to main content

What's new in OpenTofu 1.10?

OpenTofu 1.10 brings major improvements to how you distribute and manage your infrastructure code, with OCI registry support, native S3 state locking, and enhanced observability through OpenTelemetry tracing.

This page will run you through the most important changes in OpenTofu 1.10:

OCI Registry Support​

OpenTofu can now use OCI (Open Container Initiative) registries to distribute both providers and modules, enabling you to use your existing container registry infrastructure for infrastructure-as-code components.

Configure OCI registry provider mirrors in your CLI configuration:

Code Block
provider_installation {
oci_mirror {
repository_template = "example.com/opentofu-providers/${namespace}/${type}"
include = ["registry.opentofu.org/*/*"]
}
}

Use module packages from OCI registries directly as a new module source type:

Code Block
module "vpc" {
source = "oci://example.com/terraform-modules/vpc/aws"
}

This feature is particularly valuable for air-gapped environments and organizations that want to use their existing container registry infrastructure.

You can find more information on OpenTofu's OCI artifact formats, and instructions for building your own artifacts, in OCI Registry Integrations.

Native S3 State Locking​

The S3 backend now supports native state locking without requiring DynamoDB, simplifying your infrastructure and reducing costs.

Code Block
terraform {
backend "s3" {
bucket = "my-opentofu-state"
key = "prod/opentofu.tfstate"
region = "us-east-1"
use_lockfile = true # Enable native S3 locking
}
}

This feature leverages S3's conditional writes to provide reliable state locking using only your S3 bucket. Migration from DynamoDB-based locking is straightforward, with support for dual locking during the transition period. See the S3 backend documentation for details.

OpenTelemetry Tracing (Experimental)​

Debug and optimize your OpenTofu operations with built-in OpenTelemetry support. Tracing is disabled by default to ensure privacy.

Enable tracing by setting environment variables:

Code Block
export OTEL_TRACES_EXPORTER=otlp
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317
export OTEL_EXPORTER_OTLP_INSECURE=true

OpenTofu will then send traces to your configured collector (such as Jaeger or Grafana Tempo), helping you identify performance bottlenecks and debug complex operations. Learn more in the tracing documentation.

Please note that no telemetry data is sent to OpenTofu or any external service unless you explicitly configure it.

Target and Exclude Files​

New -target-file and -exclude-file options allow you to manage resource targeting through version-controlled files:

Code Block
tofu plan -target-file=targets/production.txt
tofu apply -exclude-file=excludes/experimental.txt

The file format is simple - one resource address per line with support for comments:

Code Block
# Critical infrastructure components
module.networking.aws_vpc.main
module.networking.aws_subnet.public[*]

# Database infrastructure
module.database.aws_db_instance.primary

This feature is perfect for CI/CD pipelines, phased deployments, and team collaboration.

Global Provider Cache Lock​

Concurrent OpenTofu operations can now safely share the provider cache, preventing corruption and conflicts in CI/CD environments and when using tools like Terragrunt.

Enable the global cache with:

Code Block
export TF_PLUGIN_CACHE_DIR=/path/to/shared/cache

The filesystem-level locking ensures only one process can modify a provider at a time, while others wait gracefully. This makes the provider cache ready for large-scale parallel operations.

You can find more information about using the global provider cache in the provider cache documentation.

Deprecation Support (Experimental)​

Module authors can now mark variables and outputs as deprecated, helping users migrate to newer APIs gracefully:

Code Block
variable "instance_type" {
type = string
deprecated = "Use var.compute_type instead"
}

output "instance_ip" {
value = aws_instance.main.public_ip
deprecated = "Use output.instance_details for more information"
}

Users will see clear warnings when using deprecated features, making module evolution more manageable.

Enhanced moved and removed blocks​

The moved block now supports migrating resources between different types, including built-in support for migrating from null_resource to terraform_data:

Code Block
moved {
from = null_resource.example
to = terraform_data.example
}

The removed block now supports lifecycle rules and provisioners:

Code Block
removed {
from = aws_instance.legacy

lifecycle {
destroy = false
}
}

These enhancements make infrastructure refactoring more powerful and flexible. See the refactoring documentation for more details.

External Key Providers​

State encryption now fully supports external key providers, allowing integration with your preferred secret management tools:

Code Block
terraform {
encryption {
key_provider "external" "password_manager" {
command = ["op", "read", "op://opentofu/stateencryption"]
}

method "aes_gcm" "state" {
keys = key_provider.external.password_manager
}

state {
method = method.aes_gcm.state
}
}
}

You can also chain key providers for enhanced security. Learn more in the state encryption documentation.

Breaking Changes​

Platform Requirements​

  • Linux: Now requires kernel 3.2 or later
  • macOS: Now requires macOS 11 (Big Sur) or later
  • Windows: More conservative symlink handling

Docker Image​

The ghcr.io/opentofu/opentofu image is no longer supported as a base image. See building your own image for alternatives.

PostgreSQL Backend​

The locking mechanism has changed. You should not use OpenTofu 1.10 in parallel with earlier versions when sharing the same PostgreSQL database because the locking implementation has changed. Mixing versions can lead to conflicting writes and could cause data loss.

Smaller improvements​

  • The element function now supports negative indices: element(list, -1) returns the last element
  • New -concise flag for cleaner automation output
  • PostgreSQL backend supports custom table names for multi-project setups
  • HTTP backend now supports force-unlock
  • Provider installation performance improvements
  • Improved error messages for type conversion failures
  • New built-in provider functions:
    • provider::terraform::decode_tfvars - Decode a TFVars file content into an object
    • provider::terraform::encode_tfvars - Encode an object into a string with TFVars format
    • provider::terraform::encode_expr - Encode an expression into valid OpenTofu syntax
  • OpenTofu now recommends -exclude instead of -target in error messages about unknown values in count and for_each

Bugfixes​

  • Fixed provider name validation crash in provider_meta block
  • PostgreSQL backend no longer fails on workspace creation for parallel returns
  • Fixed null value handling in element, slice, and values functions
  • Resolved state encryption issues with backend interactions
  • Fixed import block generation improvements
  • Better handling of provider installation errors
  • Fixed dependency graph issues with import blocks

For a complete list of changes, see the full changelog.