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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With