Skip to main content

Get ready for OpenTofu Beta 1.9.0

Get ready for OpenTofu Beta 1.9.0

Hey there, OpenTofu community! We've been working hard to refine the 1.9.0-alpha2 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.9.0-alpha2 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.9.0-beta1_windows_amd64.zip
MacOS
(Macbook M1 or higher; ARM64)
tofu_1.9.0-beta1_darwin_arm64.tar.gz
MacOS
(Macbook pre-M1; AMD64)
tofu_1.9.0-beta1_darwin_amd64.tar.gz
Intel/AMD Linux computer or server
(AMD64)
tofu_1.9.0-beta1_linux_amd64.tar.gz
ARM-based Linux computer
or
Raspberry Pi 3 or higher

(ARM64)
tofu_1.9.0-beta1_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 iteration (for_each)

One of the biggest challenges keeping the code clean in a multi-region or multi-zone deployment is the sheer number of providers and related configurations you have to juggle. Essentially, you will have to create duplicated code for each region or zone.

With provider iteration, you can now get rid of your code duplications by iterating over a set of providers instead of the duplicated code. If you have a small-scale setup with one of the cloud providers offering multiple zones, start by adding two variables:

Code Block
variable "regions" {
description = "A list of regions that should have a deployment."
type = set(string)
}

variable "disabled_regions" {
description = "A list of regions that should be disabled and all resources removed."
type = set(string)
default = []
}

The regions variable serves as a list of regions you will want to deploy to. The disabled_regions variable will allow you to remove a region later without removing the provider. This feature is extremely important because if you remove the provider without removing its resources, OpenTofu will be unable to remove the resources in that region.

As a next step, you can create your provider declarations. As you can see, this is only a single declaration. The only restriction worth mentioning here is the alias. Due to technical limitations, in this version you can only use for_each in conjunction with alias.

Code Block
provider "aws" {
alias = "by_region"
region = each.value
for_each = var.regions
}

Finally, you can use the provider set to call a submodule. Note that in contrast to the provider block above, the for_each iterates only over the providers that are not disabled. This lets you deprovision a region properly and later completely remove the provider.

Code Block
module "deploy" {
source = "./deploy"
providers = {
aws = aws.by_region[each.key]
}
for_each = setsubtract(var.regions, var.disabled_regions)
}

As this feature is very new, there are a few limitations in place you may want to observe:

  1. You can only use for_each on variables and locals that can be obtained statically. Expressions that rely on data sources or resources are currently not usable.
  2. If you have an already-deployed infrastructure, don't simply remove a provider from the list as this will make it impossible for OpenTofu to destroy the infrastructure in this region. Instead, you will need to implement removing that infrastructure first and then remove the provider from the list. See the disabled_regions variable for an example above.
  3. Currently, each provider used in a for_each must have an alias. Providers without aliases are not supported for now due to internal technical reasons.
  4. There is currently no way to pass a set of providers to a module, you can only pass individual providers.

The -exclude flag

OpenTofu already has a -target option to only plan or apply certain resources. Why not apply everything except a certain resource? This was the thought behind the -exclude flag and, in fact, this was one of the highest upvoted feature requests for this release.

You can test it by creating the following simple configuration:

Code Block
resource "local_file" "a" {
filename = "a.txt"
content = "a"
}

resource "local_file" "b" {
filename = "b.txt"
content = "b"
}

resource "local_file" "c" {
filename = "c.txt"
content = "c"
}

If you run tofu apply -exclude local_file.b, you will see that OpenTofu creates a.txt and c.txt, but not b.txt.

Bugfixes and improvements

Early evaluation improvements

When using early evaluation introduced in OpenTofu 1.8, OpenTofu will now prompt you for the variables needed for evaluation.

The new encrypted_metadata_alias option for state encryption

One of the tricky parts when using state encryption in previous versions is that OpenTofu needs to store the name of the key provider into the encrypted data alongside some metadata needed for decryption. This meant that changing the key provider name would involve using a fallback block and key provider naming for remote state data sources would have to be synchronized. With OpenTofu 1.9, we are introducing a new encrypted_metadata_alias option you can use to explicitly set the ID stored with the encrypted data:

Code Block
terraform {
encryption {
key_provider "pbkdf2" "mykey" {
passphrase = "OpenTofu has encryption"
# Note the fixed encrypted_metadata_alias here:
encrypted_metadata_alias = "certificates"
}
method "aes_gcm" "mymethod" {
keys = key_provider.pbkdf2.mykey
}
state {
method = method.aes_gcm.mymethod
}
}
}

Logging and other improvements

  • You can now use the -consolidate-warnings and -consolidate-errors options to consolidate similar warnings and errors together.
  • The HTTP backend now supports extended trace logging, including request and response bodies.
  • OpenTofu will now prompt for values for input variables needed for early evaluation.
  • tofu console now accepts expressions split over multiple lines, when the newline characters appear inside bracketing pairs or when they are escaped using a backslash.
  • tofu test now throws errors instead of warnings for invalid override and mock fields.
  • Several performance improvements for large graphs and large amounts of submodules.

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.