AWS API Gateway's method integration is not able to access the lambda while using the aws_lambda_permission

I have a lambda with aws api gatewat. I have writhed the script for lambda and api gateay with integration. Once I have done a terraform apply the code will run without any issue. but the api gateway url shows internanel server error. I can fix this issue while update the api gateway get connection Integration Request lambda update manually. I have attached the screen shot and my terrafomr script here.

--------------------------------------------------------------

Create LAMDA Function Prod

--------------------------------------------------------------

resource “aws_lambda_function” “lambda_function1” {
function_name = “lamb-prod”
role = aws_iam_role.my_lambda_role1.arn
handler = “lambda_function.lambda_handler”
runtime = “python3.9”
filename = “test-b3974c99-c775-44f5-9860-71e77e439061.zip”
}

--------------------------------------------------------------

Create Policy and Cloudwatch

--------------------------------------------------------------

resource “aws_cloudwatch_log_group” “cloud1” {
name = “/aws/lambda/lamb-prod”
retention_in_days = 14
}

resource “aws_iam_policy” “lambda_logging1” {
name = “lambda_logging1”
path = “/”
description = “IAM policy for logging from a lambda1”
policy = <<EOF
{
“Version”: “2012-10-17”,
“Statement”: [
{
“Action”: [
“logs:CreateLogGroup”,
“logs:CreateLogStream”,
“logs:PutLogEvents”
],
“Resource”: “arn:aws:logs:::*”,
“Effect”: “Allow”
}
]
}
EOF
}

--------------------------------------------------------------

Lambda IAM role

--------------------------------------------------------------

resource “aws_iam_role” “my_lambda_role1” {
name = “mylambdarole1”

assume_role_policy = <<EOF
{
“Version”: “2012-10-17”,
“Statement”: [
{
“Action”: “sts:AssumeRole”,
“Principal”: {
“Service”: [
lambda.amazonaws.com”,
apigateway.amazonaws.com
]
},
“Effect”: “Allow”,
“Sid”: “”
}
]
}
EOF
}

--------------------------------------------------------------

attached Policy and role

--------------------------------------------------------------

resource “aws_iam_role_policy_attachment” “lambda_logs1” {
role = aws_iam_role.my_lambda_role1.name
policy_arn = aws_iam_policy.lambda_logging1.arn

}

Create AWS API gateway

--------------------------------------------------------------

resource “aws_api_gateway_rest_api” “apigateway” {
name = “apigateway-1”
description = “prod-dev-stage”
endpoint_configuration {
types = [“REGIONAL”]
}
}

-----------------------------------------------------------------

Resourse

-----------------------------------------------------------------

resource “aws_api_gateway_resource” “apigatewayresource” {
rest_api_id = aws_api_gateway_rest_api.apigateway.id
parent_id = aws_api_gateway_rest_api.apigateway.root_resource_id
path_part = “configuration”
}

resource “aws_api_gateway_method” “apigatewaymethod” {
rest_api_id = aws_api_gateway_rest_api.apigateway.id
resource_id = aws_api_gateway_resource.apigatewayresource.id
http_method = “GET”
authorization = “NONE”
}

resource “aws_api_gateway_integration” “apigatewayintegration” {
rest_api_id = aws_api_gateway_rest_api.apigateway.id
resource_id = aws_api_gateway_resource.apigatewayresource.id
http_method = aws_api_gateway_method.apigatewaymethod.http_method
integration_http_method = “GET”
type = “AWS_PROXY”

uri = “arn:aws:apigateway:ap-northeast-2:lambda:path/2015-03-31/functions/arn:aws:lambda:ap-northeast-2:185690593249:function:$${stageVariables.function}/invocations”

uri = aws_lambda_function.lambda_function1.invoke_arn
}

resource “aws_api_gateway_method_response” “response_200get” {
rest_api_id = aws_api_gateway_rest_api.apigateway.id
resource_id = aws_api_gateway_resource.apigatewayresource.id
http_method = aws_api_gateway_method.apigatewaymethod.http_method
status_code = “200”
response_models = { “application/json” = “Empty”}

}

resource “aws_api_gateway_integration_response” “MyDemoIntegrationResponse” {
rest_api_id = aws_api_gateway_rest_api.apigateway.id
resource_id = aws_api_gateway_resource.apigatewayresource.id
http_method = aws_api_gateway_method.apigatewaymethod.http_method
status_code = aws_api_gateway_method_response.response_200get.status_code

Transforms the backend JSON response to XML

response_templates = {
“application/xml” = <<EOF
#set($inputRoot = input.path(''))

<?xml version="1.0" encoding="UTF-8"?> $inputRoot.body EOF } }

resource “aws_lambda_permission” “apigw_lambda” {
depends_on = [
“aws_lambda_function.lambda_function1”,
“aws_api_gateway_rest_api.apigateway”,
“aws_api_gateway_method.apigatewaymethod”
]
#statement_id = “AllowAPIGatewayInvoke”
statement_id = “AllowExecutionFromAPIGateway”
action = “lambda:InvokeFunction”
function_name = aws_lambda_function.lambda_function1.function_name
principal = “apigateway.amazonaws.com
#source_arn = “{aws_api_gateway_rest_api.apigateway.execution_arn}/*/GET/configuration" #source_arn = "arn:aws:execute-api:{var.myregion}:{var.accountId}:{aws_api_gateway_rest_api.apigateway.id}//{aws_api_gateway_method.apigatewaymethod.http_method}{aws_api_gateway_resource.apigatewayresource.path}"
source_arn = "arn:aws:execute-api:ap-northeast-3:185690593249:vlab9shba8/
/*”
}

---------------------------------------------------------------------

Stage Production

---------------------------------------------------------------------

resource “aws_api_gateway_deployment” “prod_deploy” {
rest_api_id = aws_api_gateway_rest_api.apigateway.id
triggers = {

redeployment = sha1(jsonencode(aws_api_gateway_rest_api.apigateway.body))

 redeployment = sha1(jsonencode([
   aws_api_gateway_resource.apigatewayresource.id,
   aws_api_gateway_method.apigatewaymethod.id,
   aws_api_gateway_integration.apigatewayintegration.id
 ]))

}
lifecycle {
create_before_destroy = true
}
depends_on = [aws_api_gateway_method.apigatewaymethod, aws_api_gateway_integration.apigatewayintegration]
}

resource “aws_api_gateway_stage” “prod_stage” {
deployment_id = aws_api_gateway_deployment.prod_deploy.id
rest_api_id = aws_api_gateway_rest_api.apigateway.id
stage_name = “prod”
variables = {
function = aws_lambda_function.lambda_function1.function_name
}
}

facing similar issue

Ok I used a trained AWS RAG to solve this one

To fix the issue with your Terraform script where API Gateway can’t access Lambda:

  1. Correct the principal in aws_lambda_permission from “apigateway.amazonaws.com 3” to “apigateway.amazonaws.com”.
  2. Ensure there’s no typo in the source_arn for aws_lambda_permission. It should accurately reference your API Gateway’s ARN.
  3. Remove duplicate uri declarations in aws_api_gateway_integration. Use only aws_lambda_function.lambda_function1.invoke_arn.
  4. Check the aws_api_gateway_deployment resource to ensure it updates with API changes.
  5. Use the AWS Console to test the Lambda function and API Gateway integration for detailed error messages.
  6. Review IAM roles and policies for proper permissions.
  7. Examine CloudWatch Logs for error messages.
  8. Compare your Terraform configuration with the manual updates you make in the AWS Console to identify any missing configurations.