使用适用于 亚马逊云科技 Lambda 的 Powertools (TypeScript) 检索参数和机密

作者: 帕斯卡尔·沃格尔 | 2023

这篇文章由高级解决方案架构师安德里亚·阿莫罗西和解决方案架构师帕斯卡尔·沃格尔撰写。

使用 AW S Lambda 构建无服务器应用程序时,您经常需要在运行时检索参数,例如数据库连接详情、API 密钥或全局配置值。您可以通过安全、可扩展和高度可用的参数存储(例如 亚马逊云科技 Sy stems Manager 参数存储 或 亚马逊云科技 S ec rets Manager)将这些参数 提供给您的 Lambda 函数。

适用于 亚马逊云科技 Lambda 的 Powertools( TypeScript)的 参数实用程序简化了这些参数存储在您的 Lambda 函数中的集成。该实用程序提供了用于检索机密和参数的高级函数,集成了缓存和转换,并减少了您必须编写的样板代码量。

参数实用程序支持以下参数存储:

  • 亚马逊云科技 Systems Manager 参数存储
  • 亚马逊云科技 Secrets Manager
  • 亚马逊云科技 应用程序配置
  • 亚马逊 DynamoDB
  • 自定义参数存储提供商

参数实用程序是 亚马逊云科技 Lambda Powertools( TypeScript)的一部分,你可以在 Java Script 和 TypeScript 代码库中使用它。Powertools 实施来自 亚马逊云科技 架构完善框架的 无服务器应用程序视角 的指导 ,提供了一些实用工具,可简化分布式跟踪、结构化日志以及异步业务和应用程序指标等最佳实践的采用。

更多详情,请参阅 GitHub 上的 亚马逊云科技 Lambda Powertools (TypeScript ) 文档和介绍性博客文章。

这篇博客文章展示了如何使用新的参数实用程序来安全地检索 JavaScript 和 TypeScript Lambda 函数中的参数和密码。

参数实用程序入门

初始设置

Powertools 工具包是模块化的,这意味着您可以独立于记录器、跟踪或指标包安装参数实用程序。通过 npm 在您的项目中安装参数实用程序库:

npm install @aws-lambda-powertools/parameters

此外,您必须为计划使用的参数存储添加 亚马逊云科技 SDK 客户端。参数实用程序 仅支持适用于 Java Script 的 亚马逊云科技 开发工具包 v3 ,这允许该实用程序实现模块化。您只安装所需的 SDK 包以缩小捆绑包的大小。

接下来,为您的 Lambda 函数的 L ambda 函数执行 角色分配适当的 A WS 身份和访问管理 (IAM) 权限, 该 角色允许从参数存储中检索参数。

以下部分说明如何针对一些典型的参数检索场景执行前面提到的步骤。

从 SSM 参数存储中检索单个参数

要从 SSM 参数存储中检索参数,除了参数实用程序外,还要安装适用于 SSM 的 亚马逊云科技 开发工具包客户端:

npm install @aws-sdk/client-ssm

为了检索单个参数,参数实用程序提供了 getP arameter 函数:

import { getParameter } from '@aws-lambda-powertools/parameters/ssm';

export const handler = async (): Promise<void> => {
  // Retrieve a single parameter
  const parameter = await getParameter('/my/parameter');
  console.log(parameter);
};

最后,您需要为您的 Lambda 函数执行角色分配一个具有 ssm: getParameter 权限的 IAM 策略。 通过将 权限范围限定到特定参数资源来应用最低权限 原则 ,如以下策略示例所示:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "ssm:GetParameter"
      ],
      "Resource": [
        "arn:aws:ssm:AWS_REGION:AWS_ACCOUNT_ID:my/parameter"
      ]
    }
  ]
}

调整缓存 TTL

默认情况下,检索到的参数在内存中缓存 5 秒。此缓存值用于进一步调用 Lambda 函数,直至其过期。如果您的应用程序需要不同的行为,则参数实用程序允许您通过 maxAge 参数调整生存时间 (TTL)。

在前面的示例的基础上,如果您想将检索到的参数缓存 30 秒而不是 5 秒,则可以按如下方式调整函数代码:

import { getParameter } from '@aws-lambda-powertools/parameters/ssm';

export const handler = async (): Promise<void> => {
  // Retrieve a single parameter with a 30 seconds cache TTL
  const parameter = await getParameter('/my/parameter', { maxAge: 30 });
  console.log(parameter);
};

在其他情况下,您可能希望始终从参数存储中检索最新值并忽略任何缓存值。要实现此目的,请将 forceFetch 参数设置为 true

import { getParameter } from '@aws-lambda-powertools/parameters/ssm';

export const handler = async (): Promise<void> => {
  // Always retrieve the latest value of a single parameter
  const parameter = await getParameter('/my/parameter', { forceFetch: true });
  console.log(parameter);
};

有关详细信息,请参阅适用于 亚马逊云科技 Lambda 的 Powertools (TypeScript) 文档 中的 “ 始终获取最新 信息”。

解码以 JSON 或 base64 格式存储的参数

如果您的某些参数存储在 base64 或 JSON 中,则可以通过参数实用程序的 转换参数对其进行反序列化。

考虑到以 JSON 形式存储在 SSM 中的参数,可以按如下方式对其进行检索和反序列化:

import { Transform } from '@aws-lambda-powertools/parameters';
import { getParameter } from '@aws-lambda-powertools/parameters/ssm';

export const handler = async (): Promise => {
  // Retrieve and deserialize a single JSON parameter
  const valueFromJson = await getParameter('/my/json/parameter', { transform: Transform.JSON });
  console.log(valueFromJson);
};

参数实用程序支持所有参数存储提供程序和高级函数的 转换 参数。有关详细信息,请参见 使用转换参数 反序列化值

在 SSM 参数存储中使用加密参数

SSM Parameter Store 支持通过 亚马逊云科技 密钥管理服务 (亚马逊云科技 KMS) 加密的安全字符串参数。参数实用程序允许您通过在请求中添加 解密参数来检索这些加密 参数。

例如,您可以按如下方式检索加密参数:

import { getParameter } from '@aws-lambda-powertools/parameters/ssm';

export const handler = async (): Promise<void> => {
  // Decrypt the parameter
  const decryptedParameter = await getParameter('/my/encrypted/parameter', { decrypt: true });
  console.log(decryptedParameter);
};

在这种情况下,除了 ssm: getParameter 之外,Lambda 函数执行角色还需要拥有 kms: Decrypt IAM 权限。

从 SSM 参数存储中检索多个参数

除了使用 getParameter 检索单个参数外,您还可以使用 getParam et ers 以递归方式检索 SSM 参数存储路径下的多个参数,或者使用 getParametersByName 按其全名检索 多个不同的参数。

使用 getParameter sByName 时,您还可以对每个参数应用自定义缓存、转换或解密配置。以下示例使用不同的缓存和转换配置从 SSM Parameter Store 中检索三个不同的参数:

import { getParametersByName } from '@aws-lambda-powertools/parameters/ssm';
import type {
  SSMGetParametersByNameOptionsInterface
} from '@aws-lambda-powertools/parameters/ssm/types';

const props: Record<string, SSMGetParametersByNameOptionsInterface> = {
  '/develop/service/commons/telemetry/config': { maxAge: 300, transform: 'json' },
  '/no_cache_param': { maxAge: 0 },
  '/develop/service/payment/api/capture/url': {}, // When empty or undefined, it uses default values
};

export const handler = async (): Promise<void> => {
  // This returns an object with the parameter name as key
  const parameters = await getParametersByName(props);
  for (const [ key, value ] of Object.entries(parameters)) {
    console.log(`${key}: ${value}`);
  }
};

检索多个参数需要 Lamb da 函数执行角色中具 有 getPar ameter 和 get Parameters 权限。

从密钥管理器中检索密钥

为了安全地存储敏感参数,例如外部服务的密码或 API 密钥,Secrets Manager 是一个合适的选择。要使用参数实用程序从密钥管理器检索密钥,除了参数实用程序外,还要安装适用于密钥管理器的 亚马逊云科技 开发工具包客户端:

npm install @aws-sdk/client-secrets-manager

现在,您可以使用密钥访问密钥,如下所示:

import { getSecret } from '@aws-lambda-powertools/parameters/secrets';

export const handler = async (): Promise<void> => {
  // Retrieve a single secret
  const secret = await getSecret('my-secret');
  console.log(secret);
};

从 Secrets Manager 获取密钥需要你将 secretsMan ager: getSecretValue IAM 权限添加到你的 Lam bda 函数执行角色中。

从 AppConfig 检索应用程序配置

如果您计划在基于 Lambda 构建的应用程序中利用 功能标志 或动态应用程序配置,AppConfig 是一个合适的选择。参数实用程序使您可以轻松地从 AppConfig 获取配置,同时受益于缓存和转换等实用功能。

例如,假设一个名为 my-app 的 AppConfig 应用程序的环境名为 my- env,您可以按如下方式检索其配置文件 my- configuration:

import { getAppConfig } from '@aws-lambda-powertools/parameters/appconfig';

export const handler = async (): Promise<void> => {
  // Retrieve a configuration, latest version
  const config = await getAppConfig('my-configuration', {
    environment: 'my-env',
    application: 'my-app'
  });
  console.log(config);
};

检索配置需要将 appConfi g: getLatestConfig uration 和 appConfig: startConfigurationSession IAM 权限都附加 到 L ambda 函数执行角色。

从 DynamoDB 表中检索参数

DynamoDB 的低延迟和高灵活性使其成为存储参数的绝佳选择。要通过参数实用程序将 DynamoDB 用作参数存储,除了参数实用程序外,还要安装 DynamoDB 亚马逊云科技 开发工具包客户端和实用程序包。

npm install @aws-sdk/client-dynamodb @aws-sdk/util-dynamodb

默认情况下,参数实用程序期望包含参数的 DynamoDB 表具有 id 的 分区键 和名为值的属性。例如,假设项目的 ID 为 my-parameter,值为 my- value 存储在名为 my-table 的 Dy namoDB 表中,则可以按如下方式检索该项目:

import { DynamoDBProvider } from '@aws-lambda-powertools/parameters/dynamodb';

const dynamoDBProvider = new DynamoDBProvider({ tableName: 'my-table' });

export const handler = async (): Promise<void> => {
  // Retrieve a value from DynamoDB
  const value = await dynamoDBProvider.get('my-parameter');
  console.log(value);
};

如果从 DynamoDB 检索单个参数,Lambda 函数执行角色需要拥有 dynamoDB: getItem IAM 权限。

参数实用程序 DynamoDB 提供者还可以通过 Dynam oDB 查询通过单个请求从表中检索多个参数。 有关详细信息,请参阅 Powert ools for 亚马逊云科技 Lambda(TypeScript)文档 中的 DynamoDB 提供商

结论

这篇博文介绍了适用于 亚马逊云科技 Lambda 的 Powertools(TypeScript)参数实用程序,并演示了如何将其用于不同的参数存储。参数实用程序允许您从 SSM 参数存储库、密钥管理器、AppConfig、DynamoDB 和自定义参数存储中检索 Lambda 函数中的密钥和参数。通过使用该实用程序,您可以访问诸如缓存和转换之类的功能,并减少需要为 Lambda 函数编写的样板代码量。

要了解有关参数实用程序及其全套功能的更多信息,请查看 适用于 亚马逊云科技 Lambda 的 Powertools (TypeScript) 文档。

打开 GitHub 问题,分享你对 Powertools for 亚马逊云科技 Lambda(TypeScript)的反馈。

如需更多无服务器学习资源,请访问 无服务器世界