Bird
Raised Fist0
Terraformcloud~30 mins

Dynamic blocks vs for_each decision in Terraform - Hands-On Comparison

Choose your learning style10 modes available
Dynamic blocks vs for_each decision
📖 Scenario: You are managing cloud infrastructure using Terraform. You need to create multiple security group rules for a virtual network. Some rules are fixed, but others depend on a list of IP addresses that can change. You want to learn how to decide between using dynamic blocks and for_each to manage these rules efficiently.
🎯 Goal: Build a Terraform configuration that creates a security group with fixed rules and additional rules generated dynamically from a list of IP addresses. Learn when to use dynamic blocks versus for_each in Terraform.
📋 What You'll Learn
Create a security group resource with fixed ingress rules
Define a variable list of IP addresses for additional ingress rules
Use a dynamic block to add ingress rules from the IP list
Use for_each to create multiple security group rules from the IP list
Understand the difference between dynamic blocks and for_each in Terraform
💡 Why This Matters
🌍 Real World
Managing cloud security groups often requires adding multiple rules that can change over time. Using dynamic blocks and for_each helps automate and scale these configurations.
💼 Career
Cloud engineers and DevOps professionals use Terraform to manage infrastructure as code. Knowing how to decide between dynamic blocks and for_each is essential for writing clean, maintainable Terraform code.
Progress0 / 4 steps
1
Create a security group with fixed ingress rules
Write a Terraform resource called aws_security_group named example_sg with a fixed ingress rule allowing TCP port 80 from CIDR block 0.0.0.0/0.
Terraform
Hint

Use the resource block with aws_security_group and add an ingress block with the specified port and CIDR.

2
Define a variable list of IP addresses
Create a Terraform variable called extra_ips of type list(string) with the default value ["10.0.0.1/32", "10.0.0.2/32"].
Terraform
Hint

Use the variable block with type = list(string) and set the default list as shown.

3
Add ingress rules using a dynamic block
Inside the aws_security_group.example_sg resource, add a dynamic block named ingress that iterates over var.extra_ips. For each IP, create an ingress rule allowing TCP port 22 from that IP.
Terraform
Hint

Use a dynamic block with for_each = var.extra_ips and inside content, define the ingress rule using ingress.value for the CIDR.

4
Create multiple security group rules using for_each
Create a separate resource aws_security_group_rule named extra_rules that uses for_each = toset(var.extra_ips). For each IP, create an ingress rule allowing TCP port 22 in the security group aws_security_group.example_sg.
Terraform
Hint

Create a separate aws_security_group_rule resource with for_each = toset(var.extra_ips). Use each.key for the CIDR block and link to the security group ID.

Practice

(1/5)
1. Which Terraform feature should you use to repeat a nested block inside a single resource?
easy
A. Dynamic blocks
B. for_each on the resource
C. count on the resource
D. locals block

Solution

  1. Step 1: Understand nested block repetition

    Dynamic blocks are designed to repeat nested blocks inside a single resource.
  2. Step 2: Compare with for_each usage

    for_each repeats entire resources or top-level blocks, not nested blocks.
  3. Final Answer:

    Dynamic blocks -> Option A
  4. Quick Check:

    Nested block repetition = Dynamic blocks [OK]
Hint: Use dynamic blocks for nested repeated settings [OK]
Common Mistakes:
  • Using for_each to repeat nested blocks inside one resource
  • Confusing count with dynamic blocks
  • Trying to use locals for repeating blocks
2. Which syntax correctly uses a dynamic block inside a resource to repeat a nested block named setting?
easy
A. locals { setting = var.settings } resource { setting = local.setting }
B. for_each = var.settings { setting { key = each.value } }
C. count = length(var.settings) setting { key = var.settings[count.index] }
D. dynamic "setting" { for_each = var.settings; content { key = each.value } }

Solution

  1. Step 1: Identify correct dynamic block syntax

    Dynamic blocks use the syntax: dynamic "block_name" { for_each = ... content { ... } }.
  2. Step 2: Check other options for syntax errors

    Options A, B, and C misuse for_each, count, or locals incorrectly for nested blocks.
  3. Final Answer:

    dynamic "setting" { for_each = var.settings; content { key = each.value } } -> Option D
  4. Quick Check:

    Correct dynamic block syntax = dynamic "setting" { for_each = var.settings; content { key = each.value } } [OK]
Hint: Dynamic blocks use dynamic "name" with for_each and content [OK]
Common Mistakes:
  • Placing for_each directly inside resource without dynamic
  • Using count for nested blocks
  • Trying to assign locals directly as blocks
3. Given this Terraform snippet, what will be the number of aws_security_group_rule resources created?
resource "aws_security_group_rule" "example" {
  for_each = { for idx, port in var.ports : idx => port }
  type        = "ingress"
  from_port   = each.value
  to_port     = each.value
  protocol    = "tcp"
  security_group_id = var.sg_id
}
Assuming var.ports = [80, 443].
medium
A. 1 resource
B. 2 resources
C. No resources, syntax error
D. One resource with two ports

Solution

  1. Step 1: Understand for_each on resource

    for_each creates one resource instance per map or set element. Here, var.ports has 2 elements.
  2. Step 2: Count resource instances

    Since var.ports has 2 ports, Terraform creates 2 aws_security_group_rule resources, one for each port.
  3. Final Answer:

    2 resources -> Option B
  4. Quick Check:

    for_each with 2 items = 2 resources [OK]
Hint: for_each creates one resource per item in collection [OK]
Common Mistakes:
  • Thinking for_each creates one resource regardless of items
  • Confusing dynamic blocks with resource repetition
  • Assuming ports combine into one resource
4. This Terraform code throws an error. What is the main issue?
resource "aws_instance" "example" {
  for_each = var.instances
  ami           = "ami-123456"
  instance_type = "t2.micro"

  dynamic "ebs_block_device" {
    for_each = each.value.ebs_volumes
    content {
      device_name = ebs_block_device.value.device_name
      volume_size = ebs_block_device.value.size
    }
  }
}
Assuming var.instances is a map with nested ebs_volumes lists.
medium
A. Dynamic blocks cannot be nested inside resources
B. for_each cannot be used on resources
C. Incorrect reference to dynamic block variable inside content
D. Missing count argument on resource

Solution

  1. Step 1: Identify the error in dynamic block reference

    Inside the content block of a dynamic block, the iterator must be referenced as each.value, not ebs_block_device.value. The iterator variable is always each regardless of the dynamic block name.
  2. Step 2: Confirm the fix

    Change to device_name = each.value.device_name and volume_size = each.value.size. Other options are incorrect: dynamic blocks work inside resources, for_each works on resources, count is not required.
  3. Final Answer:

    Incorrect reference to dynamic block variable inside content -> Option C
  4. Quick Check:

    Dynamic block content uses each.value [OK]
Hint: Inside dynamic content, always use each.value, not block_name.value [OK]
Common Mistakes:
  • Using block_name.value inside dynamic block content instead of each.value
  • Trying to use for_each on resource incorrectly
  • Forgetting to define for_each on dynamic block
5. You want to create multiple AWS IAM users, each with multiple inline policies. Which Terraform approach is best to manage this efficiently? A snippet of your variables:
variable "users" {
  type = map(object({
    policies = list(object({
      name   = string
      policy = string
    }))
  }))
}
hard
A. Use for_each on aws_iam_user for users, and for_each on aws_iam_user_policy for policies
B. Use count on aws_iam_user for users, and for_each on aws_iam_user_policy for policies
C. Use for_each on aws_iam_user resource for users, and dynamic blocks inside aws_iam_user_policy for policies
D. Use dynamic blocks on aws_iam_user resource for users, and count on aws_iam_user_policy for policies

Solution

  1. Step 1: Manage multiple users

    Use for_each on aws_iam_user resource to create one user per map entry.
  2. Step 2: Manage multiple policies per user

    Since policies are separate resources (aws_iam_user_policy), use for_each on that resource to create one policy per user-policy pair.
  3. Step 3: Why not dynamic blocks here?

    Dynamic blocks repeat nested blocks inside a resource, but aws_iam_user_policy is a separate resource, so for_each is appropriate.
  4. Final Answer:

    Use for_each on aws_iam_user for users, and for_each on aws_iam_user_policy for policies -> Option A
  5. Quick Check:

    Multiple resources = for_each on both [OK]
Hint: Use for_each for multiple resources, dynamic blocks for nested blocks [OK]
Common Mistakes:
  • Using dynamic blocks to create multiple resources
  • Using count instead of for_each for maps
  • Trying to nest policies inside user resource with dynamic blocks
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard