【发布时间】:2023-02-21 03:18:34
【问题描述】:
我在 terraform 中设置 rest api 以调用 lambda 函数时遇到问题。我遗漏了一些东西,因为当我从 terraform 部署 lambda 函数并从具有相同配置的 aws 控制台手动创建 rest api 时(已经检查控制台配置 5 次,它与使用 terraform 部署的相同)。因此,当我使用 terraform 进行部署时,我会得到 {"message": "Internal server error"} 响应。在我的 lambda、rest api 和 ham 的 terraform 代码下方。知道我在 terraform conf 中遗漏了什么。很确定我在其余的 api 部分遗漏了一些东西......
resource "aws_api_gateway_rest_api" "search_api" {
name = "search_api"
endpoint_configuration {
types = ["REGIONAL"]
}
}
resource "aws_api_gateway_resource" "search_api" {
rest_api_id = aws_api_gateway_rest_api.search_api.id
parent_id = aws_api_gateway_rest_api.search_api.root_resource_id
path_part = "search"
}
resource "aws_api_gateway_method" "search_api" {
rest_api_id = aws_api_gateway_rest_api.search_api.id
resource_id = aws_api_gateway_resource.search_api.id
http_method = "GET"
authorization = "NONE"
}
resource "aws_api_gateway_method_response" "response_200" {
rest_api_id = aws_api_gateway_rest_api.search_api.id
resource_id = aws_api_gateway_resource.search_api.id
http_method = aws_api_gateway_method.search_api.http_method
status_code = "200"
response_models = {
"application/json" = null
}
}
resource "aws_api_gateway_integration" "search_api" {
rest_api_id = aws_api_gateway_rest_api.search_api.id
resource_id = aws_api_gateway_resource.search_api.id
http_method = aws_api_gateway_method.search_api.http_method
integration_http_method = "GET"
type = "AWS"
uri = aws_lambda_function.lambda_search_py.invoke_arn
credentials = aws_iam_role.search_py_lambda_execution.arn
request_templates = {
"application/json" = jsonencode(
{
name = "$input.params('name')"
})
}
depends_on = [aws_lambda_permission.lambda_search_py]
}
resource "aws_api_gateway_integration_response" "search_api" {
http_method = aws_api_gateway_method.search_api.http_method
resource_id = aws_api_gateway_resource.search_api.id
rest_api_id = aws_api_gateway_rest_api.search_api.id
status_code = aws_api_gateway_method_response.response_200.status_code
depends_on = [
aws_api_gateway_integration.search_api
]
}
resource "aws_api_gateway_deployment" "search_api" {
rest_api_id = aws_api_gateway_rest_api.search_api.id
stage_name = "test"
depends_on = [aws_api_gateway_integration.search_api]
}
output "search_api_url" {
value = aws_api_gateway_deployment.search_api.invoke_url
}
resource "aws_lambda_function" "lambda_search_py" {
function_name = "SearchField"
s3_bucket = aws_s3_bucket.lambda.id
s3_key = aws_s3_object.s3_search_py.key
runtime = "python3.9"
handler = "lambda_function.lambda_handler"
source_code_hash = data.archive_file.data_lambda_search_py.output_base64sha256
role = aws_iam_role.lambda_role.arn
vpc_config {
subnet_ids = [data.terraform_remote_state.infra.outputs.subnet_main_prv1a_id, data.terraform_remote_state.infra.outputs.subnet_main_prv2b_id]
security_group_ids = [data.terraform_remote_state.infra.outputs.secgrp_ec2_id]
}
}
resource "aws_lambda_permission" "lambda_search_py" {
statement_id = "AllowAPIGatewayInvoke"
action = "lambda:InvokeFunction"
function_name = aws_lambda_function.lambda_search_py.function_name
principal = "apigateway.amazonaws.com"
source_arn = "${aws_api_gateway_rest_api.search_api.execution_arn}/*/GET/search"
}
resource "aws_iam_role" "lambda_role" {
name = "lambda_role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Action = "sts:AssumeRole"
Effect = "Allow"
Sid = ""
Principal = {
Service = "lambda.amazonaws.com"
}
}
]
})
}
resource "aws_iam_role_policy_attachment" "AWSLambda_FullAccess" {
role = aws_iam_role.lambda_role.name
policy_arn = "arn:aws:iam::aws:policy/AWSLambda_FullAccess"
}
resource "aws_iam_role_policy_attachment" "AWSLambdaVPCAccessExecutionRole" {
role = aws_iam_role.lambda_role.name
policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole"
}
resource "aws_iam_role" "search_py_lambda_execution" {
name = "lambda_execution"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = "sts:AssumeRole"
Effect = "Allow"
Principal = {
Service = "apigateway.amazonaws.com"
}
}
]
})
}
resource "aws_iam_policy" "search_py_lambda_execution" {
name = "search_py_lambda_execution"
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = "lambda:InvokeFunction"
Effect = "Allow"
Resource = "*"
}
]
})
}
resource "aws_iam_role_policy_attachment" "search_py_lambda_execution1" {
role = aws_iam_role.search_py_lambda_execution.name
policy_arn = aws_iam_policy.search_py_lambda_execution.arn
}
resource "aws_iam_role_policy_attachment" "AmazonAPIGatewayInvokeFullAccess" {
role = aws_iam_role.search_py_lambda_execution.name
policy_arn = "arn:aws:iam::aws:policy/AmazonAPIGatewayInvokeFullAccess"
}
我收到内部服务器错误,当我调用 rest api 时,我应该从 lambda 函数得到响应。如果我只从 Amazon 控制台创建 rest api 那么它就可以工作
【问题讨论】:
-
对于 Lambda,我认为您可能需要使用
integration_http_method = "POST"和type = "AWS_PROXY"。 -
这是权限问题吗?您是否拥有在 TF 中具有正确权限的 AWS 凭证?
-
@LHWizard aws 凭据没问题我可以部署到 terraform 我的 api gw 和所有 necesarry
-
我启用了日志记录并想到了以下内容,但不知道在从 aws 控制台部署相同内容时我缺少什么访问问题 (e1770769-c366-4097-b301-446d82d15437) 转换前的端点响应正文: <AccessDeniedException> <Message>无法确定要授权的服务/操作名称</Message></AccessDeniedException> (e1770769-c366-4097-b301-446d82d15437) Lambda 调用失败,状态:403。Lambda 请求 ID:adf1a992-6ca6 -4974-b0e8-d7163cd68910 (e1770769-c366-4097-b301-446d82d15437) 由于配置错误导致执行失败:
-
@MarkoE 谢谢你的建议,我把 post 作为集成,它起作用了,对于我不想使用代理集成的类型,所以我把它留给了 AWS。它现在正在工作,所以解决方案是使用 integration_http_method = "POST"
标签: aws-lambda terraform aws-api-gateway terraform-provider-aws