Learn how to use conditional logic in Terraform to dynamically create a module only when certain conditions are met, optimizing your infrastructure provisioning workflow.
This document outlines a pattern for conditionally creating Terraform modules using variables and the for_each
meta-argument. This approach provides flexibility in your infrastructure deployments by allowing you to control module instantiation based on input variables. The example demonstrates a simple scenario with a boolean variable, but the concept can be extended to more complex conditions and multiple modules.
Define a variable for your condition:
variable "create_module" {
type = bool
default = false
}
Use the for_each
meta-argument on the module
block:
module "my_module" {
source = "./my_module"
# ... other module inputs ...
for_each = var.create_module ? { "enabled" = true } : {}
}
Access module outputs conditionally:
output "module_output" {
value = try(module.my_module.some_output, null)
}
Explanation:
for_each
argument creates an instance of the module for each key in the map.var.create_module
is true, otherwise an empty map.try()
function handles cases where the module is not created and prevents errors when accessing outputs.This Terraform code defines a module named "my_module" that can be conditionally created based on the value of a boolean variable "create_module". The "for_each" meta-argument in the module block uses a conditional expression to control module instantiation. If "create_module" is true, the module is created and its output "some_output" is accessible. Otherwise, the module is not created and the output defaults to null. This allows for flexible and dynamic infrastructure provisioning based on user-defined conditions.
This example demonstrates how to conditionally create a module based on a variable.
main.tf:
# Define a variable to control module creation
variable "create_module" {
type = bool
default = false
}
# Define the module block with conditional for_each
module "my_module" {
source = "./my_module"
# ... other module inputs ...
# Conditionally create the module
for_each = var.create_module ? { "enabled" = true } : {}
}
# Access module outputs conditionally
output "module_output" {
value = try(module.my_module.enabled.some_output, null)
}
my_module/variables.tf:
variable "some_input" {
type = string
}
my_module/outputs.tf:
output "some_output" {
value = var.some_input
}
Explanation:
create_module
variable determines whether the module should be created.for_each
: The for_each
meta-argument on the module
block uses a conditional expression. If create_module
is true, it creates a map with a single key "enabled". Otherwise, it creates an empty map.for_each
map. If the map is empty (when create_module
is false), no module instance is created. If the map has the "enabled" key, a single instance of the module is created.try()
function in the output
block handles cases where the module is not created. If the module exists, it retrieves the some_output
value. Otherwise, it returns null
, preventing errors.To use this example:
main.tf
, my_module/variables.tf
, and my_module/outputs.tf
with the code above.terraform init
to initialize the working directory.terraform apply
to create the infrastructure. By default, the module will not be created.create_module
variable to true
in your Terraform configuration or using the command line: terraform apply -var 'create_module=true'
.terraform destroy
to destroy the infrastructure when you are finished.for_each
: While for_each
is the recommended approach for conditional module creation in Terraform 0.13 and above, you can achieve similar results using count
with conditional expressions in earlier versions. However, this approach can be less readable and maintainable.create_module
in this case) should be defined in a scope accessible to both the module definition and the location where you are calling the module.try()
function is crucial for gracefully handling cases where the module is not created. Without it, attempting to access outputs from a non-existent module would result in errors.for_each
meta-argument to create modules based on multiple variables or logical operations.for_each
. For example, you could use a map of resource names to create a module instance for each resource.This document outlines a pattern for conditionally creating Terraform modules based on a variable.
Steps:
Define a Boolean Variable:
create_module
) to control module creation. Set its default to false
.Use for_each
with a Conditional Expression:
module
block, utilize the for_each
meta-argument.{"enabled": true}
) if the variable is true, or an empty map ({}
) otherwise.Access Outputs Conditionally:
try()
function to gracefully handle cases where the module wasn't created due to the condition being false.How it Works:
for_each
dynamically creates module instances based on the provided map.try()
prevents errors when accessing outputs of a potentially non-existent module.Benefits:
By combining variables, the for_each
meta-argument, and the try()
function, Terraform users can implement conditional module creation, enhancing the flexibility and control over infrastructure deployments. This approach allows for modules to be included or excluded based on specific conditions, leading to more efficient and adaptable infrastructure as code configurations.