Bird
Raised Fist0
Terraformcloud~10 mins

Dynamic blocks in security groups in Terraform - Step-by-Step Execution

Choose your learning style10 modes available
Process Flow - Dynamic blocks in security groups
Start Terraform config
↓
Define security group resource
↓
Enter dynamic block for rules
↓
Loop over input list
↓
Create each rule block
↓
Apply config to cloud
↓
Security group with rules created
Terraform reads the security group resource, loops over the input list inside the dynamic block, creates each rule block, and applies the configuration to create the security group with all rules.
Execution Sample
Terraform
resource "aws_security_group" "example" {
  name = "example-sg"

  dynamic "ingress" {
    for_each = var.ingress_rules
    content {
      from_port   = ingress.value.from_port
      to_port     = ingress.value.to_port
      protocol    = ingress.value.protocol
      cidr_blocks = ingress.value.cidr_blocks
    }
  }
}
This Terraform code creates a security group with multiple ingress rules defined dynamically from a list variable.
Process Table
StepActionInputDynamic Block IterationResulting Rule Created
1Start resource creationvar.ingress_rules = [{from_port=80, to_port=80, protocol="tcp", cidr_blocks=["0.0.0.0/0"]}, {from_port=443, to_port=443, protocol="tcp", cidr_blocks=["0.0.0.0/0"]}]N/ANo rules yet
2Enter dynamic blockList has 2 itemsPrepare to loop over 2 itemsNo rules yet
3First iterationFirst item: from_port=80, to_port=80, protocol=tcp, cidr_blocks=["0.0.0.0/0"]1Create ingress rule: port 80 tcp from 0.0.0.0/0
4Second iterationSecond item: from_port=443, to_port=443, protocol=tcp, cidr_blocks=["0.0.0.0/0"]2Create ingress rule: port 443 tcp from 0.0.0.0/0
5Finish dynamic blockAll items processedN/ASecurity group has 2 ingress rules
6Apply configurationTerraform applies resourceN/ASecurity group created with 2 ingress rules
💡 All ingress rules from the input list are processed and created in the security group.
Status Tracker
VariableStartAfter 1After 2Final
var.ingress_rules[2 items][2 items][2 items][2 items]
ingress.valueN/A{from_port=80, to_port=80, protocol=tcp, cidr_blocks=["0.0.0.0/0"]}{from_port=443, to_port=443, protocol=tcp, cidr_blocks=["0.0.0.0/0"]}N/A
security_group.ingress_rules_count0122
Key Moments - 3 Insights
Why does Terraform loop over the list inside the dynamic block?
Terraform uses the dynamic block to create multiple nested blocks based on the list length. Each item in the list becomes one ingress rule block, as shown in execution_table rows 3 and 4.
What happens if the input list is empty?
If the list is empty, the dynamic block creates no ingress rules. The security group will have zero ingress rules, as the loop does not run any iterations.
Can the dynamic block create different types of rules?
Yes, the dynamic block content can use values from each list item to create varied rules. For example, different ports or protocols per item, as seen in the different values in rows 3 and 4.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution table, what is the ingress rule created at step 4?
APort 443 TCP from 0.0.0.0/0
BPort 80 TCP from 0.0.0.0/0
CPort 22 TCP from 0.0.0.0/0
DNo rule created
💡 Hint
Check execution_table row 4 under 'Resulting Rule Created'
At which step does Terraform finish processing all ingress rules?
AStep 3
BStep 5
CStep 4
DStep 6
💡 Hint
Look for the step where 'All items processed' is noted in execution_table
If var.ingress_rules had 3 items instead of 2, how would the execution table change?
AThe dynamic block would create only 2 rules regardless
BTerraform would error out due to too many rules
CThere would be 3 iterations in the dynamic block loop
DThe security group would have zero rules
💡 Hint
Refer to variable_tracker and execution_table showing loop iterations per list item
Concept Snapshot
Terraform dynamic blocks let you create multiple nested blocks from a list.
Use for_each inside dynamic to loop over input data.
Each iteration creates one nested block with values from the list.
This is useful for security groups to define many rules cleanly.
If the list is empty, no blocks are created.
Dynamic blocks keep configs DRY and flexible.
Full Transcript
This visual execution traces how Terraform uses dynamic blocks inside a security group resource. The dynamic block loops over a list variable containing ingress rules. For each item, Terraform creates one ingress block with the specified ports, protocol, and CIDR blocks. The execution table shows step-by-step how each rule is created in order. The variable tracker shows how the loop variable changes each iteration. Key moments clarify why the loop runs and what happens if the list is empty. The quiz tests understanding of the iteration steps and effects of changing the input list. The snapshot summarizes how dynamic blocks simplify creating multiple similar nested blocks in Terraform resources.

Practice

(1/5)
1. What is the main purpose of using dynamic blocks in Terraform security groups?
easy
A. To delete all security group rules at once
B. To manually write each security group rule one by one
C. To encrypt security group rules for security
D. To create multiple similar security group rules from a list automatically

Solution

  1. Step 1: Understand the role of dynamic blocks

    Dynamic blocks allow repeating a block of code multiple times based on a list or map input.
  2. Step 2: Apply this to security groups

    In security groups, dynamic blocks help create many similar rules without writing each rule manually.
  3. Final Answer:

    To create multiple similar security group rules from a list automatically -> Option D
  4. Quick Check:

    Dynamic blocks automate repeated blocks [OK]
Hint: Dynamic blocks repeat code for lists automatically [OK]
Common Mistakes:
  • Thinking dynamic blocks delete rules
  • Believing dynamic blocks encrypt rules
  • Confusing dynamic blocks with manual rule writing
2. Which of the following is the correct syntax to start a dynamic block named ingress in a Terraform security group resource?
easy
A. dynamic ingress {
B. dynamic "ingress" {
C. dynamic ingress() {
D. dynamic "ingress"() {

Solution

  1. Step 1: Recall Terraform dynamic block syntax

    Dynamic blocks use the keyword dynamic followed by the block name in quotes and curly braces.
  2. Step 2: Match syntax for ingress block

    The correct syntax is dynamic "ingress" { to define a dynamic ingress block.
  3. Final Answer:

    dynamic "ingress" { -> Option B
  4. Quick Check:

    Dynamic block name must be in quotes [OK]
Hint: Use quotes around block name in dynamic block [OK]
Common Mistakes:
  • Omitting quotes around block name
  • Adding parentheses after block name
  • Using incorrect keywords
3. Given the following Terraform snippet, what will be the number of ingress rules created?
variable "ports" {
  default = [22, 80, 443]
}

resource "aws_security_group" "example" {
  name = "example-sg"

  dynamic "ingress" {
    for_each = var.ports
    content {
      from_port   = ingress.value
      to_port     = ingress.value
      protocol    = "tcp"
      cidr_blocks = ["0.0.0.0/0"]
    }
  }
}
medium
A. 3 ingress rules, one for each port
B. 1 ingress rule with ports 22, 80, and 443 combined
C. No ingress rules created due to syntax error
D. Ingress rules created only for port 22

Solution

  1. Step 1: Analyze the for_each expression

    The dynamic block uses for_each = var.ports where ports are [22, 80, 443]. This means it loops 3 times.
  2. Step 2: Understand content block creation

    Each iteration creates one ingress rule with from_port and to_port set to the current port value.
  3. Final Answer:

    3 ingress rules, one for each port -> Option A
  4. Quick Check:

    One rule per list item = 3 rules [OK]
Hint: Count list items for number of dynamic blocks created [OK]
Common Mistakes:
  • Thinking all ports combine into one rule
  • Assuming syntax error without checking
  • Ignoring for_each iteration count
4. Identify the error in this Terraform dynamic block for security group ingress rules:
dynamic "ingress" {
  for_each = var.rules
  content {
    from_port   = rule.value.from
    to_port     = rule.value.to
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
}
medium
A. for_each must be a map, not a list
B. Missing quotes around "ingress" in dynamic block
C. Incorrect reference to loop variable; should use ingress.value instead of rule.value
D. cidr_blocks cannot be a list

Solution

  1. Step 1: Check loop variable usage inside dynamic block

    Inside a dynamic block named "ingress", the loop variable is ingress, not rule.
  2. Step 2: Correct variable reference

    References should be ingress.value.from and ingress.value.to to access current item values.
  3. Final Answer:

    Incorrect reference to loop variable; should use ingress.value instead of rule.value -> Option C
  4. Quick Check:

    Loop variable matches dynamic block name [OK]
Hint: Loop variable = dynamic block name [OK]
Common Mistakes:
  • Using wrong loop variable name
  • Omitting quotes around dynamic block name
  • Misunderstanding for_each data types
5. You want to create a security group with dynamic ingress rules from a list of maps, but only include rules where enabled is true. Which Terraform code snippet correctly uses a dynamic block with filtering?
variable "rules" {
  default = [
    { from = 22, to = 22, enabled = true },
    { from = 80, to = 80, enabled = false },
    { from = 443, to = 443, enabled = true }
  ]
}

resource "aws_security_group" "filtered" {
  name = "filtered-sg"

  dynamic "ingress" {
    for_each = ???
    content {
      from_port   = ingress.value.from
      to_port     = ingress.value.to
      protocol    = "tcp"
      cidr_blocks = ["0.0.0.0/0"]
    }
  }
}
hard
A. for_each = [for r in var.rules : r if r.enabled]
B. for_each = var.rules
C. for_each = { for r in var.rules : r.from => r if r.enabled }
D. for_each = filter(var.rules, r => r.enabled)

Solution

  1. Step 1: Understand filtering with for expressions

    Terraform uses for expressions with an if condition to filter lists, e.g. [for r in var.rules : r if r.enabled].
  2. Step 2: Apply filtered list to for_each

    Using this filtered list in for_each creates dynamic blocks only for enabled rules.
  3. Final Answer:

    for_each = [for r in var.rules : r if r.enabled] -> Option A
  4. Quick Check:

    Use for expression with if to filter list [OK]
Hint: Filter list with for expression and if condition [OK]
Common Mistakes:
  • Using unfiltered list causing unwanted rules
  • Trying to use non-existent filter() function
  • Using map instead of list for for_each
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