# API Gateway REST API resource "aws_api_gateway_rest_api" "api" { name = "${var.app_name}-api" description = "API for ${var.app_name}" } # API Gateway Resources resource "aws_api_gateway_resource" "filaments" { rest_api_id = aws_api_gateway_rest_api.api.id parent_id = aws_api_gateway_rest_api.api.root_resource_id path_part = "filaments" } resource "aws_api_gateway_resource" "filament" { rest_api_id = aws_api_gateway_rest_api.api.id parent_id = aws_api_gateway_resource.filaments.id path_part = "{id}" } resource "aws_api_gateway_resource" "auth" { rest_api_id = aws_api_gateway_rest_api.api.id parent_id = aws_api_gateway_rest_api.api.root_resource_id path_part = "auth" } resource "aws_api_gateway_resource" "login" { rest_api_id = aws_api_gateway_rest_api.api.id parent_id = aws_api_gateway_resource.auth.id path_part = "login" } # Lambda Authorizer resource "aws_api_gateway_authorizer" "jwt_authorizer" { name = "${var.app_name}-jwt-authorizer" rest_api_id = aws_api_gateway_rest_api.api.id type = "TOKEN" authorizer_uri = aws_lambda_function.auth_api.invoke_arn authorizer_credentials = aws_iam_role.api_gateway_auth_invocation.arn identity_source = "method.request.header.Authorization" } # IAM role for API Gateway to invoke Lambda authorizer resource "aws_iam_role" "api_gateway_auth_invocation" { name = "${var.app_name}-api-gateway-auth-invocation" assume_role_policy = jsonencode({ Version = "2012-10-17" Statement = [ { Action = "sts:AssumeRole" Effect = "Allow" Principal = { Service = "apigateway.amazonaws.com" } } ] }) } resource "aws_iam_role_policy" "api_gateway_auth_invocation" { name = "${var.app_name}-api-gateway-auth-invocation" role = aws_iam_role.api_gateway_auth_invocation.id policy = jsonencode({ Version = "2012-10-17" Statement = [ { Effect = "Allow" Action = "lambda:InvokeFunction" Resource = aws_lambda_function.auth_api.arn } ] }) } # Methods for /filaments resource "aws_api_gateway_method" "get_filaments" { rest_api_id = aws_api_gateway_rest_api.api.id resource_id = aws_api_gateway_resource.filaments.id http_method = "GET" authorization = "NONE" } resource "aws_api_gateway_method" "post_filament" { rest_api_id = aws_api_gateway_rest_api.api.id resource_id = aws_api_gateway_resource.filaments.id http_method = "POST" authorization = "CUSTOM" authorizer_id = aws_api_gateway_authorizer.jwt_authorizer.id } # Methods for /filaments/{id} resource "aws_api_gateway_method" "get_filament" { rest_api_id = aws_api_gateway_rest_api.api.id resource_id = aws_api_gateway_resource.filament.id http_method = "GET" authorization = "NONE" } resource "aws_api_gateway_method" "put_filament" { rest_api_id = aws_api_gateway_rest_api.api.id resource_id = aws_api_gateway_resource.filament.id http_method = "PUT" authorization = "CUSTOM" authorizer_id = aws_api_gateway_authorizer.jwt_authorizer.id } resource "aws_api_gateway_method" "delete_filament" { rest_api_id = aws_api_gateway_rest_api.api.id resource_id = aws_api_gateway_resource.filament.id http_method = "DELETE" authorization = "CUSTOM" authorizer_id = aws_api_gateway_authorizer.jwt_authorizer.id } # Method for /auth/login resource "aws_api_gateway_method" "login" { rest_api_id = aws_api_gateway_rest_api.api.id resource_id = aws_api_gateway_resource.login.id http_method = "POST" authorization = "NONE" } # OPTIONS methods for CORS resource "aws_api_gateway_method" "options_filaments" { rest_api_id = aws_api_gateway_rest_api.api.id resource_id = aws_api_gateway_resource.filaments.id http_method = "OPTIONS" authorization = "NONE" } resource "aws_api_gateway_method" "options_filament" { rest_api_id = aws_api_gateway_rest_api.api.id resource_id = aws_api_gateway_resource.filament.id http_method = "OPTIONS" authorization = "NONE" } resource "aws_api_gateway_method" "options_login" { rest_api_id = aws_api_gateway_rest_api.api.id resource_id = aws_api_gateway_resource.login.id http_method = "OPTIONS" authorization = "NONE" } # Lambda integrations resource "aws_api_gateway_integration" "filaments_get" { rest_api_id = aws_api_gateway_rest_api.api.id resource_id = aws_api_gateway_resource.filaments.id http_method = aws_api_gateway_method.get_filaments.http_method integration_http_method = "POST" type = "AWS_PROXY" uri = aws_lambda_function.filaments_api.invoke_arn } resource "aws_api_gateway_integration" "filaments_post" { rest_api_id = aws_api_gateway_rest_api.api.id resource_id = aws_api_gateway_resource.filaments.id http_method = aws_api_gateway_method.post_filament.http_method integration_http_method = "POST" type = "AWS_PROXY" uri = aws_lambda_function.filaments_api.invoke_arn } resource "aws_api_gateway_integration" "filament_get" { rest_api_id = aws_api_gateway_rest_api.api.id resource_id = aws_api_gateway_resource.filament.id http_method = aws_api_gateway_method.get_filament.http_method integration_http_method = "POST" type = "AWS_PROXY" uri = aws_lambda_function.filaments_api.invoke_arn } resource "aws_api_gateway_integration" "filament_put" { rest_api_id = aws_api_gateway_rest_api.api.id resource_id = aws_api_gateway_resource.filament.id http_method = aws_api_gateway_method.put_filament.http_method integration_http_method = "POST" type = "AWS_PROXY" uri = aws_lambda_function.filaments_api.invoke_arn } resource "aws_api_gateway_integration" "filament_delete" { rest_api_id = aws_api_gateway_rest_api.api.id resource_id = aws_api_gateway_resource.filament.id http_method = aws_api_gateway_method.delete_filament.http_method integration_http_method = "POST" type = "AWS_PROXY" uri = aws_lambda_function.filaments_api.invoke_arn } resource "aws_api_gateway_integration" "login" { rest_api_id = aws_api_gateway_rest_api.api.id resource_id = aws_api_gateway_resource.login.id http_method = aws_api_gateway_method.login.http_method integration_http_method = "POST" type = "AWS_PROXY" uri = aws_lambda_function.auth_api.invoke_arn } # OPTIONS integrations for CORS resource "aws_api_gateway_integration" "options_filaments" { rest_api_id = aws_api_gateway_rest_api.api.id resource_id = aws_api_gateway_resource.filaments.id http_method = aws_api_gateway_method.options_filaments.http_method integration_http_method = "POST" type = "AWS_PROXY" uri = aws_lambda_function.filaments_api.invoke_arn } resource "aws_api_gateway_integration" "options_filament" { rest_api_id = aws_api_gateway_rest_api.api.id resource_id = aws_api_gateway_resource.filament.id http_method = aws_api_gateway_method.options_filament.http_method integration_http_method = "POST" type = "AWS_PROXY" uri = aws_lambda_function.filaments_api.invoke_arn } resource "aws_api_gateway_integration" "options_login" { rest_api_id = aws_api_gateway_rest_api.api.id resource_id = aws_api_gateway_resource.login.id http_method = aws_api_gateway_method.options_login.http_method integration_http_method = "POST" type = "AWS_PROXY" uri = aws_lambda_function.auth_api.invoke_arn } # Lambda permissions for API Gateway resource "aws_lambda_permission" "api_gateway_filaments" { statement_id = "AllowAPIGatewayInvoke" action = "lambda:InvokeFunction" function_name = aws_lambda_function.filaments_api.function_name principal = "apigateway.amazonaws.com" source_arn = "${aws_api_gateway_rest_api.api.execution_arn}/*/*" } resource "aws_lambda_permission" "api_gateway_auth" { statement_id = "AllowAPIGatewayInvoke" action = "lambda:InvokeFunction" function_name = aws_lambda_function.auth_api.function_name principal = "apigateway.amazonaws.com" source_arn = "${aws_api_gateway_rest_api.api.execution_arn}/*/*" } # API Gateway Deployment resource "aws_api_gateway_deployment" "api" { rest_api_id = aws_api_gateway_rest_api.api.id depends_on = [ aws_api_gateway_integration.filaments_get, aws_api_gateway_integration.filaments_post, aws_api_gateway_integration.filament_get, aws_api_gateway_integration.filament_put, aws_api_gateway_integration.filament_delete, aws_api_gateway_integration.login, aws_api_gateway_integration.options_filaments, aws_api_gateway_integration.options_filament, aws_api_gateway_integration.options_login ] lifecycle { create_before_destroy = true } } # API Gateway Stage resource "aws_api_gateway_stage" "api" { deployment_id = aws_api_gateway_deployment.api.id rest_api_id = aws_api_gateway_rest_api.api.id stage_name = var.environment }