Utiliser des secrets Secrets Manager dans des fonctions Lambda - AWS Lambda

Utiliser des secrets Secrets Manager dans des fonctions Lambda

AWS Secrets Manager vous aide à gérer les informations d’identification, les clés d’API et les autres secrets dont vos fonctions Lambda ont besoin. Vous disposez de deux approches principales pour récupérer des secrets dans vos fonctions Lambda, toutes deux offrant de meilleures performances et des coûts réduits par rapport à la récupération de secrets directement à l’aide du SDK AWS :

  • Extension AWS Parameters and Secrets Lambda : solution indépendante de l’environnement d’exécution qui fournit une interface HTTP simple pour récupérer les secrets

  • Utilitaire de paramètres Powertools pour AWS Lambda : solution intégrée au code qui prend en charge plusieurs fournisseurs (Secrets Manager, Parameter Store, AppConfig) avec des transformations intégrées

Les deux approches conservent des caches locaux de secrets, ce qui évite à votre fonction d’appeler Secrets Manager pour chaque invocation. Lorsque votre fonction demande un secret, le cache est d’abord vérifié. Si le secret est disponible et n’a pas expiré, il est renvoyé immédiatement. Sinon, il est extrait de Secrets Manager, mis en cache et renvoyé. Ce mécanisme de mise en cache permet d’accélérer les temps de réponse et de réduire les coûts en minimisant les appels d’API.

Choix d’une approche

Tenez compte des facteurs suivants lorsque vous choisissez entre l’extension et Powertools :

Utilisez l’extension Lambda AWS Parameters and Secrets quand :
  • Vous recherchez une solution indépendante de l’environnement d’exécution qui fonctionne avec n’importe quel environnement d’exécution Lambda

  • Vous préférez ne pas ajouter de dépendances de code à votre fonction

  • Vous souhaitez seulement récupérer des secrets à partir de Secrets Manager ou de Parameter Store

Utilisez l’utilitaire de paramètres Powertools pour AWS Lambda quand :
  • Vous souhaitez bénéficier d’une expérience de développement intégrée au code de votre application

  • Vous avez besoin de la prise en charge de plusieurs fournisseurs (Secrets Manager, Parameter Store, AppConfig)

  • Vous souhaitez des transformations de données intégrées (analyse JSON, décodage Base64)

  • Vous utilisez des environnements d’exécution Python, TypeScript, Java ou .NET

Quand utiliser Secrets Manager avec Lambda

Les scénarios courants d’utilisation de Secrets Manager avec Lambda comprennent les suivants :

  • Stockage d’informations d’identification de base de données que votre fonction utilise pour se connecter à Amazon RDS ou d’autres bases de données

  • Gestion des clés d’API pour les services externes appelés par votre fonction

  • Stockage des clés de chiffrement ou d’autres données de configuration sensibles

  • Rotation automatique des informations d’identification sans qu’il soit nécessaire de mettre à jour le code de votre fonction

Utilisation de l’extension Lambda AWS Parameters and Secrets

L’extension Lambda AWS Parameters and Secrets utilise une interface HTTP simple compatible avec n’importe quel environnement d’exécution Lambda. Par défaut, elle met en cache les secrets pendant 300 secondes (5 minutes) et peut contenir jusqu’à 1 000 secrets. Vous pouvez personnaliser ces paramètres à l’aide de variables d’environnement.

Utiliser Secrets Manager dans une fonction Lambda

Cette section part du principe que vous possédez déjà un secret Secrets Manager. Pour créer un secret, consultez Créer un secret AWS Secrets Manager.

Choisissez votre environnement d’exécution préféré et suivez les étapes pour créer une fonction qui récupère les secrets depuis Secrets Manager. L’exemple de fonction extrait un secret dans Secrets Manager et peut être utilisé pour accéder aux informations d’identification de base de données, aux clés d’API ou à d’autres données de configuration sensibles dans vos applications.

Python
Pour créer une fonction Python
  1. Créez et accédez à un nouveau répertoire de projet. Exemple :

    mkdir my_function cd my_function
  2. Créez un fichier nommé lambda_function.py avec le code suivant. Pour secret_name, utilisez le nom ou l’Amazon Resource Name (ARN) de votre secret.

    import json import os import requests def lambda_handler(event, context): try: # Replace with the name or ARN of your secret secret_name = "arn:aws:secretsmanager:us-east-1:111122223333:secret:SECRET_NAME" secrets_extension_endpoint = f"http://localhost:2773/secretsmanager/get?secretId={secret_name}" headers = {"X-Aws-Parameters-Secrets-Token": os.environ.get('AWS_SESSION_TOKEN')} response = requests.get(secrets_extension_endpoint, headers=headers) print(f"Response status code: {response.status_code}") secret = json.loads(response.text)["SecretString"] print(f"Retrieved secret: {secret}") return { 'statusCode': response.status_code, 'body': json.dumps({ 'message': 'Successfully retrieved secret', 'secretRetrieved': True }) } except Exception as e: print(f"Error: {str(e)}") return { 'statusCode': 500, 'body': json.dumps({ 'message': 'Error retrieving secret', 'error': str(e) }) }
  3. Créez un fichier nommé requirements.txt avec ce contenu :

    requests
  4. Installez les dépendances :

    pip install -r requirements.txt -t .
  5. Créez un fichier .zip contenant tous les fichiers :

    zip -r function.zip .
Node.js
Pour créer une fonction Node.js.
  1. Créez et accédez à un nouveau répertoire de projet. Exemple :

    mkdir my_function cd my_function
  2. Créez un fichier nommé index.mjs avec le code suivant. Pour secret_name, utilisez le nom ou l’Amazon Resource Name (ARN) de votre secret.

    import http from 'http'; export const handler = async (event) => { try { // Replace with the name or ARN of your secret const secretName = "arn:aws:secretsmanager:us-east-1:111122223333:secret:SECRET_NAME"; const options = { hostname: 'localhost', port: 2773, path: `/secretsmanager/get?secretId=${secretName}`, headers: { 'X-Aws-Parameters-Secrets-Token': process.env.AWS_SESSION_TOKEN } }; const response = await new Promise((resolve, reject) => { http.get(options, (res) => { let data = ''; res.on('data', (chunk) => { data += chunk; }); res.on('end', () => { resolve({ statusCode: res.statusCode, body: data }); }); }).on('error', reject); }); const secret = JSON.parse(response.body).SecretString; console.log('Retrieved secret:', secret); return { statusCode: response.statusCode, body: JSON.stringify({ message: 'Successfully retrieved secret', secretRetrieved: true }) }; } catch (error) { console.error('Error:', error); return { statusCode: 500, body: JSON.stringify({ message: 'Error retrieving secret', error: error.message }) }; } };
  3. Créez un fichier .zip contient le fichier index.mjs.

    zip -r function.zip index.mjs
Java
Pour créer une fonction Java
  1. Créez un projet Maven :

    mvn archetype:generate \ -DgroupId=example \ -DartifactId=lambda-secrets-demo \ -DarchetypeArtifactId=maven-archetype-quickstart \ -DarchetypeVersion=1.4 \ -DinteractiveMode=false
  2. Accédez au répertoire du projet :

    cd lambda-secrets-demo
  3. Ouvrez pom.xml et remplacez le contenu par ce qui suit :

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>example</groupId> <artifactId>lambda-secrets-demo</artifactId> <version>1.0-SNAPSHOT</version> <properties> <maven.compiler.source>11</maven.compiler.source> <maven.compiler.target>11</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-lambda-java-core</artifactId> <version>1.2.1</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.2.4</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <createDependencyReducedPom>false</createDependencyReducedPom> <finalName>function</finalName> </configuration> </execution> </executions> </plugin> </plugins> </build> </project>
  4. Renommez /lambda-secrets-demo/src/main/java/example/App.java en Hello.java pour qu’il corresponde au nom du gestionnaire Java par défaut de Lambda (example.Hello::handleRequest) :

    mv src/main/java/example/App.java src/main/java/example/Hello.java
  5. Ouvrez le fichier Hello.java et remplacez son contenu par ce qui suit. Pour secretName, utilisez le nom ou l’Amazon Resource Name (ARN) de votre secret.

    package example; import com.amazonaws.services.lambda.runtime.Context; import com.amazonaws.services.lambda.runtime.RequestHandler; import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; public class Hello implements RequestHandler<Object, String> { private final HttpClient client = HttpClient.newHttpClient(); @Override public String handleRequest(Object input, Context context) { try { // Replace with the name or ARN of your secret String secretName = "arn:aws:secretsmanager:us-east-1:111122223333:secret:SECRET_NAME"; String endpoint = "http://localhost:2773/secretsmanager/get?secretId=" + secretName; HttpRequest request = HttpRequest.newBuilder() .uri(URI.create(endpoint)) .header("X-Aws-Parameters-Secrets-Token", System.getenv("AWS_SESSION_TOKEN")) .GET() .build(); HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString()); String secret = response.body(); secret = secret.substring(secret.indexOf("SecretString") + 15); secret = secret.substring(0, secret.indexOf("\"")); System.out.println("Retrieved secret: " + secret); return String.format( "{\"statusCode\": %d, \"body\": \"%s\"}", response.statusCode(), "Successfully retrieved secret" ); } catch (Exception e) { e.printStackTrace(); return String.format( "{\"body\": \"Error retrieving secret: %s\"}", e.getMessage() ); } } }
  6. Supprimez le répertoire de test. Maven le crée par défaut, mais nous n’en avons pas besoin pour cet exemple.

    rm -rf src/test
  7. Générez le projet :

    mvn package
  8. Téléchargez le fichier JAR (target/function.jar) pour une utilisation ultérieure.

  1. Ouvrez la page Functions (Fonctions) de la console Lambda.

  2. Choisissez Créer une fonction.

  3. Sélectionnez Créer à partir de zéro.

  4. Sous Nom de la fonction, saisissez secret-retrieval-demo.

  5. Choisissez votre Environnement d’exécution préféré.

  6. Choisissez Créer une fonction.

Charger un package de déploiement
  1. Dans l’onglet Code de la fonction, choisissez Charger à partir de et sélectionnez Fichier .zip (pour Python et Node.js) ou Fichier .jar (pour Java).

  2. Chargez le package de déploiement créé précédemment.

  3. Choisissez Enregistrer.

Ajouter l’extension Lambda AWS Parameters and Secrets en tant que couche
  1. Dans l’onglet Code de la fonction, faites défiler la page jusqu’à Couches.

  2. Choisissez Add a layer (Ajouter une couche).

  3. Sélectionnez Couches AWS.

  4. Choisissez AWS-Parameters-and-Secrets-Lambda-Extension.

  5. Sélectionnez la dernière version.

  6. Choisissez Ajouter.

Ajouter des autorisations Secrets Manager à votre rôle d’exécution
  1. Choisissez l’onglet Configuration, puis Permissions (Autorisations).

  2. Sous Nom du rôle, cliquez sur le lien vers votre rôle d’exécution. Ce lien ouvre le rôle dans la console IAM.

    Lien vers le rôle d’exécution
  3. Sélectionnez Ajouter des autorisations, puis Ajouter la politique.

    Attacher des politiques dans la console IAM
  4. Choisissez l’onglet JSON et ajoutez la politique suivante. Pour Resource, saisissez l’ARN de votre secret.

    JSON
    { "Version":"2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "secretsmanager:GetSecretValue", "Resource": "arn:aws:secretsmanager:us-east-1:111122223333:secret:SECRET_NAME" } ] }
  5. Choisissez Suivant.

  6. Entrez le nom de la politique.

  7. Choisissez Créer une politique.

Pour tester la fonction
  1. Retournez à la console Lambda.

  2. Sélectionnez l’onglet Test.

  3. Sélectionnez Tester). Vous devriez voir la réponse suivante :

    Résultat de test réussi

Variables d’environnement

L’extension Lambda AWS Parameters and Secrets utilise les paramètres par défaut suivants. Vous pouvez remplacer ces paramètres en créant les variables d’environnement correspondantes. Pour afficher les paramètres actuels d’une fonction, réglez PARAMETERS_SECRETS_EXTENSION_LOG_LEVEL sur DEBUG. L’extension enregistre ses informations de configuration dans CloudWatch Logs au début de chaque invocation de fonction.

Paramètre Valeur par défaut Valeurs valides Variable d'environnement Détails
Port HTTP 2773 1 – 65535 PARAMETERS_SECRETS_EXTENSION_HTTP_PORT Port du serveur HTTP local
Cache activé TRUE TRUE | FALSE PARAMETERS_SECRETS_EXTENSION_CACHE_ENABLED Activer ou désactiver le cache
Taille du cache 1 000 0 - 1000 PARAMETERS_SECRETS_EXTENSION_CACHE_SIZE Définissez cette valeur sur 0 pour désactiver la mise en cache
TTL de Secrets Manager 300 secondes 0 à 300 secondes SECRETS_MANAGER_TTL Durée de vie des secrets mis en cache. Définissez sur 0 pour désactiver la mise en cache. Cette variable est ignorée si la valeur de PARAMETERS_SECRETS_EXTENSION_CACHE_SIZE est de 0.
TTL du magasin de paramètres 300 secondes 0 à 300 secondes SSM_PARAMETER_STORE_TTL Durée de vie des paramètres mis en cache. Définissez sur 0 pour désactiver la mise en cache. Cette variable est ignorée si la valeur de PARAMETERS_SECRETS_EXTENSION_CACHE_SIZE est de 0.
Niveau de journalisation INFO DEBUG | INFO | WARN | ERROR | NONE PARAMETERS_SECRETS_EXTENSION_LOG_LEVEL Le niveau de détail indiqué dans les journaux pour l’extension
Nombre maximal de connexions 3 1 ou plus PARAMETERS_SECRETS_EXTENSION_MAX_CONNECTIONS Nombre maximum de connexions HTTP pour les requêtes à Parameter Store ou Secrets Manager.
Délai d’expiration de Secrets Manager 0 (n’expire pas) Tous les nombres entiers SECRETS_MANAGER_TIMEOUT_MILLIS Délai d’expiration des requêtes adressées à Secrets Manager (en millisecondes)
Délai d’expiration de Parameter Store 0 (n’expire pas) Tous les nombres entiers SSM_PARAMETER_STORE_TIMEOUT_MILLIS Délai d’expiration des requêtes adressées au Parameter Store (en millisecondes)

Utilisation d’une rotation des secrets

Si vous alternez fréquemment les secrets, la durée de cache par défaut de 300 secondes peut entraîner l’utilisation de secrets obsolètes par votre fonction. Deux options s’offrent à vous pour vous assurer que votre fonction utilise la dernière valeur de secret :

  • Réduisez le TTL du cache en définissant la variable d’environnement SECRETS_MANAGER_TTL sur une valeur inférieure (en secondes). Par exemple, configurez-le sur 60 pour que votre fonction n’utilise jamais un secret vieux de plus d’une minute.

  • Utilisez les étiquettes intermédiaires AWSCURRENT ou AWSPREVIOUS dans votre demande de secret pour vous assurer d’obtenir la version spécifique que vous souhaitez :

    secretsmanager/get?secretId=YOUR_SECRET_NAME&versionStage=AWSCURRENT

Choisissez l’approche qui équilibre le mieux vos besoins en matière de performances et de fraîcheur. Un TTL inférieur signifie des appels plus fréquents à Secrets Manager, mais garantit que vous travaillez avec les valeurs de secret les plus récentes.

Utilisation de l’utilitaire de paramètres Powertools pour AWS Lambda

L’utilitaire de paramètres Powertools pour AWS Lambda fournit une interface unifiée permettant de récupérer des secrets auprès de plusieurs fournisseurs, notamment Secrets Manager, Parameter Store et AppConfig. Il gère la mise en cache, les transformations et fournit une expérience de développement plus intégrée par rapport à l’approche de l’extension.

Avantages de l’utilitaire de paramètres

  • Fournisseurs multiples : récupérez les paramètres depuis Secrets Manager, Parameter Store et AppConfig à l’aide de la même interface

  • Transformations intégrées : analyse automatique du JSON, décodage Base64 et autres transformations de données

  • Mise en cache intégrée : mise en cache configurable avec prise en charge de TTL pour réduire les appels d’API

  • Sécurité des types : prise en charge du typage fort dans TypeScript et les autres environnements d’exécution pris en charge

  • Gestion des erreurs : logique de nouvelle tentative et gestion des erreurs intégrées

Exemples de code

Les exemples suivants montrent comment récupérer des secrets à l’aide de l’utilitaire de paramètres dans différents environnements d’exécution :

Python
Note

Pour obtenir des exemples complets et des instructions de configuration, consultez la documentation de l’utilitaire de paramètres.

Récupération de secrets à partir de Secrets Manager avec l’utilitaire de paramètres Powertools pour AWS Lambda.

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
Note

Pour obtenir des exemples complets et des instructions de configuration, consultez la documentation de l’utilitaire de paramètres.

Récupération de secrets à partir de Secrets Manager avec l’utilitaire de paramètres Powertools pour AWS Lambda.

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
Note

Pour obtenir des exemples complets et des instructions de configuration, consultez la documentation de l’utilitaire de paramètres.

Récupération de secrets à partir de Secrets Manager avec l’utilitaire de paramètres Powertools pour AWS Lambda.

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
Note

Pour obtenir des exemples complets et des instructions de configuration, consultez la documentation de l’utilitaire de paramètres.

Récupération de secrets à partir de Secrets Manager avec l’utilitaire de paramètres Powertools pour AWS Lambda.

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 } }

Configuration et autorisations

Pour utiliser l’utilitaire de paramètres :

  1. Installez Powertools pour AWS Lambda pour votre environnement d’exécution. Pour en savoir plus, consultez Powertools pour AWS Lambda.

  2. Ajoutez les autorisations IAM nécessaires au rôle d’exécution de votre fonction. Pour plus d'informations, consultez Gestion des autorisations dans AWS Lambda.

  3. Configurez tous les paramètres facultatifs par le biais de variables d’environnement.

Les autorisations IAM requises sont les mêmes que pour l’approche de l’extension. L’utilitaire gère automatiquement la mise en cache et les appels d’API à Secrets Manager en fonction de votre configuration.