在 Lambda 函数中使用 Secrets Manager 密钥
Amazon Secrets Manager 可帮助您管理 Lambda 函数所需的凭证、API 密钥和其他密钥。您有两种主要方法可以在 Lambda 函数中检索密钥,与直接使用 Amazon SDK 检索密钥相比,这两种方法的性能更佳且成本更低:
-
Amazon 参数和密钥 Lambda 扩展 - 一种与运行时无关的解决方案,提供一个简单的 HTTP 接口来检索密钥
-
Powertools for Amazon Lambda 参数实用程序 - 支持多个提供商(Secrets Manager、Parameter Store、AppConfig)的代码集成解决方案,具有内置转换功能
这两种方法都维护密钥的本地缓存,从而无需您的函数在每次调用时都调用 Secrets Manager。当您的函数请求密钥时,将首先检查缓存。如果密钥可用且尚未过期,则会立即返回该密钥。否则,将从 Secrets Manager 中检索、缓存并返回密钥。这种缓存机制通过最大限度地减少 API 调用,可以缩短响应时间并降低成本。
选择方法
在扩展和 PowerTools 之间进行选择时,请考虑以下因素:
- 在以下情况下使用 Amazon 参数和密钥 Lambda 扩展:
-
您需要一个与任何 Lambda 运行时兼容的、与运行时无关的解决方案
您不想在函数中添加代码依赖项
您只需从 Secrets Manager 或 Parameter Store 检索密钥
- 在以下情况下使用 Powertools for Amazon Lambda 参数实用程序:
-
您想要获得与应用程序代码集成的开发体验
您需要支持多个提供商(Secrets Manager、Parameter Store、AppConfig)
您需要内置数据转换(JSON 解析、base64 解码)
您正在使用 Python、TypeScript、Java 或 .NET 运行时
何时将 Secrets Manager 与 Lambda 结合使用
将 Secrets Manager 与 Lambda 结合使用的常见场景包括:
-
存储您的函数用于连接到 Amazon RDS 或其他数据库的数据库凭证
-
管理您的函数调用的外部服务的 API 密钥
-
存储加密密钥或其他敏感配置数据
-
自动轮换凭证,无需更新函数代码
使用 Amazon 参数和密钥 Lambda 扩展
Amazon 参数和密钥 Lambda 扩展使用与任何 Lambda 运行时兼容的简单 HTTP 接口。默认情况下,它会缓存密钥 300 秒(5 分钟),最多可容纳 1,000 个密钥。您可以使用环境变量自定义这些设置。
在 Lambda 函数中使用 Secrets Manager
本节假设您已经拥有 Secrets Manager 密钥。要创建密钥,请参阅 Create an Amazon Secrets Manager secret。
选择您的首选运行时,并按照步骤创建用于从 Secrets Manager 检索密钥的函数。该示例函数从 Secrets Manager 中检索密钥,并可用于访问数据库凭证、API 密钥或应用程序中的其他敏感配置数据。
打开 Lamba 控制台的 Functions page
(函数页面)。 -
选择 Create function(创建函数)。
-
选择从头开始编写。
-
对于函数名称,请输入
secret-retrieval-demo。 -
选择您的首选运行时。
-
选择创建函数。
上传部署包
-
在函数的代码选项卡中,选择上传自,然后选择 .zip 文件(对于 Python 和 Node.js)或 .jar 文件(对于 Java)。
-
上传您之前创建的部署包。
-
选择保存。
将 Amazon 参数和密钥 Lambda 扩展添加为层
-
在函数的代码选项卡中,向下滚动到层。
-
选择 Add a layer。
-
选择 Amazon 层。
-
选择 Amazon-Parameters-and-Secrets-Lambda-Extension。
-
选择最新版本。
-
选择添加。
向您的执行角色添加 Secrets Manager 权限
-
选择 Configuration(配置)选项卡,然后选择 Permissions(权限)。
-
在角色名称下,选择至执行角色的链接。此角色将在 IAM 控制台中打开角色。
-
选择添加权限,然后选择创建内联策略。
-
选择 JSON 选项卡,然后添加以下策略。对于
Resource,输入您的密钥的 ARN。 -
选择下一步。
-
输入策略的名称。
-
选择创建策略。
测试此函数
-
返回 Lambda 控制台。
-
选择测试选项卡。
-
选择测试。您应看到以下响应:
环境变量
Amazon 参数和密钥 Lambda 扩展使用下面的默认设置。您可以通过创建相应的环境变量来覆盖这些设置。要查看函数的当前设置,请将 PARAMETERS_SECRETS_EXTENSION_LOG_LEVEL 设置为 DEBUG。该扩展将在每次函数调用开始时将其配置信息记录到 CloudWatch Logs 中。
| 设置 | 默认值 | 有效值 | 环境变量 | 详细信息 |
|---|---|---|---|---|
| HTTP 端口 | 2773 | 1-65535 | PARAMETERS_SECRETS_EXTENSION_HTTP_PORT | 本地 HTTP 服务器的端口 |
| 已启用缓存 | TRUE | TRUE | FALSE | PARAMETERS_SECRETS_EXTENSION_CACHE_ENABLED | 启用或禁用缓存 |
| 缓存大小 | 1000 | 0 - 1000 | PARAMETERS_SECRETS_EXTENSION_CACHE_SIZE | 设置为 0 以禁用缓存 |
| Secrets Manager TTL | 300 秒 | 0 - 300 秒 | SECRETS_MANAGER_TTL | 缓存密钥的生存时间。设置为 0 以禁用缓存。如果 PARAMETERS_SECRETS_EXTENSION_CACHE_SIZE 的值为 0,则忽略此变量。 |
| Parameter Store TTL | 300 秒 | 0 - 300 秒 | SSM_PARAMETER_STORE_TTL | 缓存参数的生存时间。设置为 0 以禁用缓存。如果 PARAMETERS_SECRETS_EXTENSION_CACHE_SIZE 的值为 0,则忽略此变量。 |
| 日志级别 | INFO | 调试 | 信息 | 警告 | 错误 | 无 | PARAMETERS_SECRETS_EXTENSION_LOG_LEVEL | 扩展日志中报告的详细信息级别 |
| 最大连接数 | 3 | 1 或更多 | PARAMETERS_SECRETS_EXTENSION_MAX_CONNECTIONS | 对 Parameter Store 或 Secrets Manager 的请求的最大 HTTP 连接数 |
| Secrets Manager 超时 | 0(无超时) | 所有整数 | SECRETS_MANAGER_TIMEOUT_MILLIS | Secrets Manager 的请求超时(以毫秒为单位) |
| Parameter Store 超时 | 0(无超时) | 所有整数 | SSM_PARAMETER_STORE_TIMEOUT_MILLIS | Parameter Store 的请求超时(以毫秒为单位) |
使用密钥轮换
如果频繁轮换密钥,则默认 300 秒缓存持续时间可能会导致您的函数使用过时的密钥。您有两种方法可以确保函数使用最新的密钥值:
-
通过将
SECRETS_MANAGER_TTL环境变量设置为较低的值(以秒为单位)来缩短缓存 TTL。例如,将其设置为60可确保函数永远不会使用超过一分钟的密钥。 -
在密钥请求中使用
AWSCURRENT或AWSPREVIOUS暂存标签来确保获得所需的特定版本:secretsmanager/get?secretId=YOUR_SECRET_NAME&versionStage=AWSCURRENT
选择最能平衡您对性能和新鲜度需求的方法。较低 TTL 意味着对 Secrets Manager 的调用更频繁,但可确保您使用最新的密钥值。
使用 Powertools for Amazon Lambda 中的参数实用程序
Powertools for Amazon Lambda 中的参数实用程序提供了一个统一的界面,用于从多个提供商(包括 Secrets Manager、Parameter Store 和 AppConfig)检索密钥。它处理缓存、转换,并提供与扩展方法相比更加集成的开发体验。
参数实用程序的好处
多个提供商 - 使用相同的接口从 Secrets Manager、Parameter Store 和 AppConfig 检索参数
内置转换 - 自动 JSON 解析、base64 解码和其他数据转换
集成缓存 - 支持 TTL 的可配置缓存,可减少 API 调用
键入安全 - 在 TypeScript 和其他支持的运行时中提供强大的键入支持
错误处理 - 内置重试逻辑和错误处理
代码示例
以下示例展示了如何在不同的运行时使用参数实用程序检索密钥:
- Python
-
注意
有关完整示例和设置说明,请参阅参数实用程序文档
。 使用 Powertools for Amazon Lambda 参数实用程序从 Secrets Manager 中检索密钥。
from aws_lambda_powertools import Logger from aws_lambda_powertools.utilities import parameters logger = Logger() def lambda_handler(event, context): try: # Get secret with caching (default TTL: 5 seconds) secret_value = parameters.get_secret("my-secret-name") # Get secret with custom TTL secret_with_ttl = parameters.get_secret("my-secret-name", max_age=300) # Get secret and transform JSON secret_json = parameters.get_secret("my-json-secret", transform="json") logger.info("Successfully retrieved secrets") return { 'statusCode': 200, 'body': 'Successfully retrieved secrets' } except Exception as e: logger.error(f"Error retrieving secret: {str(e)}") return { 'statusCode': 500, 'body': f'Error: {str(e)}' } - TypeScript
-
注意
有关完整示例和设置说明,请参阅参数实用程序文档
。 使用 Powertools for Amazon Lambda 参数实用程序从 Secrets Manager 中检索密钥。
import { Logger } from '@aws-lambda-powertools/logger'; import { getSecret } from '@aws-lambda-powertools/parameters/secrets'; import type { Context } from 'aws-lambda'; const logger = new Logger(); export const handler = async (event: any, context: Context) => { try { // Get secret with caching (default TTL: 5 seconds) const secretValue = await getSecret('my-secret-name'); // Get secret with custom TTL const secretWithTtl = await getSecret('my-secret-name', { maxAge: 300 }); // Get secret and transform JSON const secretJson = await getSecret('my-json-secret', { transform: 'json' }); logger.info('Successfully retrieved secrets'); return { statusCode: 200, body: 'Successfully retrieved secrets' }; } catch (error) { logger.error('Error retrieving secret', { error }); return { statusCode: 500, body: `Error: ${error}` }; } }; - Java
-
注意
有关完整示例和设置说明,请参阅参数实用程序文档
。 使用 Powertools for Amazon Lambda 参数实用程序从 Secrets Manager 中检索密钥。
import software.amazon.lambda.powertools.logging.Logging; import software.amazon.lambda.powertools.parameters.SecretsProvider; import software.amazon.lambda.powertools.parameters.ParamManager; import com.amazonaws.services.lambda.runtime.Context; import com.amazonaws.services.lambda.runtime.RequestHandler; public class SecretHandler implements RequestHandler<Object, String> { private final SecretsProvider secretsProvider = ParamManager.getSecretsProvider(); @Logging @Override public String handleRequest(Object input, Context context) { try { // Get secret with caching (default TTL: 5 seconds) String secretValue = secretsProvider.get("my-secret-name"); // Get secret with custom TTL (300 seconds) String secretWithTtl = secretsProvider.withMaxAge(300).get("my-secret-name"); // Get secret and transform JSON MySecret secretJson = secretsProvider.get("my-json-secret", MySecret.class); return "Successfully retrieved secrets"; } catch (Exception e) { return "Error retrieving secret: " + e.getMessage(); } } public static class MySecret { // Define your secret structure here } } - .NET
-
注意
有关完整示例和设置说明,请参阅参数实用程序文档
。 使用 Powertools for Amazon Lambda 参数实用程序从 Secrets Manager 中检索密钥。
using AWS.Lambda.Powertools.Logging; using AWS.Lambda.Powertools.Parameters; using Amazon.Lambda.Core; [assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] public class Function { private readonly ISecretsProvider _secretsProvider; public Function() { _secretsProvider = ParametersManager.SecretsProvider; } [Logging] public async Task<string> FunctionHandler(object input, ILambdaContext context) { try { // Get secret with caching (default TTL: 5 seconds) var secretValue = await _secretsProvider.GetAsync("my-secret-name"); // Get secret with custom TTL var secretWithTtl = await _secretsProvider.WithMaxAge(TimeSpan.FromMinutes(5)) .GetAsync("my-secret-name"); // Get secret and transform JSON var secretJson = await _secretsProvider.GetAsync<MySecret>("my-json-secret"); return "Successfully retrieved secrets"; } catch (Exception e) { return $"Error retrieving secret: {e.Message}"; } } public class MySecret { // Define your secret structure here } }
设置和权限
要使用参数实用程序,您需要:
为您的运行时安装 Powertools for Amazon Lambda。有关更多信息,请参阅 Powertools for Amazon Lambda。
向您的函数的执行角色添加必要的 IAM 权限。有关详细信息,请参阅在 Amazon Lambda 中管理权限。
通过环境变量配置任何可选设置。
所需的 IAM 权限与扩展方法相同。该实用程序将根据您的配置自动处理缓存和对 Secrets Manager 的 API 调用。