Additional documentation for IAM Auth with AWS Lambda

The documentation here recommends:

  • Instantiating the Mongo client once in global scope
  • Assuming an IAM role to authenticate with atlas.

This can create a problem in higher traffic lambdas where the global scope lives longer than 60 minutes. When using role chaining to assume an AWS role, there is a time limit of one hour, so requests send after this one hour time limit will always fail with a MongoServerError: Authentication failed. error message.

It would be helpful to add this caveat to the documentation.

For reference, this is the workaround we have been using:

const fetchClient = async () => {

  const { Credentials } = await sts.assumeRole({
    arn: 'arn:aws:iam::000000000000:role/MyMongoRole',
    roleSessionName: 'MyMongoSession',
  });

  const auth = `${Credentials?.AccessKeyId!}:${encodeURIComponent(Credentials?.SecretAccessKey!)}`;

  const params = new URLSearchParams({
    // ...etc
    authMechanismProperties: `AWS_SESSION_TOKEN:${Credentials?.SessionToken!}`,
  });

  const uri = `mongodb+srv://${auth}@my-cluster-name.mongodb.net/?${params.toString()}`;

  return { client: new MongoClient(uri), expiry: Credentials?.Expiration! };
};

let globalConnection = await fetchClient();

const handler = async () => {
  if (globalConnection.expiry) {
    globalConnection = await fetchClient();
  }

  await globalConnection.client.db('MyMongoDb').command({ listDatabases: 1 });
};

It would be good to know if this is the recommended approach for this problem, or if I’ve missed some neater way to reconnect to the client on token expiry.