Terraformed AWS API Gateway 自定义域名抛出 403 Forbidden
Posted
技术标签:
【中文标题】Terraformed AWS API Gateway 自定义域名抛出 403 Forbidden【英文标题】:Terraformed AWS API Gateway Custom Domain Names throws 403 Forbidden 【发布时间】:2021-03-22 03:23:30 【问题描述】:我正在尝试通过区域自定义域公开我的区域 API 网关的所有阶段。
问题
如果我直接卷曲我的 API 网关(即https://xx.execute-api.eu-west-3.amazonaws.com/default/users
),它可以工作,但如果我卷曲域名(即https://api.acme.com/default/users
),我会得到一个403
。
配置
我的 Terraform 文件如下所示:
data "aws_route53_zone" "acme"
name = "acme.com."
resource "aws_api_gateway_rest_api" "backend"
name = "acme-backend-api"
description = "Backend API"
body = "SOMETHING"
endpoint_configuration
types = ["REGIONAL"]
resource "aws_api_gateway_deployment" "backend"
rest_api_id = aws_api_gateway_rest_api.backend.id
stage_name = "default"
lifecycle
create_before_destroy = true
resource "aws_api_gateway_domain_name" "backend"
domain_name = "api.acme.com"
regional_certificate_arn = "arn:aws:acm:xx:certificate/xx"
endpoint_configuration
types = ["REGIONAL"]
resource "aws_route53_record" "backend"
name = aws_api_gateway_domain_name.backend.domain_name
type = "A"
zone_id = data.aws_route53_zone.acme.id
alias
evaluate_target_health = true
name = aws_api_gateway_domain_name.backend.regional_domain_name
zone_id = aws_api_gateway_domain_name.backend.regional_zone_id
resource "aws_api_gateway_base_path_mapping" "backend"
api_id = aws_api_gateway_rest_api.backend.id
domain_name = aws_api_gateway_domain_name.backend.domain_name
# No stage_name: expose all stages
根据 Terraform api_gateway_domain_name 和 api_gateway_base_path_mapping 的例子,应该没问题。
我也跟着很多howtos,我有这些元素:
-
证书
API 自定义域的 A 记录
到已部署阶段的映射(如果您直接调用它就可以)
我错过了什么/做错了什么?
【问题讨论】:
您观察到哪些错误或非预期行为? 【参考方案1】:这是今天为我工作的 v2 示例,此“aws_apigatewayv2_api_mapping”是避免 port 80: Connection refused
的关键
或 "message":"Forbidden"
错误,我看到你有,但我确实遇到了困难。
// ACM
resource "aws_acm_certificate" "cert_api"
domain_name = var.api_domain
validation_method = "DNS"
tags =
Name = var.api_domain
resource "aws_acm_certificate_validation" "cert_api"
certificate_arn = aws_acm_certificate.cert_api.arn
// API Gateway V2
resource "aws_apigatewayv2_api" "lambda"
name = "serverless_lambda_gw"
protocol_type = "HTTP"
resource "aws_apigatewayv2_stage" "lambda"
api_id = aws_apigatewayv2_api.lambda.id
name = "serverless_lambda_stage"
auto_deploy = true
access_log_settings
destination_arn = aws_cloudwatch_log_group.api_gw.arn
format = jsonencode(
requestId = "$context.requestId"
sourceIp = "$context.identity.sourceIp"
requestTime = "$context.requestTime"
protocol = "$context.protocol"
httpMethod = "$context.httpMethod"
resourcePath = "$context.resourcePath"
routeKey = "$context.routeKey"
status = "$context.status"
responseLength = "$context.responseLength"
integrationErrorMessage = "$context.integrationErrorMessage"
)
resource "aws_apigatewayv2_integration" "testimonials"
api_id = aws_apigatewayv2_api.lambda.id
integration_uri = aws_lambda_function.testimonials.invoke_arn
integration_type = "AWS_PROXY"
integration_method = "POST"
resource "aws_apigatewayv2_route" "testimonials"
api_id = aws_apigatewayv2_api.lambda.id
route_key = "GET /testimonials"
target = "integrations/$aws_apigatewayv2_integration.testimonials.id"
resource "aws_cloudwatch_log_group" "api_gw"
name = "/aws/api_gw/$aws_apigatewayv2_api.lambda.name"
retention_in_days = 30
resource "aws_lambda_permission" "api_gw"
statement_id = "AllowExecutionFromAPIGateway"
action = "lambda:InvokeFunction"
function_name = aws_lambda_function.testimonials.function_name
principal = "apigateway.amazonaws.com"
source_arn = "$aws_apigatewayv2_api.lambda.execution_arn/*/*"
resource "aws_apigatewayv2_domain_name" "api"
domain_name = var.api_domain
domain_name_configuration
certificate_arn = aws_acm_certificate.cert_api.arn
endpoint_type = "REGIONAL"
security_policy = "TLS_1_2"
resource "aws_apigatewayv2_api_mapping" "api"
api_id = aws_apigatewayv2_api.lambda.id
domain_name = aws_apigatewayv2_domain_name.api.id
stage = aws_apigatewayv2_stage.lambda.id
// Route53
resource "aws_route53_zone" "api"
name = var.api_domain
resource "aws_route53_record" "cert_api_validations"
allow_overwrite = true
count = length(aws_acm_certificate.cert_api.domain_validation_options)
zone_id = aws_route53_zone.api.zone_id
name = element(aws_acm_certificate.cert_api.domain_validation_options.*.resource_record_name, count.index)
type = element(aws_acm_certificate.cert_api.domain_validation_options.*.resource_record_type, count.index)
records = [element(aws_acm_certificate.cert_api.domain_validation_options.*.resource_record_value, count.index)]
ttl = 60
resource "aws_route53_record" "api-a"
name = aws_apigatewayv2_domain_name.api.domain_name
type = "A"
zone_id = aws_route53_zone.api.zone_id
alias
name = aws_apigatewayv2_domain_name.api.domain_name_configuration[0].target_domain_name
zone_id = aws_apigatewayv2_domain_name.api.domain_name_configuration[0].hosted_zone_id
evaluate_target_health = false
【讨论】:
以上是关于Terraformed AWS API Gateway 自定义域名抛出 403 Forbidden的主要内容,如果未能解决你的问题,请参考以下文章
错误 - 403 禁止 - Microsoft-Azure-Application-Gateway/v2
如何在调用 google pay API 时了解我的支付提供商名称?
如何根据域名阻止对我的 api-gateway url 的任何请求?