Home > Mobile >  Dynamically getting values from Terraform output and pass them by index
Dynamically getting values from Terraform output and pass them by index

Time:01-13

Terraform greenhorn here. I want to output and dynamically add only the first 2 subnets in the vpc_zone_identifier below. But I can't get it by index, is asking for a name.

vpc_zone_identifier = [module.subnet[0].subnet_id, module.subnet[1].subnet_id]

Here is what I tried.

Any suggestion is appreciated.

resource "aws_subnet" "this" {
  vpc_id     = var.vpc_id
  cidr_block = var.cidr_block_subnet
  map_public_ip_on_launch = var.map_public_ip_on_launch
  tags = var.tags
}
module "subnet" {
  source = "./aws_modules/subnet"
  for_each = {for key, value in var.subnet_settings: value.cidr_block_subnet => value}
  
  vpc_id                  = module.vpc.vpc_id
  cidr_block_subnet       = each.key
  map_public_ip_on_launch = each.value.map_public_ip_on_launch
  tags                    = var.tags

  depends_on = [module.vpc]
}
variable "subnet_settings" {
     type = list(object({
        cidr_block_subnet       = string
        map_public_ip_on_launch = bool
     }))
}
subnet_settings = [
  {
    cidr_block_subnet       = "10.1.1.0/24"
    map_public_ip_on_launch = false
  },
    {
    cidr_block_subnet       = "10.1.2.0/24"
    map_public_ip_on_launch = false
  },
    {
    cidr_block_subnet       = "10.1.3.0/24"
    map_public_ip_on_launch = false
  }
]
output "subnet_id" {
 value = aws_subnet.this.id
}
resource "aws_autoscaling_group" "autosys" {
  desired_capacity    = var.node-count
  max_size            = var.node-count
  min_size            = var.node-count
  name                = var.asg-name
  vpc_zone_identifier = [module.subnet[0].subnet_id, module.subnet[1].subnet_id]
  launch_template {
    id      = aws_launch_template.autosys.id
    version = "$Latest"
  }
}

CodePudding user response:

In a for expression, you can initialize two variables within the scope of the lambda when iterating on a list type. In this situation, the first variable will be assigned the index of the iteration. Therefore, we can modify the for_each meta-argument of your module:

module "subnet" {
  source = "./aws_modules/subnet"
  for_each = {for idx, subnet in var.subnet_settings: idx => subnet}

  vpc_id                  = module.vpc.vpc_id
  cidr_block_subnet       = each.value.cidr_block_subnet
  map_public_ip_on_launch = each.value.map_public_ip_on_launch
  tags                    = var.tags

  depends_on = [module.vpc]
}

and now the module key will be the index of the var.subnet_settings. Correspondingly, the module output namespace will now be module.<declared_name>["<index>"].<output_name>. Therefore, we can modify the value for the vpc_zone_identifier argument to have keys of string type instead of number type:

vpc_zone_identifier = [module.subnet["0"].subnet_id, module.subnet["1"].subnet_id]

and now the passed value to the argument will be the first two subnets as desired.

  •  Tags:  
  • Related