Skip to main content

Get ready for OpenTofu Beta 1.8.0

Get ready for OpenTofu Beta 1.8.0

Hey there, OpenTofu community! We've been working hard to refine the 1.8.0-alpha1 with your feedback! A few rough edges have been polished and a few new features have been added.

If you have a non-production setup that you would be willing to test any of the new features on, please give it a try and give us feedback using a GitHub issue, even if it's just telling us that everything went well.

This blog post will go over how to download the new preview release and expand on the features presented in the 1.8.0-alpha1 blog post.

Downloading the beta release

The beta release is available exclusively from the GitHub Releases page. Please select the appropriate file for your platform. Here are some quick links:

Platform/DeviceDownload link
Desktop Windows computer
(64-bit)
tofu_1.8.0-beta2_windows_amd64.zip
MacOS
(Macbook M1 or higher; ARM64)
tofu_1.8.0-beta2_darwin_arm64.tar.gz
MacOS
(Macbook pre-M1; AMD64)
tofu_1.8.0-beta2_darwin_amd64.tar.gz
Intel/AMD Linux computer or server
(AMD64)
tofu_1.8.0-beta2_linux_amd64.tar.gz
ARM-based Linux computer
or
Raspberry Pi 3 or higher

(ARM64)
tofu_1.8.0-beta2_linux_arm64.tar.gz

For the releases above, please unpack the archive and you should find the tofu binary inside. You can also use the standalone installer to download the release with signature verification.

Provider mocking in tofu test

Building on the existing ability to override specific data sources, resources, and module calls, tofu test now supports mocking entire provider definitions. This new feature allows you to automatically generate mock values for resources and data sources on a per-provider basis. As an example, consider the following code that spins up an m6i.2xlarge instance on AWS:

Code Block
provider "aws" {
region = "us-east-1"
}

data "aws_ami" "ubuntu" {
most_recent = true
filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-jammy-24.04-amd64-server-*"]
}
owners = ["099720109477"]
}

resource "aws_instance" "web" {
ami = data.aws_ami.ubuntu.id
instance_type = "m6i.2xlarge"
}

Instead of querying the AMI ID and spinning up the instance, we can write test code as follows:

Code Block
// This block will prevent OpenTofu from configuring aws provider.
// All provider's resources and data sources will be mocked.
mock_provider "aws" {
mock_data "aws_ami" {
defaults = {
id = "ami-12345"
}
}
}

run "test" {
assert {
condition = aws_instance.web.ami == "ami-12345"
error_message = "Incorrect AMI ID passed to aws_instance.web: ${aws_instance.web.ami}"
}
}

While this will not fully test the entire provisioning, it will highlight errors that may be caused by incorrectly connecting resources together without the need for an actual AWS account.

Resource overrides in tofu test

First introduced in OpenTofu 1.8.0-alpha1, you can now override resources, data sources and entire modules from your tests, allowing you to create similar behavior to mocks in traditional software testing. As an example, consider the following code that spins up an m6i.2xlarge instance on AWS:

Code Block
provider "aws" {
region = "us-east-1"
}

data "aws_ami" "ubuntu" {
most_recent = true
filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-jammy-24.04-amd64-server-*"]
}
owners = ["099720109477"]
}

resource "aws_instance" "web" {
ami = data.aws_ami.ubuntu.id
instance_type = "m6i.2xlarge"
}

Instead of querying the AMI ID and spinning up the instance, we can write test code as follows:

Code Block
provider "aws" {
access_key = "foo"
secret_key = "bar"

skip_credentials_validation = true
skip_region_validation = true
skip_metadata_api_check = true
skip_requesting_account_id = true
}

# This block disables refreshing the aws_ami.ubuntu data source
# and lets you manually specify the values:
override_data {
target = data.aws_ami.ubuntu
values = {
id = "ami-12345"
}
}

run "test" {
# This block disables provisioning the aws_instance.web resource:
override_resource {
target = aws_instance.web
values = {
# You can add values here.
}
}

assert {
condition = aws_instance.web.ami == "ami-12345"
error_message = "Incorrect AMI ID passed to aws_instance.web: ${aws_instance.web.ami}"
}
}

While this will not fully test the entire provisioning, it will highlight errors that may be caused by incorrectly connecting resources together without the need for an actual AWS account. Similarly, you can use override_module to override an entire module.

Early variable/locals evaluation

Introduced in OpenTofu 1.8.0-alpha1, this feature lets you use variables and locals for backends, module sources and encryption configuration as long as they are not dependent on resources, data sources or module outputs. This works even if a local is referencing a variable, for example. This is only the first in a series of improvements that will make the .tf code more flexible with more improvements coming in future releases.

The tofu init command will now consume your .tfvars file and let you specify variables using the -var and -var-file options. Please note that this alpha release will not prompt you for missing variables, which is a feature we will add later. Note, that tofu init will fail if it is missing variables needed for static evaluation.

For example, if you wanted to use the same configuration for your S3 backend and your AWS provider, you can now do this:

Code Block
variable "aws_region" {
default = "us-east-1"
}

terraform {
backend "s3" {
region = var.aws_region
}
}

provider "aws" {
region = var.aws_region
}

You can also use this to manage module versions with both registry references and git URLs.

Code Block
locals {
aws_module_version = "5.6.1"
}

module "webserver" {
source = "terraform-aws-modules/ec2-instance/aws"
version = local.aws_module_version

// Other ec2_instance options
}

module "db" {
source = "https://github.com/terraform-aws-modules/terraform-aws-ec2-instance?ref=v${local.aws_module_version}"

// Other ec2_instance options
}

Finally, here's how you can set up encryption with a passphrase using a variable:

Code Block
variable "passphrase" {
type = string
}

terraform {
encryption {
key_provider "pbkdf2" "my_passphrase" {
passphrase = var.passphrase
}

method "aes_gcm" "my_method" {
keys = key_provider.pbkdf2.my_passphrase
}

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

Override files for OpenTofu: keeping compatibility

Since we are now adding features to OpenTofu that are not present in Terraform, we want to give module authors the ability to write code for both OpenTofu and Terraform without needing to maintain two copies of their modules. You can now create files named .tofu that are exclusive to OpenTofu. If you create a file named foo.tofu, OpenTofu will ignore the similarly-named foo.tf file. You can use this functionality to put your Terraform-specific code in the .tf file and then override it for OpenTofu in the .tofu file.

Bugfixes and improvements

Static Variable Planing

Static variables are now handled correctly when embedded in plan files. This was reported as a bug found in 1.8.0-alpha1.

Code Block
tofu plan -out=tofu.tfstate -var="param=value"
# Variables are correctly read from the given plan and should not be specified via CLI
tofu show tofu.tfstate
tofu apply tofu.tfstate

Improved provider error messages

Also included in the beta is improvements in error messages produced by misconfigured providers. Some defaulted providers which require configuration blocks were able to generate error messages like:

Code Block

│ Error: Insufficient features blocks

│ on <empty> line 0:
│ (source code not available)

│ At least 1 "features" blocks are required.

This error message will now include information about which provider is encountering the specific missing-block validation issue to help the user track it down.

Providing feedback

Thank you for taking the time to test this preview release. If you have any feedback, please use a GitHub issue or chat with us on the OpenTofu Slack.