📖 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
Step 1: Understand nested block repetition
Dynamic blocks are designed to repeat nested blocks inside a single resource.
Step 2: Compare with for_each usage
for_each repeats entire resources or top-level blocks, not nested blocks.
Final Answer:
Dynamic blocks -> Option A
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?
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
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.
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.
Final Answer:
Incorrect reference to dynamic block variable inside content -> Option C
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
Step 1: Manage multiple users
Use for_each on aws_iam_user resource to create one user per map entry.
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.
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.
Final Answer:
Use for_each on aws_iam_user for users, and for_each on aws_iam_user_policy for policies -> Option A
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 unknownstrongwhile earning +1 Grip toward your certificate.