Vinita Shah
Vinita Shah

Reputation: 129

Terraform to have a for_each and dynamic block in the same resource? Or can I have multiple for_each in a resource statement

Can I have a for_each and dynamic block in the same resource statement ? Or can I have multiple for_each in a resource statement /// Creating 2 EC2 instances ///

resource "aws_instance" "ABC" {
  count = 2
  ami           = var.AMIX
  instance_type = "t3.small"
  subnet_id = xxx
  vpc_security_group_ids = [data.aws_security_group.SG.id]
  key_name = var.AMIX-KEY
  tags = {
    Name = abc)
  }
}

/// Creating local dict with subnet name and subnet id /// This has 2 subnets for ec2 instance 1 and 2 subnets for ec2 instance 2

locals {
# With List 
  subnets = flatten([
    for subnet_details in aws_subnet.SUBNET : {
      subnet_name = subnet_details.tags.Name,
      subnet_id = subnet_details.id
      } if contains(["abc", "xyz"], subnet_details.tags.Name)
  ])
}

/// Local subnets output.

 dev = [
      + {
          + subnet_id    = "A"
          + subnet_name  = "DEV1"
        },
      + {
          + subnet_id    = "B"
          + subnet_name  = "DEV1"
        },
      + {
          + subnet_id    = "C"
          + subnet_name  = "DEV2"
        },
      + {
          + subnet_id    = "D"
          + subnet_name  = "DEV2"
        },
    ]

/// How to attach EC2 instances with Network Interfaces ??? Loop two times in attachment as I need to tie two ec2 instances depending on the subnet_name 2 subnets get ec2-1 and 2 subnets get ec2-2 and based on that they will get the device_index ///

resource "aws_network_interface" "NICS" {
  for_each = {
    for subnet_id, subnet_name in local.subnets : subnet_id => subnet_name
  }
  subnet_id = each.value.subnet_id
  security_groups = [data.aws_security_group.SG.id]
  tags = {
    Name = each.value.subnet_name
  }
  attachment {
  instance = ?
  device_index = 1
  } 
}

Upvotes: 1

Views: 1525

Answers (1)

Marcin
Marcin

Reputation: 238877

What about the following version of your code. I haven't run the code, but but you can consider the idea behind it:

variable "instance_name" {
  default = ["Y", "Z"]
}

resource "aws_instance" "ABC" {

  for_each = var.instance_name

  ami           = var.AMIX
  instance_type = "t3.small"
  subnet_id = xxx
  vpc_security_group_ids = [data.aws_security_group.SG.id]
  key_name = var.AMIX-KEY

  tags = {
    Name = each.key
  }
}

Then, you would create four NICs based on local.subnets when you also specify instance name. Also I would separate creation of NICs from their attachments using aws_network_interface_attachment:

locals {

  subnets = [
       {
           subnet_id    = "A"
           subnet_name  = "DEV1"
           instance_name = "Y"
        },
       {
           subnet_id    = "B"
           subnet_name  = "DEV1"
           instance_name = "Y"           
        },
       {
           subnet_id    = "C"
           subnet_name  = "DEV2"
           instance_name = "Z"                      
        },
       {
           subnet_id    = "D"
           subnet_name  = "DEV2"
           instance_name = "Z"                                 
        }
    ]
}


resource "aws_network_interface" "NICS" {
  
  for_each = {for subnet in local.subnets : (subnet.subnet_name) => subnet}

  subnet_id       = each.value.subnet_id
  security_groups = [data.aws_security_group.SG.id]

  tags = {
    Name = each.value.subnet_name
  }
}

resource "aws_network_interface_attachment" "test" {

  for_each = {for subnet in local.subnets : (subnet.subnet_name) => subnet}

  instance_id          = aws_instance.ABC[each.value.instance_name].id
  network_interface_id = aws_network_interface.NICS[each.key].id
  device_index         = 0
}

Upvotes: 1

Related Questions