Local variable will be known only after apply


I need to create some static routes for vpc attachment. I have a module with these properties :

vpc_attachments = {
    vpc_digital_factory = {
      tgw_id                                          = var.tgw_id //data.tfe_outputs.tgw.values.ec2_transit_gateway_id
      vpc_id                                          = module.vpc.vpc_id
      subnet_ids                                      = module.vpc.private_subnets
      vpc_route_table_ids                             = data.aws_route_tables.this.ids
      tgw_destination_cidr                            = var.tgw_destination_cidr
      dns_support                                     = true
      ipv6_support                                    = false
      transit_gateway_default_route_table_association = false
      transit_gateway_default_route_table_propagation = false
      appliance_mode_support                          = true


I use a local variable to setup a specific list of properties for aws_route resources :

 vpc_route_table_destination_cidr = !var.create_tgw ? flatten([
    for k, v in var.vpc_attachments : [
      for rtb_id in try(v.vpc_route_table_ids, []) : [
        for dest_cidr in try(v.tgw_destination_cidr, []) : {
        rtb_id = rtb_id
        cidr   = dest_cidr
        tgw_id = v.tgw_id
        id = "${rtb_id}-${dest_cidr}"
  ]) : flatten([])
resource "aws_route" "this" {
  for_each = { for x in local.vpc_route_table_destination_cidr : x.id => x if !var.create_tgw  } 

  route_table_id         = each.value["rtb_id"]
  destination_cidr_block = each.value["cidr"]
  transit_gateway_id     = var.create_tgw ? aws_ec2_transit_gateway.this[0].id : each.value["tgw_id"]

I’m facing to this issue :

Error: Invalid for_each argument
│   on ../../../../modules/terraform-aws-transit-gateway/main.tf line 144, in resource "aws_route" "this":
│  144:   for_each = { for x in local.vpc_route_table_destination_cidr : x.id => x if !var.create_tgw  } 
│     ├────────────────
│     │ local.vpc_route_table_destination_cidr will be known only after apply
│     │ var.create_tgw is false
│ The "for_each" map includes keys derived from resource attributes that cannot be determined until apply, and so Terraform cannot determine the full set of keys that will identify the instances of this resource.
│ When working with unknown values in for_each, it's better to define the map keys statically in your configuration and place apply-time results only in the map values.
│ Alternatively, you could use the -target planning option to first apply only the resources that the for_each value depends on, and then apply a second time to fully converge.

I don’t know how fix it. Sure if var.create_tgw is true, there is no issue. And in the second time I launch a plan with var.create_tgw = false, that works but it is not ideal way to do.

Thanks for your support in advance.


It is a fundamental consequence of Terraform’s plan/apply architecture, that it needs to be able to figure out exactly what things it will be creating (plan) before any part of the apply starts.

It looks like some part of your

involves something that can’t be computed until apply time.

Not enough of your configuration is shown above to investigate further.