HCL & Terraform compatibility
Providers, resources, and shared syntax.
OpenTofu speaks the same configuration language as Terraform — HCL — with the same building blocks: a provider configures a target platform, a resource declares a piece of infrastructure, and references wire them together into an implicit dependency graph. If you have written Terraform, none of this is new; if you have not, this is the same core you would learn there.
terraform { # yes, still the "terraform" blockrequired_providers {aws = { source = "hashicorp/aws", version = "~> 5.0" }}}provider "aws" { region = "us-east-1" }resource "aws_s3_bucket" "logs" {bucket = "acme-logs-prod"}resource "aws_s3_bucket_versioning" "logs" {bucket = aws_s3_bucket.logs.id # reference => dependency edgeversioning_configuration { status = "Enabled" }}
File extensions and the settings block
OpenTofu reads .tf files for full Terraform compatibility, and also supports a .tofu extension for files that should apply only under OpenTofu — a .tofu file overrides a same-named .tf file when running tofu, which is how you keep one repo that behaves one way under each tool. For maximum compatibility the top settings block is still named terraform { }, not tofu { } — a pragmatic choice so shared modules parse under both.
# providers resolve through the same protocol => the ecosystem just works$ tofu providersProviders required by configuration:.└── provider[registry.opentofu.org/hashicorp/aws] ~> 5.0