在AWS Lambda执行处理程序外部缓存异步API结果

问题描述

正在考虑使用SSM参数存储SDK来获取lambda函数的机密。我还使用epsagon包装异步处理函数。 Epsagon需要使用一些秘密进行初始化,然后用于包装处理程序函数

import * as epsagon from 'epsagon'

epsagon.init({
  token: EPSAGON_ACCOUNT_TOKEN,})

export const lambdaHandler = epsagon.lambdaWrapper(async (event) => {
  // do stuff
  
})

开始使用aws-parameter-cache从SSM Param Store中获取配置值,但是由于它们是通过API调用解析的,因此需要await才能完全解析这些值。

import { ssmParameter } from 'aws-parameter-cache'

const param = ssmParameter({ name: 'foo' })
const value = await param.value; // <-- can only be done inside an async function (nodejs12)

由于在nodejs12中我们还没有顶层等待,是否有办法在处理程序函数之外解析变量?是否可以等待await param.value的API调用完成,以便我可以使用SSM Param Store中存储的值来初始化epsagon?

import * as epsagon from 'epsagon'
import { ssmParameter } from 'aws-parameter-cache'
const ssmParam = ssmParameter({ name: 'epsagonToken' })

const epsagonToken = await ssmParam.value // fails since outside of async func

epsagon.init({
  token: epsagonToken,})

export const lambdaHandler = epsagon.lambdaWrapper(async (event) => {
  const epsagonToken = await ssmParam.value // works here but too late
})

在顶级等待的情况下,nodejs 14.3.0中的“工作”是否可行?自定义运行时?

或者也许是某种形式的永不拒绝的顶级异步函数,例如对此的最高答案:how-can-i-use-async-await-at-the-top-level

需要处理程序作为顶级异步函数的回调-从我读到的内容来看,本质上是14.3中顶级异步的工作方式。寻找将所有机密存储在SSM Param存储中并减少cf模板ENV变量映射的方法

解决方法

在这种情况下,基本上没有简单的方法可以进行顶级等待,但是有一些简单的解决方法。例如,这是另一个包装器的实现,可用于初始化Epsagon:

import * as epsagon from 'epsagon'
import { ssmParameter } from 'aws-parameter-cache'
const ssmParam = ssmParameter({ name: 'epsagonToken' })

const withEpsagon = (wrapped) => {
  let epsagonInited = false
  const epsagonizedFunction = epsagon.lambdaWrapper(wrapped)
  return async (event,context,callback) => {
    if (!epsagonInited) {
      const epsagonToken = await ssmParam.value
      epsagon.init({
        token: epsagonToken,})
      epsagonInited = true
    }
    return epsagonizedFunction(event,callback)
  }
}

export const lambdaHandler = withEpsagon(async (event) => {
    // your code here
})

此代码将在首次执行时解析SSM参数(在冷启动之后,无论如何,这都是您必须花费的时间),并记住它已经初始化了Epsagon,因此您无需浪费时间在每次调用Lambda时。