在 Lambda 函式中使用 Secrets Manager 秘密
AWS Secrets Manager 可協助您管理 Lambda 函式所需的憑證、API 金鑰和其他秘密。在 Lambda 函式中擷取秘密有兩種主要方案,與直接透過 AWS SDK 擷取秘密相比,這兩種方案皆能提供更佳的效能與更低的成本:
-
AWS Parameters and Secrets Lambda 延伸 – 一種與執行時期無關的解決方案,提供簡單的 HTTP 介面來擷取秘密
-
Powertools for AWS Lambda 參數公用程式 – 一種程式碼整合解決方案,支援多個具有內建轉換功能的提供者 (Secrets Manager、Parameter Store、AppConfig)
這兩種方案都會維護秘密的本機快取,無需函式在每次調用時都呼叫 Secrets Manager。當您的函式請求秘密時,會先檢查快取。如果秘密可用且未過期,則會立即傳回。否則,會從 Secrets Manager 中擷取秘密,快取後再傳回。此快取機制透過最大限度地減少 API 呼叫次數來縮短回應時間並降低成本。
選擇合適方案
在延伸模組與 PowerTools 之間進行選擇時,建議考量以下因素:
- 在下列情況下,請使用 AWS Parameters and Secrets Lambda 延伸:
-
您想要一種與執行時期無關的解決方案,並且其可與任何 Lambda 執行時期搭配使用
您不想將程式碼相依項新增至函式
您僅需從 Secrets Manager 或 Parameter Store 中擷取秘密
- 在下列情況下,請使用 Powertools for AWS Lambda 參數公用程式:
-
您希望獲得與應用程式程式碼整合的開發體驗
您需要支援多個提供者 (Secrets Manager、Parameter Store、AppConfig)
您需要內建的資料轉換功能 (JSON 剖析、base64 解碼)
您目前使用的是 Python、TypeScript、Java 或 .NET 執行時期
何時將 Secrets Manager 與 Lambda 搭配使用
將 Secrets Manager 與 Lambda 搭配使用的常見案例包括:
-
儲存函式用來連線至 Amazon RDS 或其他資料庫的資料庫憑證
-
管理函式呼叫之外部服務的 API 金鑰
-
儲存加密金鑰或其他敏感組態資料
-
自動輪換憑證,而無需更新函式程式碼
使用 AWS Parameters and Secrets Lambda 延伸
AWS Parameters and Secrets Lambda 延伸模組使用與所有 Lambda 執行時期均相容的簡單 HTTP 介面。依預設,該功能會快取秘密 300 秒 (5 分鐘),並且最多可保留 1,000 個秘密。您可以使用環境變數自訂這些設定。
在 Lambda 函式中使用 Secrets Manager
本節假設您已擁有一個 Secrets Manager 秘密。若要建立秘密,請參閱建立 AWS Secrets Manager 秘密。
選擇您偏好的執行時期,並依照步驟建立從 Secrets Manager 中擷取秘密的函式。範例函式會從 Secrets Manager 中擷取秘密,並可用來存取應用程式中的資料庫憑證、API 金鑰或其他敏感組態資料。
開啟 Lambda 主控台中的 函數頁面
。 -
選擇建立函數。
-
選取從頭開始撰寫。
-
針對函數名稱,請輸入
secret-retrieval-demo。 -
選擇偏好的執行時期。
-
選擇 Create function (建立函數)。
若要上傳部署套件
-
在函式的程式碼索引標籤中,選擇上傳來源,然後選擇 .zip 檔案 (適用於 Python 與 Node.js) 或 .jar 檔案 (適用於 Java)。
-
上傳先前建立的部署套件。
-
選擇儲存。
若要將 AWS Parameters and Secrets Lambda 延伸模組新增為層
-
在函式的程式碼索引標籤中,向下捲動至層。
-
選擇 Add a layer (新增 layer)。
-
選擇 AWS 層。
-
選擇 AWS-Parameters-and-Secrets-Lambda-Extension。
-
選擇最新版本。
-
選擇新增。
若要將 Secrets Manager 許可新增至執行角色
-
依序選擇 Configuration (組態) 索引標籤和 Permissions (許可)。
-
在角色名稱下面,選擇執行角色連結。此連結會在 IAM 主控台中開啟該角色。
-
選擇新增許可,然後選擇建立內嵌政策。
-
選擇 JSON 索引標籤,並新增下列政策。在
Resource欄位中輸入秘密的 ARN。 -
選擇下一步。
-
輸入政策的名稱。
-
選擇建立政策。
若要測試函數
-
返回 Lambda 主控台。
-
選取測試索引標籤。
-
選擇測試。您應該會看到下列回應:
環境變數
AWS Parameters and Secrets 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 | DEBUG | INFO | WARN | ERROR | NONE | 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 AWS Lambda 中的參數公用程式
Powertools for AWS Lambda 中的參數公用程式提供了統一介面,用於從多個提供者中擷取秘密,包括 Secrets Manager、Parameter Store 和 AppConfig。該方案會處理快取、轉換作業,且相較於延伸模組方案,能提供整合更緊密的開發體驗。
參數公用程式的優點
多個提供者 – 使用同一個介面從 Secrets Manager、Parameter Store 和 AppConfig 中擷取參數
內建轉換功能 – 自動 JSON 剖析、base64 解碼和其他資料轉換
整合式快取 – 具有 TTL 支援的可設定快取,可減少 API 呼叫次數
型別安全 – 在 TypeScript 與其他支援的執行時期中提供強型別支援
錯誤處理 – 內建重試邏輯和錯誤處理
程式碼範例
下列範例示範如何在不同的執行時期中使用參數公用程式擷取秘密:
- Python
-
注意
如需完整的範例和設定說明,請參閱 Parameters utility documentation
。 使用 Powertools for AWS 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
-
注意
如需完整的範例和設定說明,請參閱 Parameters utility documentation。
使用 Powertools for AWS 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
-
注意
如需完整的範例和設定說明,請參閱 Parameters utility documentation
。 使用 Powertools for AWS 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
-
注意
如需完整的範例和設定說明,請參閱 Parameters utility documentation。
使用 Powertools for AWS 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 AWS Lambda。如需詳細資訊,請參閱 Powertools for AWS Lambda。
將必要的 IAM 許可新增至函式的執行角色。請參閱 在 AWS Lambda 中管理許可 以取得詳細資訊。
透過環境變數來進行選用設定。
所需的 IAM 許可與延伸模組方案相同。參數公用程式會根據您的組態自動處理對 Secrets Manager 的快取和 API 呼叫。