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
dynamic
keyword. - It contains a
for_each
argument to iterate over a collection. - The
content
block 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_rules
to 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_each
Type: Ensure that thefor_each
argument is a collection (list, map, or set). - Referencing Values: Use
block_name.value
to 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