Dynamic blocks in Terraform allow you to generate multiple nested blocks within a resource or module dynamically. This feature is particularly useful when you need to create a variable number of nested blocks based on input variables or other dynamic data.
Key Concepts
-
Dynamic Block Structure:
- A dynamic block is defined using the
dynamickeyword. - It contains a
for_eachargument to iterate over a collection. - The
contentblock defines the structure of the nested blocks to be generated.
- A dynamic block is defined using the
-
Use Cases:
- Creating multiple sub-resources within a resource.
- Generating configuration blocks based on variable input.
Syntax
The basic syntax for a dynamic block is as follows:
resource "resource_type" "resource_name" {
# Other resource arguments
dynamic "block_name" {
for_each = var.collection
content {
# Nested block arguments
argument1 = block_name.value.argument1
argument2 = block_name.value.argument2
}
}
}block_name: The name of the nested block to be generated.for_each: The collection to iterate over.content: The structure of the nested block.
Practical Example
Let's consider an example where we need to create multiple security group rules for an AWS security group. The rules are defined in a variable.
Variable Definition
First, define a variable to hold the security group rules:
variable "security_group_rules" {
description = "List of security group rules"
type = list(object({
type = string
from_port = number
to_port = number
protocol = string
cidr_blocks = list(string)
}))
default = []
}Resource Definition with Dynamic Block
Next, use a dynamic block to create the security group rules:
resource "aws_security_group" "example" {
name = "example"
description = "Example security group"
vpc_id = var.vpc_id
dynamic "ingress" {
for_each = var.security_group_rules
content {
from_port = ingress.value.from_port
to_port = ingress.value.to_port
protocol = ingress.value.protocol
cidr_blocks = ingress.value.cidr_blocks
}
}
}Example Variable Values
Provide values for the security_group_rules variable:
variable "security_group_rules" {
default = [
{
type = "ingress"
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
},
{
type = "ingress"
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
]
}Practical Exercise
Exercise
- Define a variable
firewall_rulesto hold a list of firewall rules. - Create a Google Cloud Platform (GCP) firewall resource using a dynamic block to generate the rules.
Solution
Variable Definition
variable "firewall_rules" {
description = "List of firewall rules"
type = list(object({
name = string
direction = string
priority = number
ranges = list(string)
allow_ports = list(object({
protocol = string
ports = list(string)
}))
}))
default = []
}Resource Definition with Dynamic Block
resource "google_compute_firewall" "example" {
name = "example-firewall"
network = var.network
dynamic "allow" {
for_each = var.firewall_rules
content {
protocol = allow.value.allow_ports[0].protocol
ports = allow.value.allow_ports[0].ports
}
}
source_ranges = var.firewall_rules[0].ranges
direction = var.firewall_rules[0].direction
priority = var.firewall_rules[0].priority
}Example Variable Values
variable "firewall_rules" {
default = [
{
name = "allow-http"
direction = "INGRESS"
priority = 1000
ranges = ["0.0.0.0/0"]
allow_ports = [
{
protocol = "tcp"
ports = ["80"]
}
]
},
{
name = "allow-https"
direction = "INGRESS"
priority = 1000
ranges = ["0.0.0.0/0"]
allow_ports = [
{
protocol = "tcp"
ports = ["443"]
}
]
}
]
}Common Mistakes and Tips
- Incorrect
for_eachType: Ensure that thefor_eachargument is a collection (list, map, or set). - Referencing Values: Use
block_name.valueto reference the current item in the collection. - Nested Blocks: Dynamic blocks can be nested within other dynamic blocks if needed.
Conclusion
Dynamic blocks in Terraform provide a powerful way to generate multiple nested blocks based on dynamic data. By understanding and utilizing dynamic blocks, you can create more flexible and reusable Terraform configurations. In the next section, we will explore Terraform Import, which allows you to import existing infrastructure into your Terraform state.
Terraform Course
Module 1: Introduction to Terraform
Module 2: Terraform Configuration Language
Module 3: State Management
Module 4: Terraform Modules
Module 5: Provisioning Resources
- Provisioning Basics
- Provisioning AWS Resources
- Provisioning Azure Resources
- Provisioning GCP Resources
Module 6: Advanced Terraform Features
Module 7: Terraform Best Practices
Module 8: Terraform in CI/CD
- Integrating Terraform with CI/CD
- Automating Terraform with Jenkins
- Using Terraform with GitHub Actions
- Terraform Cloud and Enterprise
