I have an API Gateway with the following API proxy endpoint that calls a Lambda function for retrieving data from a dynamodb table:
This is the policy associated to the IAM role attached to the Lambda function "connect_api" that calls the DynamoDB table:
{
"Statement": [
{
"Action": [
"connect:ListRoutingProfiles",
"connect:*"
],
"Effect": "Allow",
"Resource": [
"arn:aws:connect:eu-west-2:xxxxxxxxxxxx:instance/xxxxxxxxxxxx/contact-flow/*/*",
"arn:aws:connect:eu-west-2:xxxxxxxxxxxx:instance/xxxxxxxxxxxx/contact-flow/*",
"arn:aws:connect:eu-west-2:xxxxxxxxxxxx:instance/xxxxxxxxxxxx/*",
"arn:aws:connect:eu-west-2:xxxxxxxxxxxx:instance/xxxxxxxxxxxx"
],
"Sid": ""
},
{
"Effect": "Allow",
"Action": "lambda:InvokeFunction",
"Resource": "arn:aws:lambda:eu-west-2:xxxxxxxxxxxx:function:connect_api"
},
{
"Action": "dynamodb:Query",
"Effect": "Allow",
"Resource": [
"arn:aws:dynamodb:eu-west-2:xxxxxxxxxxxx:table/contactlens/index/timestamp",
"arn:aws:dynamodb:eu-west-2:xxxxxxxxxxxx:table/contactlens"
],
"Sid": ""
},
{
"Action": [
"dynamodb:Scan",
"dynamodb:GetItem"
],
"Effect": "Allow",
"Resource": [
"arn:aws:dynamodb:eu-west-2:xxxxxxxxxxxx:table/ctr",
"arn:aws:dynamodb:eu-west-2:xxxxxxxxxxxx:table/agent_status"
],
"Sid": ""
},
{
"Action": "dynamodb:UpdateItem",
"Effect": "Allow",
"Resource": "arn:aws:dynamodb:eu-west-2:xxxxxxxxxxxx:table/agent_status",
"Sid": ""
},
{
"Action": [
"logs:PutLogEvents",
"logs:CreateLogStream",
"logs:CreateLogGroup"
],
"Effect": "Allow",
"Resource": "arn:aws:logs:*:*:*",
"Sid": ""
}
],
"Version": "2012-10-17"
}
This is the trust relationship entity associated to the previous role:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
This is the policy associated to the IAM role attached to the API Gateway that calls the Lambda function "connect_api":
{
"Statement": [
{
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:DescribeLogGroups",
"logs:DescribeLogStreams",
"logs:PutLogEvents",
"logs:GetLogEvents",
"logs:FilterLogEvents"
],
"Effect": "Allow",
"Resource": [
"arn:aws:logs:*:*:*"
]
},
{
"Action": [
"dynamodb:PutItem",
"dynamodb:UpdateItem",
"dynamodb:DeleteItem",
"dynamodb:GetItem",
"dynamodb:Scan"
],
"Effect": "Allow",
"Resource": [
"arn:aws:dynamodb:eu-west-2:xxxxxxxxxxxx:table/customers",
"arn:aws:dynamodb:eu-west-2:xxxxxxxxxxxx:table/accounts",
"arn:aws:dynamodb:eu-west-2:xxxxxxxxxxxx:table/cards",
"arn:aws:dynamodb:eu-west-2:xxxxxxxxxxxx:table/sinistres",
"arn:aws:dynamodb:eu-west-2:xxxxxxxxxxxx:table/email",
"arn:aws:dynamodb:eu-west-2:xxxxxxxxxxxx:table/appointment_slots",
"arn:aws:dynamodb:eu-west-2:xxxxxxxxxxxx:table/agencies",
"arn:aws:dynamodb:eu-west-2:xxxxxxxxxxxx:table/intent_history",
"arn:aws:dynamodb:eu-west-2:xxxxxxxxxxxx:table/authorization_requests",
"arn:aws:dynamodb:eu-west-2:xxxxxxxxxxxx:table/ctr",
"arn:aws:dynamodb:eu-west-2:xxxxxxxxxxxx:table/agent_status",
"arn:aws:dynamodb:eu-west-2:xxxxxxxxxxxx:table/missed_calls"
]
},
{
"Action": [
"lambda:InvokeFunction"
],
"Effect": "Allow",
"Resource": [
"arn:aws:lambda:eu-west-2:xxxxxxxxxxxx:function:*"
]
}
],
"Version": "2012-10-17"
}
This is the trust relationship entity associated to the previous role (the one attached to the API Gateway):
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "apigateway.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
Now, if I test the Lambda function from the Lambda console, everything works fine:
But if I test the proxy API linked to the Lambda function:
It doesn't work and I get the following Internal Server Error:
Request: /connect/list_users
Status: 500
Latency: 29 ms
Response Body
{"message": "Internal server error"}
Response Headers
{"x-amzn-ErrorType":["InternalServerErrorException"]}
Logs
Execution log for request 3ff47544-2f03-4e52-a52c-ce76e397aee7
Wed May 31 15:52:55 UTC 2023 : Starting execution for request: 3ff47544-2f03-4e52-a52c-ce76e397aee7
Wed May 31 15:52:55 UTC 2023 : HTTP Method: GET, Resource Path: /connect/list_users
Wed May 31 15:52:55 UTC 2023 : Method request path: {proxy=list_users}
Wed May 31 15:52:55 UTC 2023 : Method request query string: {}
Wed May 31 15:52:55 UTC 2023 : Method request headers: {}
Wed May 31 15:52:55 UTC 2023 : Method request body before transformations:
Wed May 31 15:52:55 UTC 2023 : Endpoint request URI: https://lambda.eu-west-2.amazonaws.com/2015-03-31/functions/arn:aws:lambda:eu-west-2:xxxxxxxxxxxx:function:connect_api/invocations
Wed May 31 15:52:55 UTC 2023 : Endpoint request headers: {X-Amz-Date=20230531T155255Z, x-amzn-apigateway-api-id=xxxxxxxxxxxx, Accept=application/json, User-Agent=AmazonAPIGateway_xxxxxxxxxxxx, Host=lambda.eu-west-2.amazonaws.com, X-Amz-Content-Sha256=xxxxxxxxxxxx, X-Amzn-Trace-Id=Root=1-64776d57-xxxxxxxxxxxx, x-amzn-lambda-integration-tag=xxxxxxxxxxxx, Authorization=*********************************************************************************************************************************************************************************************************************************************************************************************************************************************ca4e12, X-Amz-Source-Arn=arn:aws:execute-api:eu-west-2:xxxxxxxxxxxx:xxxxxxxxxxxx/test-invoke-stage/GET/connect/{proxy+}, X-Amz-Security-Token=xxxxxxxxxxxx/xxxxxxxxxxxx [TRUNCATED]
Wed May 31 15:52:55 UTC 2023 : Endpoint request body after transformations: {"resource":"/connect/{proxy+}","path":"/connect/list_users","httpMethod":"GET","headers":null,"multiValueHeaders":null,"queryStringParameters":null,"multiValueQueryStringParameters":null,"pathParameters":{"proxy":"list_users"},"stageVariables":null,"requestContext":{"resourceId":"xxxxxxxxxxxx","resourcePath":"/connect/{proxy+}","httpMethod":"GET","extendedRequestId":"xxxxxxxxxxxx=","requestTime":"31/May/2023:15:52:55 +0000","path":"/connect/{proxy+}","accountId":"xxxxxxxxxxxx","protocol":"HTTP/1.1","stage":"test-invoke-stage","domainPrefix":"testPrefix","requestTimeEpoch":xxxxxxxxxxxx,"requestId":"xxxxxxxxxxxx","identity":{"cognitoIdentityPoolId":null,"cognitoIdentityId":null,"apiKey":"test-invoke-api-key","principalOrgId":null,"cognitoAuthenticationType":null,"userArn":"arn:aws:iam::xxxxxxxxxxxx:user/[email protected]","apiKeyId":"test-invoke-api-key-id","userAgent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, li [TRUNCATED]
Wed May 31 15:52:55 UTC 2023 : Sending request to https://lambda.eu-west-2.amazonaws.com/2015-03-31/functions/arn:aws:lambda:eu-west-2:xxxxxxxxxxxx:function:connect_api/invocations
Wed May 31 15:52:55 UTC 2023 : Execution failed due to configuration error: Invalid permissions on Lambda function
Wed May 31 15:52:55 UTC 2023 : Method completed with status: 500
But if I go to the "Integration request" page of the proxy API:
Then I simply click in Lambda Function (the pencil symbol) like I want to modify the selected function and I try to save the selected function keeping the same one (connect_api), a new window will pop up before saving it:
then I click "ok" and finally the API works fine.
Now the question is, how should I change the policy in order to avoid to add the permission to the API Gateway from the API Gateway Console?





If you are using Terraform to define your IaC, use
aws_api_gateway_rest_apito create the permission aws_lambda_permission | Resources | hashicorp/aws | Terraform | Terraform Registry