Terraform - is local ran before or during the resource call

Viewed 422

For terraform, resource, is the local ran after or before the resource is called?

The reason being, when my local is ran in the below code, not all the resources in the aws_vpn_connection.VPN-CONN are ready, so my tga_vpn is not complete, and thereby, not all resources are created in aws_ec2_transit_gateway_route_table_propagation resource

I have to run terraform apply again to add the remaining resources.

locals {
  tga_vpn = flatten([
    for vpn_conn in aws_vpn_connection.VPN-CONN: 
    .
    . 
])
}
resource "aws_ec2_transit_gateway_route_table_propagation" "TGW-RT-PROP" {
  count = length(local.tga_vpn)
  something1 = lookup(local.tga_vpn[count.index], "id1", null)
  something2 = lookup(local.tga_vpn[count.index], "id2", null)
} 

I also added depends on aws_vpn_connection in the aws_ec2_transit_gateway_route_table_propagation resource, but that did not help.

Or is there a way to add depends_on for local?

Thank you

2 Answers

In the Terraform language itself, each local value is itself a node in the dependency graph and so your resource's references to local.tga_vpn already tell Terraform that aws_ec2_transit_gateway_route_table_propagation.TGW-RT-PROP depends on everything that local.tga_vpn depends on. Likewise, the local value refers to aws_vpn_connection.VPN-CONN and so the chain of dependencies here is:

  • aws_vpn_connection.VPN-CONN might have some other dependencies, but we can't see those in your partial example
  • local.tga_vpn depends on aws_vpn_connection.VPN-CONN
  • aws_ec2_transit_gateway_route_table_propagation.TGW-RT-PROP depends on local.tga_vpn.

Given this, if you are seeing the actions for aws_ec2_transit_gateway_route_table_propagation.TGW-RT-PROP happen before the actions for aws_vpn_connection.VPN-CONN are complete then unfortunately that suggests a problem either in the AWS provider or in the remote AWS API. Despite the AWS provider's efforts to work around a lot of cases, some objects in the AWS API are "eventually consistent", meaning that there isn't a guarantee that you can write a new object and then immediately try to use it. Instead, the change might take some time to be fully visible to all other parts of AWS, because AWS is a distributed system.

In that sort of situation, if the AWS API offers no way to explicitly determine when an object is actually fully proagated then unfortunately we are forced to use workarounds such as the time_sleep resource type that Marcin described, which doesn't actually solve the problem but it at least makes it less likely to occur by giving longer for the remote system to achieve consistency than would be true if Terraform just naturally began working on the downstream object immediately when its dependencies became ready.

If you know roughly how long it takes for the aws_vpn_connection to be fully initialized and ready to use after its creation, you can use time_sleep resource to delay execution of your aws_ec2_transit_gateway_route_table_propagation.

For example, assuming it takes 30 seconds, you could do:

resource "time_sleep" "wait_30_seconds" {
  depends_on = [aws_vpn_connection.VPN-CONN]

  create_duration = "30s"
}

resource "aws_ec2_transit_gateway_route_table_propagation" "TGW-RT-PROP" {
  count = length(local.tga_vpn)
  something1 = lookup(local.tga_vpn[count.index], "id1", null)
  something2 = lookup(local.tga_vpn[count.index], "id2", null)

  depends_on = [time_sleep.wait_30_seconds]
} 

Related