Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I add dependency on `aws_apigatewayv2_stage` for `aws_apigatewayv2_route` in Terraform?

I have terraform setting as below:

resource "aws_apigatewayv2_route" "signup_route" {
  api_id    = "${aws_apigatewayv2_api.signup_redirect.id}"
  route_key = "POST /signup"
  target    = "integrations/${aws_apigatewayv2_integration.lambda_integration.id}"
}

resource "aws_apigatewayv2_stage" "staging_stage" {
  api_id      = "${aws_apigatewayv2_api.signup_redirect.id}"
  name        = "staging"
  auto_deploy = true
  route_settings {
    route_key                = "POST /signup"
    logging_level            = "INFO"
    detailed_metrics_enabled = true
  }
}

I got below error when deploying:

Error: error creating API Gateway v2 stage: NotFoundException: Unable to find Route by key POST /signup within the provided RouteSettings

It seems that the stage was deployed before the route was created. How can I add a dependency on stage to depend on route?

like image 710
Joey Yi Zhao Avatar asked Oct 21 '25 16:10

Joey Yi Zhao


1 Answers

The best way to create dependencies in Terraform is to write references to the resources you want to depend on. In this case, that might look like this:

resource "aws_apigatewayv2_route" "signup_route" {
  api_id    = "${aws_apigatewayv2_api.signup_redirect.id}"
  route_key = "POST /signup"
  target    = "integrations/${aws_apigatewayv2_integration.lambda_integration.id}"
}

resource "aws_apigatewayv2_stage" "staging_stage" {
  api_id      = aws_apigatewayv2_api.signup_redirect.id
  name        = "staging"
  auto_deploy = true
  route_settings {
    route_key                = aws_apigatewayv2_route.signup_route.route_key
    logging_level            = "INFO"
    detailed_metrics_enabled = true
  }
}

Because the route_key in route_settings refers to aws_apigatewayv2_route.signup_route, Terraform will see this as a dependency on that resource. Letting dependencies be implied like this is nice because it allows you to focus on describing how data propagates from one resource to another, and if you later remove this route_settings block then the dependency it implies would be automatically removed without you needing to remember to update some other declaration.

However, in some cases the design of an underlying system makes this sort of explicit data-flow dependency impossible. One example of this is AWS IAM roles, where the policies attached to the role are separate from the role itself and so the natural dataflow-inferred dependency relationship is that both the policy and the object that will assume the role depend on the role, and the object assuming the role doesn't naturally depend on the policy. In that case we tend to need to add additional explicit dependencies depends_on to ensure that the system doesn't try to assume the role before it has had its policies applied:

resource "aws_iam_role" "for_lambda" {
  name = "lambda_function"

  assume_role_policy = jsonencode({
    "Version": "2012-10-17",
    "Statement": [
      {
        "Action": "sts:AssumeRole",
        "Principal": {
          "Service": "lambda.amazonaws.com"
        },
        "Effect": "Allow",
        "Sid": ""
      }
    ]
  })
}

resource "aws_iam_role_policy" "for_lambda" {
  # (policy that the lambda function needs to do its work)
}

resource "aws_lambda_function" "example" {
  name = "example"
  # ...

  # This reference makes the function depend on the role,
  # but the role isn't ready to use until the associated
  # policy has been attached to it too.
  role = aws_iam_role.for_lambda.arn

  # ...so we need to explicitly declare this hidden dependency:
  depends_on = [aws_iam_role_policy.for_lambda]
}

There's more information on how dependencies work in Terraform in Resource Dependencies.

like image 147
Martin Atkins Avatar answered Oct 24 '25 05:10

Martin Atkins



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!