skip to Main Content

I’ve got a terraform plan that creates a number of resources in a for_each loop, and I need another resource to depend_on those first ones. How can I do it without having to explicitly list them?

Here’s the first resource (AWS API Gateway resource):

locals {
  apps = toset(["app1", "app2", "app3"])
}

resource "aws_api_gateway_integration" "lambda" {
  for_each                = local.apps 
  rest_api_id             = aws_api_gateway_rest_api.primary.id
  resource_id             = aws_api_gateway_resource.lambda[each.key].id
  http_method             = aws_api_gateway_method.lambda_post[each.key].http_method
  integration_http_method = "POST"
  type                    = "AWS_PROXY"
  uri                     = aws_lambda_function.lambda[each.key].invoke_arn
}

Now I need to wait for all the 3 apps integrations before creating an API Gateway deployment:

resource "aws_api_gateway_deployment" "primary" {
  rest_api_id = aws_api_gateway_rest_api.primary.id

  depends_on = [
    aws_api_gateway_integration.lambda["app1"],
    aws_api_gateway_integration.lambda["app2"],
    aws_api_gateway_integration.lambda["app3"],
  ]

However the list of apps keeps growing and I don’t want to maintain it manually over here. Everywhere else I can simply use for or for_each together with local.apps but I can’t figure out how to dynamically build the list for depends_on? Any ideas?

3

Answers


  1. You have to do it manually. TF docs clearly explain that depends_on must be explicitly defined:

    You only need to explicitly specify a dependency

    Login or Signup to reply.
  2. There is another way:

    • Create a module with for_each approach called aws_api_gateway_integration

    • Modify module to support all parameters needed

    • Then you can just call new objects to create – exampleenter image description here

    • At the end you can put depends_on on a module – depends_on = [
      module.logic_app
      ]

    Login or Signup to reply.
  3. Dependencies in Terraform are always between static blocks (resource, data, and module blocks mainly) and not between individual instances of those objects.

    Therefore listing individual instances like you did in your example is redundant:

      depends_on = [
        aws_api_gateway_integration.lambda["app1"],
        aws_api_gateway_integration.lambda["app2"],
        aws_api_gateway_integration.lambda["app3"],
      ]
    

    The above is exactly equivalent to declaring a dependency on the resource as a whole:

      depends_on = [
        aws_api_gateway_integration.lambda,
      ]
    

    The for_each argument itself typically has its own dependencies (e.g. local.apps in your example) and so Terraform needs to construct the dependency graph before evaluating for_each. This means that there is only one node in the dependency graph representing the entire resource (including its for_each expression), and the individual instances are not represented in the plan-time dependency graph at all.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search