The upcoming OpenTofu 1.9 release is packed with features that simplify infrastructure management. The two main highlights of this release are the introduction of the [.code]-exclude[.code] flag and the [.code]for_each[.code] functionality for providers. Both are features that were long-requested by the community.
Let’s dive into these features and see how they can improve your infrastructure management.
The -exclude Flag
The [.code]-exclude[.code] flag introduces a new level of control in deployment processes. Acting as the opposite of the [.code]-target[.code] flag, it allows you to plan and apply everything except specified resources or modules.
Before this feature was introduced, excluding a resource or module required manually targeting every other resource, which was tedious and prone to errors. Now, with the [.code]-exclude [.code] flag, you can focus your deployments while skipping resources or modules effortlessly with a more efficient, DRY (Don’t Repeat Yourself) approach.
The use cases for the [.code]-exclude [.code] flag include:
- Handling drift: When a resource is drifted and requires troubleshooting without blocking other updates.
- Service downtime: When a specific service is temporarily down, but you want to proceed with deploying unaffected resources.
Here is an example of how the [.code]-exclude[.code] flag works:
tofu apply -exclude=aws_vpc.my_vpc
Running this applies all resources except aws_vpc.my_vpc and any dependencies tied to it, acting as a simple and useful time saver.
for_each for Providers
The [.code]for_each[.code] functionality for providers is another step forward in reducing redundant code, especially when working across m
For example, you might have different region setups for your AWS accounts—multiple regions in your dev account and a single region in your production account. Without [.code]for_each[.code] for providers, managing this setup in a single configuration just wasn’t possible.
Instead, you had to define each region separately and use each provider in its own resource or module block, like so:
provider "aws" {
alias = "useast"
region = "us-east-1"
}
provider "aws" {
alias = "uswest"
region = "us-west-1"
}
module "eks-useast" {
source = "./eks"
providers = {
aws = aws.useast
}
}
module "eks-uswest" {
source = "./eks"
providers = {
aws = aws.uswest
}
}
resource "aws_instance" "ec2-useast" {
instance_type = "t3.micro"
provider = aws.useast
}
resource "aws_instance" "ec2-usewest" {
instance_type = "t3.micro"
provider = aws.uswest
}
…
Now, instead of this tedious process, you can simply use [.code]for_each[.code] in the provider block to dynamically create instances with different configurations:
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 = []
}
provider "aws" {
alias = "by_region"
region = each.value
for_each = var.regions
}
module "eks" {
source = "./eks"
providers = {
aws = aws.by_region[each.key]
}
// Here we make sure that all resources from a region are removed
// if the region is disabled. This must be done before removing
// a region entirely.
for_each = setsubtract(var.regions, var.disabled_regions)
}
resource "aws_instance" "ec2" {
instance_type = "t3.micro"
provider = aws.by_region[each.key]
// Here we make sure that all resources from a region are removed
// if the region is disabled. This must be done before removing
// a region entirely.
for_each = setsubtract(var.regions, var.disabled_regions)
}
This approach enables you to deploy infrastructure across regions efficiently, again offering all of the benefits of having a DRY configuration.
And so, with [.code]for_each[.code] for providers, scaling across regions becomes significantly simpler and cleaner, saving time and reducing complexity.
Important notes:
- The [.code]for_each [.code] functionality can only be applied to variables and locals that are statically accessible.
- The functionality relies on the Early Evaluation feature introduced in OpenTofu 1.8, so expressions dependent on data sources or resources are not yet supported.
Joining the Testing Effort
OpenTofu 1.9 continues the tradition of making infrastructure management easier and more efficient. Whether you need to exclude specific resources temporarily or streamline multi-region deployments, the new [.code]-exclude[.code] flag and [.code]for_each[.code] for providers are here to help.
Stay tuned for the official release. Meanwhile, visit here to learn about how you can already start testing these and other new features.
The upcoming OpenTofu 1.9 release is packed with features that simplify infrastructure management. The two main highlights of this release are the introduction of the [.code]-exclude[.code] flag and the [.code]for_each[.code] functionality for providers. Both are features that were long-requested by the community.
Let’s dive into these features and see how they can improve your infrastructure management.
The -exclude Flag
The [.code]-exclude[.code] flag introduces a new level of control in deployment processes. Acting as the opposite of the [.code]-target[.code] flag, it allows you to plan and apply everything except specified resources or modules.
Before this feature was introduced, excluding a resource or module required manually targeting every other resource, which was tedious and prone to errors. Now, with the [.code]-exclude [.code] flag, you can focus your deployments while skipping resources or modules effortlessly with a more efficient, DRY (Don’t Repeat Yourself) approach.
The use cases for the [.code]-exclude [.code] flag include:
- Handling drift: When a resource is drifted and requires troubleshooting without blocking other updates.
- Service downtime: When a specific service is temporarily down, but you want to proceed with deploying unaffected resources.
Here is an example of how the [.code]-exclude[.code] flag works:
tofu apply -exclude=aws_vpc.my_vpc
Running this applies all resources except aws_vpc.my_vpc and any dependencies tied to it, acting as a simple and useful time saver.
for_each for Providers
The [.code]for_each[.code] functionality for providers is another step forward in reducing redundant code, especially when working across m
For example, you might have different region setups for your AWS accounts—multiple regions in your dev account and a single region in your production account. Without [.code]for_each[.code] for providers, managing this setup in a single configuration just wasn’t possible.
Instead, you had to define each region separately and use each provider in its own resource or module block, like so:
provider "aws" {
alias = "useast"
region = "us-east-1"
}
provider "aws" {
alias = "uswest"
region = "us-west-1"
}
module "eks-useast" {
source = "./eks"
providers = {
aws = aws.useast
}
}
module "eks-uswest" {
source = "./eks"
providers = {
aws = aws.uswest
}
}
resource "aws_instance" "ec2-useast" {
instance_type = "t3.micro"
provider = aws.useast
}
resource "aws_instance" "ec2-usewest" {
instance_type = "t3.micro"
provider = aws.uswest
}
…
Now, instead of this tedious process, you can simply use [.code]for_each[.code] in the provider block to dynamically create instances with different configurations:
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 = []
}
provider "aws" {
alias = "by_region"
region = each.value
for_each = var.regions
}
module "eks" {
source = "./eks"
providers = {
aws = aws.by_region[each.key]
}
// Here we make sure that all resources from a region are removed
// if the region is disabled. This must be done before removing
// a region entirely.
for_each = setsubtract(var.regions, var.disabled_regions)
}
resource "aws_instance" "ec2" {
instance_type = "t3.micro"
provider = aws.by_region[each.key]
// Here we make sure that all resources from a region are removed
// if the region is disabled. This must be done before removing
// a region entirely.
for_each = setsubtract(var.regions, var.disabled_regions)
}
This approach enables you to deploy infrastructure across regions efficiently, again offering all of the benefits of having a DRY configuration.
And so, with [.code]for_each[.code] for providers, scaling across regions becomes significantly simpler and cleaner, saving time and reducing complexity.
Important notes:
- The [.code]for_each [.code] functionality can only be applied to variables and locals that are statically accessible.
- The functionality relies on the Early Evaluation feature introduced in OpenTofu 1.8, so expressions dependent on data sources or resources are not yet supported.
Joining the Testing Effort
OpenTofu 1.9 continues the tradition of making infrastructure management easier and more efficient. Whether you need to exclude specific resources temporarily or streamline multi-region deployments, the new [.code]-exclude[.code] flag and [.code]for_each[.code] for providers are here to help.
Stay tuned for the official release. Meanwhile, visit here to learn about how you can already start testing these and other new features.