I am attempting to use BOTO3 to create an Api Gateway method that invokes a lambda function. I have so far been unable to find how to grant the necessary permissions.
Curiously, setting the lambda method name manually through the AWS console sets up permissions automatically. I have been unable to replicate this in code.
This is the code I am using to set up the gateway:
# Create a rest api
self.rest_api = self.apigateway.create_rest_api(
name='AWS_CMS_Operations'
)
# Get the rest api's root id
root_id = self.apigateway.get_resources(
restApiId=self.rest_api['id']
)['items'][0]['id']
# Create an api resource
api_resource = self.apigateway.create_resource(
restApiId=self.rest_api['id'],
parentId=root_id,
pathPart='AWS_CMS_Manager'
)
# Add a post method to the rest api resource
api_method = self.apigateway.put_method(
restApiId=self.rest_api['id'],
resourceId=api_resource['id'],
httpMethod='POST',
authorizationType='NONE'
)
# Add an integration method to the api resource
self.apigateway.put_integration(
restApiId=self.rest_api['id'],
resourceId=api_resource['id'],
httpMethod='POST',
type='AWS',
integrationHttpMethod='POST',
uri=self.create_api_invocation_uri()
)
# Set the put method response for the api resource
self.apigateway.put_method_response(
restApiId=self.rest_api['id'],
resourceId=api_resource['id'],
httpMethod='POST',
statusCode='200',
responseModels={
'application/json': 'Empty'
}
)
# Set the put integration response for the api resource
self.apigateway.put_integration_response(
restApiId=self.rest_api['id'],
resourceId=api_resource['id'],
httpMethod='POST',
statusCode='200',
responseTemplates={
'application/json': ''
}
)
# Create a deployment of the rest api
self.apigateway.create_deployment(
restApiId=self.rest_api['id'],
stageName='prod'
)
# Give the api deployment permission to trigger the lambda function
self.lmda.add_permission(
FunctionName=self.lmda_function['FunctionName'],
StatementId='apigateway-production-aws-cms',
Action='lambda:InvokeFunction',
Principal='apigateway.amazonaws.com',
SourceArn=self.create_api_permission_uri(api_resource)
)
Everything works fine with the exception of the proper permission being set for the gateway to invoke lambda.
2 Answers 2
I was able to get this working in Boto3 using this code:
source_arn = f'arn:aws:execute-api:{REGION}:{account_id}:{api_id}/*/*/{api_path}'
lambda_client.add_permission(FunctionName=lambda_function_arn, StatementId=f'invoke_{api_id}',
Action='lambda:InvokeFunction', Principal='apigateway.amazonaws.com',
SourceArn=source_arn)
This doesn't use the conventions used in the original question, but there are three things I'd like to point that may help with anyone wrestling with this question:
- The FunctionName parameter can take the function name, the function's ARN, or the partial ARN according to the Boto3 Documentation.
- The StatementId must be unique in your account. To ensure uniqueness, I appended something to the API ID, since I'll only need one rule per API.
- The SourceARN is the "execute-api" ARN for your api/staging location. I haven't seen that ARN used elsewhere.
Comments
From section 3.6 in this tutorial is a sample CLI command:
$ aws lambda add-permissionn \
--function-name <function-name> \
--statement-id apigateway-test-2 \
--action lambda:InvokeFunction \
--principal apigateway.amazonaws.com \
--source-arn "<method-arn">
Should be straight forward enough to translate to Boto3.
4 Comments
Explore related questions
See similar questions with these tags.