Accessing DynamoDB tables from Amplify Lambda functions
Alexey Korepanov
by Alexey Korepanov
2 min read

Categories

Tags

How to access AWS DynamoDB tables from Amplify Lambda Function: access policy configuration and resolving Dynamo table names.

In order to give your Amplify function direct access to the DynamoDB tables you need to do a couple of steps:

Configuring access policies

You can go directly to your AWS console and assign appropriate permissions through the Web UI. However, every time you create a new Amplify environment, these settings will not apply to the new functions and you would need to assign them again.

The proper way to configure access polisies is to modify amplify/backend/function/<function-name>/<function-name>-cloudformation-template.json file.

In order to give the Lambda access to DynamoDB you need to add a new policy to the Resources array. Lets for example call the policy LambdaDynamoDbPolicy, then your template file will look like this:

{
  "AWSTemplateFormatVersion": "2010-09-09",
  ...
  "LambdaDynamoDbPolicy": {
    "DependsOn": [
      "LambdaExecutionRole"
    ],
    "Type": "AWS::IAM::Policy",
    "Properties": {
      "PolicyName": "dynamo-db-read-items-policy",
      "Roles": [
        {
          "Ref": "LambdaExecutionRole"
        }
      ],
      "PolicyDocument": {
        "Version": "2012-10-17",
        "Statement": [
          {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "dynamodb:GetItem",
            "Resource": "*"
          }
        ]
      }
    }
  },
  ...
}

In this example we give the function read-only access to all dynamodb resources.

Resolving Dynamo table names of the current environment from the Lambda.

You can always hardcode your dynamodb table names in the function source code but the names will change if you switch to another Amplify environment. Here is how to avoid it.

Dynamo table name usually looks something like MyTable-zhgpujd7xuergkrdfxp9nkqcpw-prod and contains 3 parts separated with dash character:

  • User-defined table name (MyTable)
  • GraphQLAPIIdOutput which is an ID unique to your project (zhgpujd7xuergkrdfxp9nkqcpw)
  • Amplify environment name (prod)

Amplify environment name is available for the function throught ENV environment variable. To make GraphQLAPIIdOutput available, you need to give the function access to the API:

$ amplify update function
Using service: Lambda, provided by: awscloudformation
? Please select the Lambda Function you would want to update MyFunction
? Do you want to update permissions granted to this Lambda function to perform on other resources in your project? Yes
? Select the category api
Api category has a resource called myproject
? Select the operations you want to permit for myproject read

You can access the following resource attributes as environment variables from your Lambda function
var environment = process.env.ENV
var region = process.env.REGION
var apiMyProjectGraphQLAPIIdOutput = process.env.API_MYPROJECT_GRAPHQLAPIIDOUTPUT
var apiMyProjectGraphQLAPIEndpointOutput = process.env.API_MYPROJECT_GRAPHQLAPIENDPOINTOUTPUT

? Do you want to edit the local lambda function now? No
Successfully updated resource

Now you can modify your function and build DynamoDB table name like this:

const environment = process.env.ENV;
const apiGraphQLAPIIdOutput = process.env.API_MYPROJECT_GRAPHQLAPIIDOUTPUT;
const myTableName = `MyTable-${apiGraphQLAPIIdOutput}-${environment}`;

And now you can read the table data using aws-sdk library:

const AWS = require('aws-sdk');
const documentClient = new AWS.DynamoDB.DocumentClient();
documentClient.get({
  TableName: myTableName,
  Key: { 'foo' },
}, (err, data) => {
  console.log('DynamoDB record for the key "foo"', data);
});