At the end of the last lesson we've managed to create a Lambda function which we want to use to get data from DynamoDB table using the scan operation.
Unfortunately, after calling the AWS Lambda function we get a following response:
"message": "User: arn:aws:sts::696785635119:assumed-role/TodoAppStack-TodoDatabaseTodoHandlerServiceRole991-152UNT6KUIOG2/TodoAppStack-TodoDatabaseTodoHandlerDD6198FE-CPTO6AAJJU5W is not authorized to perform: dynamodb:Scan on resource: arn:aws:dynamodb:eu-central-1:696785635119:table/TodoAppStack-TodoDatabaseTodoTable29EA4913-E6Z09XSAAHF8",
In this quick lesson we're going to learn how to allow an AWS Lambda function to access data from a DynamoDB table with grantReadData function (in a single line of code!)
Instructor: [0:00] Now that we have implemented the body of our listTodos Lambda function, we need to go ahead and deploy it. In our todo-backend, I'm going to first of all import lambdaNodejs module. Secondly, I'm going to create a new Lambda function.
[0:00] I'm going to do const listTodosFunction, which is going to be a new lambdaNodejs.Function, which is a Construct. The first argument is this, the second argument, "ListTodos", and the third one are the props. In our case, we need to provide the entry. In our case, the entry is "lambda/listTodos.ts". That is because this is where this file is located.
[0:54] Secondly, we also need to provide the handler. Handler is going to be equal "handler" because this is the name of the function that is being exported from this file. We need to also pass in an environment variable. Why? Because in our listTodos function over here on the top, we need to pass in the TABLE_NAME which we are going to use in order to read data from DynamoDB.
[1:13] To do that, I'm going to do environment, which is an object, and I'm going to pass in the TABLE_NAME, which is going to be equal to...Well, to what exactly? We have this todosTable that we have defined over here. One of the powers of CDK is that you get to interact with cloud resources via code.
[1:27] The TABLE_NAME is going to be todosTable.tableName, and this variable is going to be always equal to whatever name CDK assigns for this table. With all of that in place, let me go ahead and deploy the stack. I'm going to run cdk deploy. Now that our stack has been successfully deployed, let me go to AWS console, and I'm going to go to CloudFormation.
[1:44] Next up, I'm going to select our stack. Let me expand the Resources. Here we have the TodoBackend and ListTodos function. We can see that our new Lambda function was successfully created. Let me click over here to go to AWS Lambda console. I'm going to scroll down a little, select the Test tab, and click on the Test button in order to send a test event to our Lambda function.
[2:11] Technically, our function has been evoked successfully, but if I expand the Details, we will see that the "statusCode" was 500. We are seeing an error message that our Lambda function is not authorized to perform a dynamodb:Scan. That happens because AWS is following something that's called the Principle of Least Privilege.
[2:28] The idea is that, resources created in the cloud have the least amount of privilege possible in order to get their job done. By default, a Lambda function does not need the permission to perform a scan on a DynamoDB table. Luckily with CDK, we can configure that ourselves, and in a single line of code. Let me go back to our todo-backend construct.
[2:57] Over here, we are going to grantReadData access to our listTodosFunction. Well, that's it. That's a single line which is going to solve our problem. Let me go ahead, open up the terminal. I'm going to run cdk diff to see what exactly is going to be different by adding the single line of code.
[0:00] We can see the difference over here. By adding this single line of code, we are going to make sure that our Lambda function is able to perform a dynamodb:Scan, as well as a bunch of other read operations on our TodoDatabase. With that, let me go ahead and deploy that using cdk deploy.
[0:00] Once our stack has been deployed, let me go back to AWS console. I'm going to test this function again. Now if I expand the details, we can see that the "statusCode" is 200, and in the "body", we are seeing both of our todos from our DynamoDB table.