Terraform's NotFoundException error when creating API Gateway resources typically occurs when you're trying to reference a REST API that doesn't exist yet, have missing dependencies, or are experiencing a race condition. Resolve it by adding explicit dependencies, using proper resource references, and ensuring your state is synchronized.
When Terraform attempts to create API Gateway resources (methods, integrations, deployments, or stages), it may fail with a NotFoundException if it tries to access a parent resource that doesn't exist or hasn't been fully provisioned yet. This happens most commonly when: 1. A child resource is created before its parent REST API is fully available 2. Resource references are incorrect or point to non-existent resources 3. Terraform's implicit dependency detection fails, causing out-of-order provisioning 4. Terraform state is out of sync with actual AWS resources 5. There's a race condition between resource creation and access The error can reference different missing resources: `aws_api_gateway_rest_api`, `aws_api_gateway_resource`, `aws_api_gateway_method`, or other API Gateway components.
Most API Gateway NotFoundException errors occur because Terraform tries to create resources in the wrong order. Add explicit depends_on blocks to enforce proper sequencing:
resource "aws_api_gateway_rest_api" "example" {
name = "my-api"
description = "My REST API"
}
resource "aws_api_gateway_resource" "example" {
rest_api_id = aws_api_gateway_rest_api.example.id
parent_id = aws_api_gateway_rest_api.example.root_resource_id
path_part = "users"
}
resource "aws_api_gateway_method" "example" {
rest_api_id = aws_api_gateway_rest_api.example.id
resource_id = aws_api_gateway_resource.example.id
http_method = "GET"
authorization = "NONE"
depends_on = [aws_api_gateway_resource.example]
}
resource "aws_api_gateway_integration" "example" {
rest_api_id = aws_api_gateway_rest_api.example.id
resource_id = aws_api_gateway_resource.example.id
http_method = aws_api_gateway_method.example.http_method
type = "HTTP"
uri = "https://example.com"
depends_on = [aws_api_gateway_method.example]
}
resource "aws_api_gateway_deployment" "example" {
rest_api_id = aws_api_gateway_rest_api.example.id
stage_name = "prod"
depends_on = [aws_api_gateway_integration.example]
}Notice how each resource explicitly declares its dependencies. This ensures Terraform creates them in the correct order.
Check that all resource ID references are pointing to the correct resources. The most common mistake is using hardcoded IDs instead of Terraform references:
Wrong (hardcoded):
resource "aws_api_gateway_method" "example" {
rest_api_id = "abc123def456" # BAD: hardcoded ID
resource_id = "xyz789"
# ...
}Correct (Terraform references):
resource "aws_api_gateway_method" "example" {
rest_api_id = aws_api_gateway_rest_api.example.id # GOOD
resource_id = aws_api_gateway_resource.example.id
# ...
}Make sure:
- rest_api_id references the actual aws_api_gateway_rest_api resource
- resource_id references an aws_api_gateway_resource that exists
- parent_id correctly references the parent resource's ID
- All references use the correct resource type and attribute (usually .id)
If your error persists, your Terraform state may be out of sync with actual AWS resources. Refresh the state:
terraform refreshThis updates your local state file to match the actual resources in AWS. If the state is severely corrupted or if you need to start fresh:
# Remove the problematic resource from state
terraform state rm aws_api_gateway_rest_api.example
# Then re-import it from AWS
terraform import aws_api_gateway_rest_api.example /restapis/abc123def456You can find the REST API ID in the AWS Console under API Gateway, or via the CLI:
aws apigateway get-rest-apis --region us-east-1For API Gateway deployments, use the triggers argument to ensure redeployment when underlying resources change:
resource "aws_api_gateway_deployment" "example" {
rest_api_id = aws_api_gateway_rest_api.example.id
stage_name = "prod"
triggers = {
redeployment = sha1(jsonencode(aws_api_gateway_rest_api.example.body))
}
lifecycle {
create_before_destroy = true
}
depends_on = [aws_api_gateway_integration.example]
}The sha1 hash ensures that Terraform detects changes to the API definition and redeploys. The create_before_destroy lifecycle rule prevents temporary downtime.
Ensure all your API Gateway resources are being created in the same AWS region. Mismatched regions can cause NotFoundException:
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = "us-east-1" # Ensure all resources use this region
}
# All resources below will use us-east-1
resource "aws_api_gateway_rest_api" "example" {
name = "my-api"
# region is inherited from provider
}If you're managing multiple regions, explicitly set the provider for each resource:
resource "aws_api_gateway_rest_api" "example" {
provider = aws.us_east_1
name = "my-api"
}Always run terraform plan before terraform apply to preview resource creation order:
terraform plan -out=plan.tfplanReview the output to ensure resources are created in the expected order:
- REST API should be created first
- Resources should be created second
- Methods should be created third
- Integrations and deployments last
If the order looks wrong, add more explicit depends_on blocks. Then apply:
terraform apply plan.tfplanWhy explicit dependencies matter in API Gateway: AWS API Gateway has complex internal dependencies. While Terraform can infer some implicit dependencies through resource references, it cannot always detect all relationships, especially between deployments and their underlying resources. This is why explicit depends_on blocks are crucial.
Deployment lifecycle: API Gateway deployments are uniqueβthey capture a snapshot of your API configuration at a point in time. If you modify methods, integrations, or resources after deployment, you must create a new deployment. Using triggers with a hash of the API definition ensures Terraform detects these changes automatically.
State file importance: API Gateway resources are complex and stateful. A corrupted or out-of-sync state file is a common source of NotFoundException errors. Always use a remote state backend (S3 + DynamoDB, Terraform Cloud, etc.) in production, never local state. This prevents state corruption and enables team collaboration.
Cross-module dependencies: If your API Gateway resources are split across multiple Terraform modules, ensure modules are explicitly ordered using depends_on at the root module level, not just within modules. Intra-module dependencies work reliably, but cross-module dependencies sometimes fail without explicit declaration.
API Gateway edge cases: Some API Gateway operations (like stage creation) can be slow to propagate through AWS's distributed system. If you're hitting race conditions even with depends_on, consider adding a small delay using null_resource with a local-exec provisioner, though this is a last resort.
Error: Error rendering template: template not found
How to fix "template not found" error in Terraform
Error: Error generating private key
How to fix 'Error generating private key' in Terraform
Error creating Kubernetes Service: field is immutable
How to fix "field is immutable" errors in Terraform
Error: Error creating local file: open: permission denied
How to fix "Error creating local file: permission denied" in Terraform
Error: line endings have changed from CRLF to LF
Line endings have changed from CRLF to LF in Terraform