Connect to Amazon MemoryDB for Redis from AWS Lambda

This snippet demonstrates how to conenct to an Amazon MemoryDB for Redis cluster from an AWS Lambda function with IAM authentication. This snippet is valid for Redis engine version 7.0+.

Amazon MemoryDB for Redis is a durable database with microsecond reads, low single-digit millisecond writes, scalability, and enterprise security. Connect to a MemoryDB cluster using IAM authentication.

Select language:

Copy the code into your Lambda function

Follow the AWS Lambda instructions for packaging with dependencies and uploading in .zip format. This snippet uses the ioredis library.

// Snippet uses the ioredis library, but other redis clients will also work
import { Cluster } from 'ioredis';
import { SignatureV4 } from '@aws-sdk/signature-v4';
import { Sha256 } from '@aws-crypto/sha256-js';
import { formatUrl } from '@aws-sdk/util-format-url';
import { fromNodeProviderChain } from '@aws-sdk/credential-providers';

let redisClient: Cluster;

/**
 * MemoryDB (and Elasticache) with Redis v7.0+ offer IAM authentication. In this mode, pass
 * the username with a presigned URL as the password. This function generates the presigned
 * URL, which acts as an authentication token. Note that this token expires after 15 minutes
 * and will need to be refreshed.
 * 
 * Snippet assumes that cache parameters are included as environment variables. Note that
 * cache cluster name is distinct from endpoint.
 */

const getAuthToken = async(): Promise<string> => {
    const signer = new SignatureV4({
      service: 'memorydb',
      region: process.env['AWS_REGION'],
      credentials: fromNodeProviderChain(),
      sha256: Sha256
    });
  
    const protocol = 'https';
  
    const presigned = await signer.presign({
      method: 'GET',
      protocol,
      hostname: process.env['CACHE_CLUSTER_NAME'],
      path: '/',
      query: {
        Action: 'connect',
        User: process.env['CACHE_USERNAME']
      },
      headers: {
        host: process.env['CACHE_CLUSTER_NAME']
      }
    }, { expiresIn: 900 });
  
    const token = formatUrl(presigned).replace(`${protocol}://`, '');
  
    return token;
  };

  redisClient = new Cluster(
    [
      {
        host: process.env['CACHE_ENDPOINT'],
        port: parseInt(process.env['CACHE_PORT']), // usually 6379
      }
    ],
    {
      // dnsLookup resolves an issue with TLS encryption and MemoryDB clusters
      // see https://github.com/redis/ioredis#special-note-aws-elasticache-clusters-with-tls
      dnsLookup: (address, callback) => callback(null, address),
      redisOptions: {
        username: process.env['CACHE_USERNAME'],
        password: await getAuthToken(),
        tls: {}
      }
    }
  );
}

// set a value in the cache, see ioredis docs for other options
await redisClient.set("foo", "bar");

// get the value back
const result = redisClient.get("foo");
                                                      



Created by:

Josh Kahn

Josh Kahn

Principal Solution Architect @ AWS.