使用Terraform部署API Gateway时遭遇403权限拒绝错误求助
使用OpenAPI部署API Gateway时的403 AccessDeniedException解决方案
问题概述
执行terraform apply创建API Gateway资源时抛出403状态码的AccessDeniedException,需配置正确的IAM权限完成部署。
错误信息
Error: Error creating API Gateway: AccessDeniedException: │ status code: 403, request id: 52a64b5c-709e-4214-8789-510ace031176 │ │ with module.apigw["digitalts-devtest-lab-backend"].aws_api_gateway_rest_api.restapi, │ on .terraform/modules/apigw/main.tf line 1, in resource "aws_api_gateway_rest_api" "restapi": │ 1: resource "aws_api_gateway_rest_api" "restapi" { Error: Error creating API Gateway: AccessDeniedException: │ status code: 403, request id: bf46f9aa-3521-4fa5-893c-c3af227f8f3b │ │ with module.apigw["digitalts-devtest-beta-backend"].aws_api_gateway_rest_api.restapi, │ on .terraform/modules/apigw/main.tf line 1, in resource "aws_api_gateway_rest_api" "restapi": │ 1: resource "aws_api_gateway_rest_api" "restapi" {
所需IAM权限配置
执行Terraform的IAM实体(用户/角色)需要以下权限:
基础API Gateway管理权限
apigateway:CreateRestApi:创建REST API资源apigateway:CreateDeployment:部署APIapigateway:PutRestApi:通过OpenAPI定义更新APIapigateway:GetRestApi:获取API详情apigateway:UpdateRestApi:更新API配置apigateway:CreateResource:创建API路径资源apigateway:PutMethod:配置API方法apigateway:PutIntegration:配置后端集成apigateway:PutMethodResponse:配置方法响应apigateway:PutIntegrationResponse:配置集成响应
Lambda集成相关权限
lambda:InvokeFunction:允许API Gateway调用Lambda函数(需同时在Lambda资源策略中授权API Gateway)iam:PassRole:若使用自定义执行角色,需传递角色权限
示例IAM策略
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "apigateway:CreateRestApi", "apigateway:CreateDeployment", "apigateway:PutRestApi", "apigateway:GetRestApi", "apigateway:UpdateRestApi", "apigateway:CreateResource", "apigateway:PutMethod", "apigateway:PutIntegration", "apigateway:PutMethodResponse", "apigateway:PutIntegrationResponse" ], "Resource": "arn:aws:apigateway:*::/restapis/*" }, { "Effect": "Allow", "Action": "lambda:InvokeFunction", "Resource": "arn:aws:lambda:*:*:function:*" }, { "Effect": "Allow", "Action": "iam:PassRole", "Resource": "arn:aws:iam::*:role/*ApiGatewayExecutionRole*" } ] }
当前实现代码
模块代码
resource "aws_api_gateway_rest_api" "restapi" { body = jsonencode({ openapi = "3.0.1" info = { title = "DTS API GATEWAY" version = "1.0" } paths = { "/auditlog" = { "get" = { x-amazon-apigateway-integration = { httpMethod = "GET" payloadFormatVersion = "1.0" type = "LAMBDA_PROXY" uri = var.lambda_uri_getAuditLog } x-amazon-apigateway-auth = { type: "NONE" } }, "options" = { x-amazon-apigateway-integration = { httpMethod = "OPTIONS" payloadFormatVersion = "1.0" type = "MOCK" uri = "" "requestTemplates" : { "application/json" : { "statusCode" : "200" } } "response" : { "statusCode" : "200" "responseTemplates" : { "application/json" : {} "responseParameters" : { "method.response.header.Access-Control-Allow-Credentials": "true", "method.response.header.Access-Control-Allow-Headers": "'*'", "method.response.header.Access-Control-Allow-Methods": "'*'", "method.response.header.Access-Control-Allow-Origin": "" } } } } x-amazon-apigateway-auth = { type: "NONE" } "response" : { "statusCode" : "200" "responseParameters" : { "method.response.header.Access-Control-Allow-Credentials": "", "method.response.header.Access-Control-Allow-Headers": "", "method.response.header.Access-Control-Allow-Methods": "", "method.response.header.Access-Control-Allow-Origin": "" } } } } "/dependencytable" = { "post" = { x-amazon-apigateway-integration = { httpMethod = "POST" payloadFormatVersion = "1.0" type = "LAMBDA_PROXY" uri = var.lambda_uri_postDependencyTable } x-amazon-apigateway-auth = { type: "NONE" } }, "options" = { x-amazon-apigateway-integration = { httpMethod = "OPTIONS" payloadFormatVersion = "1.0" type = "MOCK" uri = "" "requestTemplates" : { "application/json" : { "statusCode" : "200" } } "response" : { "statusCode" : "200" "responseTemplates" : { "application/json" : {} "responseParameters" : { "method.response.header.Access-Control-Allow-Credentials": "true", "method.response.header.Access-Control-Allow-Headers": "'*'", "method.response.header.Access-Control-Allow-Methods": "'*'", "method.response.header.Access-Control-Allow-Origin": "" } } } } x-amazon-apigateway-auth = { type: "NONE" } "response" : { "statusCode" : "200" "responseParameters" : { "method.response.header.Access-Control-Allow-Credentials": "", "method.response.header.Access-Control-Allow-Headers": "", "method.response.header.Access-Control-Allow-Methods": "", "method.response.header.Access-Control-Allow-Origin": "" } } } }, "/dts/info" = { "get" = { x-amazon-apigateway-integration = { httpMethod = "GET" payloadFormatVersion = "1.0" type = "LAMBDA_PROXY" uri = var.lambda_uri_getDtsInfo } x-amazon-apigateway-auth = { type: "NONE" } }, "options" = { x-amazon-apigateway-integration = { httpMethod = "OPTIONS" payloadFormatVersion = "1.0" type = "MOCK" uri = "" "requestTemplates" : { "application/json" : { "statusCode" : "200" } } "response" : { "statusCode" : "200" "responseTemplates" : { "application/json" : {} "responseParameters" : { "method.response.header.Access-Control-Allow-Credentials": "true", "method.response.header.Access-Control-Allow-Headers": "'*'", "method.response.header.Access-Control-Allow-Methods": "'*'", "method.response.header.Access-Control-Allow-Origin": "" } } } } x-amazon-apigateway-auth = { type: "NONE" } "response" : { "statusCode" : "200" "responseParameters" : { "method.response.header.Access-Control-Allow-Credentials": "", "method.response.header.Access-Control-Allow-Headers": "", "method.response.header.Access-Control-Allow-Methods": "", "method.response.header.Access-Control-Allow-Origin": "" } } } }, "/entities/{entityId}/subtract/{incrementId}" = { "delete" = { x-amazon-apigateway-integration = { httpMethod = "DELETE" payloadFormatVersion = "1.0" type = "LAMBDA_PROXY" uri = var.lambda_uri_incrementId } x-amazon-apigateway-auth = { type: "NONE" } "parameters": [ { "in" : "query" "name": "entityId" "schema": { "type": "string" } }, { "in" : "query" "name": "incrementId" "schema": { "type": "string" } } ] }, "post" = { x-amazon-apigateway-integration = { httpMethod = "POST" payloadFormatVersion = "1.0" type = "LAMBDA_PROXY" uri = var.lambda_uri_incrementId } x-amazon-apigateway-auth = { type: "NONE" } "parameters": [ { "in" : "query" "name": "entityId" "schema": { "type": "string" } }, { "in" : "query" "name": "incrementId" "schema": { "type": "string" } } ] }, "options" = { x-amazon-apigateway-integration = { httpMethod = "OPTIONS" payloadFormatVersion = "1.0" type = "MOCK" uri = "" "requestTemplates" : { "application/json" : { "statusCode" : "200" } } "response" : { "statusCode" : "200" "responseTemplates" : { "application/json" : {} "responseParameters" : { "method.response.header.Access-Control-Allow-Credentials": "true", "method.response.header.Access-Control-Allow-Headers": "'*'", "method.response.header.Access-Control-Allow-Methods": "'*'", "method.response.header.Access-Control-Allow-Origin": "" } } } } x-amazon-apigateway-auth = { type: "NONE" } "response" : { "statusCode" : "200" "responseParameters" : { "method.response.header.Access-Control-Allow-Credentials": "", "method.response.header.Access-Control-Allow-Headers": "", "method.response.header.Access-Control-Allow-Methods": "", "method.response.header.Access-Control-Allow-Origin": "" } } } } } }) name = var.api_gateway_name endpoint_configuration { types = var.endpoint_configuration } } resource "aws_api_gateway_deployment" "deployment" { rest_api_id = aws_api_gateway_rest_api.restapi.id triggers = { redeployment = sha1(jsonencode(aws_api_gateway_rest_api.restapi.body)) } lifecycle { create_before_destroy = true } }
部署配置
module "apigw" { source = "../api-gateway-new/aws" version = "0.0.6" for_each = local.api_gateway api_gateway_name = each.value.api_gateway_name lambda_uri_getAuditLog = var.lambda_uri_getAuditLog lambda_uri_postDependencyTable = var.lambda_uri_postDependencyTable lambda_uri_getDtsInfo = var.lambda_uri_getDtsInfo lambda_uri_incrementId = var.lambda_uri_incrementId endpoint_configuration = var.endpoint_configuration }
本地变量定义
locals { api_gateway = { "digitalts-devtest-beta-backend" = { api_gateway_name = var.api_gateway_name_beta #lambda_uri_getAuditLog = var.lambda_uri_getAuditLog }, "digitalts-devtest-lab-backend" = { api_gateway_name = var.api_gateway_name_lab #uri = var.uri_lab } } }
内容的提问来源于stack exchange,提问作者Shafeeq
相关产品推荐
相关产品推荐

