Usar segredos do Secrets Manager em funções do Lambda - AWS Lambda

Usar segredos do Secrets Manager em funções do Lambda

O AWS Secrets Manager ajuda você a gerenciar credenciais, chaves de API e outros segredos de que as funções do Lambda precisam. Existem duas abordagens principais para recuperar segredos em suas funções do Lambda, ambas oferecendo melhor performance e custos mais baixos em comparação com a recuperação direta de segredos usando o AWSSDK:

  • Parâmetros da AWS e segredos da extensão do Lambda: uma solução independente de tempo de execução que fornece uma interface HTTP simples para recuperar segredos

  • Utilitário de parâmetros do Powertools para AWS Lambda: uma solução integrada de código que oferece suporte a vários provedores (Secrets Manager, Parameter Store, AppConfig) com transformações integradas

Ambas as abordagens mantêm caches locais de segredos, eliminando a necessidade de sua função chamar o Secrets Manager para cada invocação. Quando sua função solicita um segredo, o cache é verificado primeiro. Se o segredo estiver disponível e não tiver expirado, ele será retornado imediatamente. Caso contrário, ele é recuperado do Gerenciador de Segredos, armazenado em cache e retornado. O resultado desse mecanismo de armazenamento em cache são tempos de resposta mais rápidos e custos reduzidos por minimizar as chamadas de API.

Como escolher uma abordagem

Considere estes fatores ao escolher entre a extensão e o PowerTools:

Use a extensão Lambda de parâmetros do AWS e segredos quando:
  • Você deseja uma solução independente de runtime que funcione com qualquer runtime do Lambda

  • Você prefere não adicionar dependências de código à sua função.

  • Você só precisa recuperar segredos do Secrets Manager ou Parameter Store

Use o Powertools para o utilitário de parâmetros do AWS Lambda quando:
  • Você quer uma experiência de desenvolvimento integrada com o código do seu aplicativo

  • Você precisa de suporte para vários provedores (Secrets Manager, Parameter Store, AppConfig)

  • Você deseja transformações de dados integradas (análise JSON, decodificação em base64)

  • Você está usando tempos de execução Python, TypeScript, Java ou .NET

Quando usar o Secrets Manager com o Lambda

Os cenários comuns para usar o Secrets Manager com o Lambda incluem:

  • Armazenamento de credenciais de banco de dados que a função usa para se conectar ao Amazon RDS ou outros bancos de dados

  • Gerenciamento de chaves de API para os serviços externos que a função chama

  • Armazenamento de chaves de criptografia ou outros dados de configuração confidenciais

  • Rodízio automático de credenciais sem precisar atualizar o código da função

Usando os parâmetros AWS e segredos da extensão do Lambda

Os parâmetros e segredos do AWS: a extensão do Lambda usa uma interface HTTP simples compatível com qualquer tempo de execução Lambda. Por padrão, ela armazena os segredos em cache por 300 segundos (5 minutos) e pode armazenar até 1.000 segredos. Você pode personalizar essas configurações com variáveis de ambiente.

Usar o Secrets Manager em uma função do Lambda

Esta seção pressupõe que você já tenha criado um segredo do Secrets Manager. Para criar um segredo, consulte Criar um segredo do AWS Secrets Manager.

Escolha seu runtime preferido e siga as etapas para criar uma função que recupere os segredos do Secrets Manager. A função do exemplo recupera um segredo do Secrets Manager e pode ser usada para acessar credenciais de banco de dados, chaves de API ou outros dados de configuração confidenciais em seus aplicativos.

Python
Para criar uma função em Python
  1. Crie e navegue até um novo diretório de projeto. Exemplo:

    mkdir my_function cd my_function
  2. Crie um arquivo denominado lambda_function.py com o código a seguir. Para secret_name, use o nome ou o nome do recurso da Amazon (ARN) do segredo.

    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. Crie um arquivo denominado requirements.txt com este conteúdo:

    requests
  4. Instale as dependências:

    pip install -r requirements.txt -t .
  5. Crie um arquivo .zip contendo todos os arquivos:

    zip -r function.zip .
Node.js
Para criar uma função em Node.js.
  1. Crie e navegue até um novo diretório de projeto. Exemplo:

    mkdir my_function cd my_function
  2. Crie um arquivo denominado index.mjs com o código a seguir. Para secret_name, use o nome ou o nome do recurso da Amazon (ARN) do segredo.

    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. Crie um arquivo .zip que contenha o arquivo index.mjs:

    zip -r function.zip index.mjs
Java
Para criar uma função em Java
  1. Criar um projeto Maven:

    mvn archetype:generate \ -DgroupId=example \ -DartifactId=lambda-secrets-demo \ -DarchetypeArtifactId=maven-archetype-quickstart \ -DarchetypeVersion=1.4 \ -DinteractiveMode=false
  2. Navegue até o diretório de projeto:

    cd lambda-secrets-demo
  3. Abra o pom.xml e substitua o conteúdo pelo seguinte:

    <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. Renomeie o /lambda-secrets-demo/src/main/java/example/App.java como Hello.java para corresponder ao nome do manipulador Java padrão do Lambda (example.Hello::handleRequest):

    mv src/main/java/example/App.java src/main/java/example/Hello.java
  5. Abra o arquivo Hello.java e substitua o conteúdo pelo que se segue. Para secretName, use o nome ou o nome do recurso da Amazon (ARN) do segredo.

    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. Remova o diretório de teste. O Maven o cria por padrão, mas não precisamos dele neste exemplo.

    rm -rf src/test
  7. Criar o projeto:

    mvn package
  8. Baixe o arquivo JAR (target/function.jar) para uso posterior.

  1. Abra a página Funções do console do Lambda.

  2. Escolha a opção Criar função.

  3. Selecione Criar do zero.

  4. Em Function name (Nome da função), insira secret-retrieval-demo.

  5. Escolha seu runtime preferido.

  6. Escolha a opção Criar função.

Para carregar o pacote de implantação
  1. Na guia Código da função, escolha Carregar de e selecione arquivo.zip (para Python e Node.js) ou arquivo.jar (para Java).

  2. Carregue o pacote de implantação que você criou anteriormente.

  3. Escolha Salvar.

Para adicionar a extensão do Lambda AWS Parameters and Secrets como uma camada
  1. Na guia Código da função, role para baixo até Camadas.

  2. Escolha Add a layer.

  3. Selecione Camadas da AWS.

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

  5. Selecione a versão mais recente.

  6. Escolha Adicionar.

Para adicionar permissões do Secrets Manager à função de execução
  1. Escolha a guia Configuration (Configuração) e, depois, Permissions (Permissões).

  2. Em Nome do perfil, escolha o link para seu perfil de execução. Esse link abre o perfil no console do IAM.

    Link para perfil de execução
  3. Escolha Adicionar permissões e, em seguida, Criar política em linha.

    Associar políticas no console do IAM
  4. Escolha a guia JSON e adicione a política a seguir. Em Resource, insira o ARN do segredo.

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

  6. Insira um nome para a política.

  7. Escolha Criar política.

Para testar a função
  1. Volte para o console do Lambda.

  2. Selecione a guia Testar.

  3. Escolha Testar. Você deverá ver a seguinte resposta:

    Resultado de teste bem-sucedido

Variáveis de ambiente

A extensão do Lambda AWS Parameters and Secrets usa as configurações padrão a seguir. Você pode substituir essas configurações criando as variáveis de ambiente correspondentes. Para visualizar as configurações atuais de uma função, defina PARAMETERS_SECRETS_EXTENSION_LOG_LEVEL como DEBUG. A extensão registrará as informações de configuração no CloudWatch Logs no início de cada invocação de função.

Configuração Valor padrão Valores válidos Variável de ambiente Detalhes
Porta HTTP 2773 1 - 65535 PARAMETERS_SECRETS_EXTENSION_HTTP_PORT Porta do servidor HTTP local
Cache habilitado VERDADEIRO TRUE | FALSE PARAMETERS_SECRETS_EXTENSION_CACHE_ENABLED Habilitar ou desabilitar o cache
Tamanho do cache 1000 0 - 1.000 PARAMETERS_SECRETS_EXTENSION_CACHE_SIZE Definir como 0 para desabilitar o cache
TTL do Secrets Manager 300 segundos 0 - 300 segundos SECRETS_MANAGER_TTL Vida útil dos segredos em cache. Defina como 0 para desabilitar o cache. Essa variável será ignorada se o valor de PARAMETERS_S_SECRETS_S_EXTENSION_CACHE_SIZE for 0.
TTL do Parameter Store 300 segundos 0 - 300 segundos SSM PARAMETER_STORE_TTL Vida útil dos parâmetros em cache. Defina como 0 para desabilitar o cache. Essa variável será ignorada se o valor de PARAMETERS_S_SECRETS_S_EXTENSION_CACHE_SIZE for 0.
Nível de log INFORMAÇÕES DEPURAR | INFORMAÇÕES | AVISAR | ERRO | NENHUM PARAMETERS_SECRETS_EXTENSION_LOG_LEVEL O nível de detalhes relatado nos logs para a extensão
Máximo de conexões 3 1 ou mais PARAMETERS_SECRETS_EXTENSION_MAX_CONNECTIONS Número máximo de conexões HTTP para solicitações ao Parameter Store ou ao Secrets Manager
Tempo limite do Secrets Manager 0 (sem tempo limite) Todos os números inteiros SECRETS_MANAGER_TIMEOUT_MILLIS Tempo limite para solicitações ao Secrets Manager (em milissegundos)
Tempo limite do Parameter Store 0 (sem tempo limite) Todos os números inteiros SSM_PARAMETER_STORE_TIMEOUT_MILLIS Tempo limite para solicitações ao Parameter Store (em milissegundos)

Trabalhar com rodízio de segredos

Se você fizer o rodízio dos segredos com frequência, a duração padrão do cache de 300 segundos poderá fazer com que a função use segredos desatualizados. Você tem duas opções para garantir que a função use o valor secreto mais recente:

  • Reduza o TTL do cache definindo a variável de ambiente SECRETS_MANAGER_TTL como um valor menor (em segundos). Por exemplo, configurá-la como 60 garante que a função nunca use um segredo que tenha mais de um minuto.

  • Use os rótulos de preparação AWSCURRENT ou AWSPREVIOUS na solicitação de segredo para garantir que obterá a versão específica que deseja:

    secretsmanager/get?secretId=YOUR_SECRET_NAME&versionStage=AWSCURRENT

Escolha a abordagem que melhor equilibre suas necessidades de performance e brevidade. Um TTL mais baixo significa chamadas mais frequentes para o Secrets Manager, mas garante que você esteja trabalhando com os valores de segredo mais recentes.

Uso do utilitário de parâmetros do Powertools para AWS Lambda

O utilitário de parâmetros do Powertools para AWS Lambda fornece uma interface unificada para recuperar segredos de vários provedores, incluindo Secrets Manager, Parameter Store e AppConfig. Ele lida com o armazenamento em cache, transformações e fornece uma experiência de desenvolvimento mais integrada em comparação com a abordagem de extensão.

Benefícios do utilitário de parâmetros

  • Vários provedores: recupere parâmetros do Secrets Manager, Parameter Store e AppConfig usando a mesma interface

  • Transformações integradas: análise automática de JSON, decodificação base64 e outras transformações de dados

  • Cache integrado - Cache configurável com suporte a TTL para reduzir as chamadas de API

  • Segurança de digitação: forte suporte de digitação em TypeScript e outros tempos de execução suportados

  • Tratamento de erros: lógica de repetição e tratamento de erros incorporados

Exemplos de código

Os exemplos a seguir mostram como recuperar segredos usando o utilitário de Parâmetros em diferentes tempos de execução:

Python
nota

Para obter exemplos completos e instruções de configuração, consulte a documentação do utilitário de Parâmetros.

Recuperar segredos do Secrets Manager com o utilitário de Parâmetros do Powertools para 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
nota

Para obter exemplos completos e instruções de configuração, consulte a documentação do utilitário de Parâmetros.

Recuperar segredos do Secrets Manager com o utilitário de Parâmetros do Powertools para 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
nota

Para obter exemplos completos e instruções de configuração, consulte a documentação do utilitário de Parâmetros.

Recuperar segredos do Secrets Manager com o utilitário de Parâmetros do Powertools para 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
nota

Para obter exemplos completos e instruções de configuração, consulte a documentação do utilitário de Parâmetros.

Recuperar segredos do Secrets Manager com o utilitário de Parâmetros do Powertools para 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 } }

Configuração e permissões

Para usar o utilitário de Parâmetros, você precisa:

  1. Instalar o Powertools para AWS Lambda para seu runtime. Para obter detalhes, consulte Powertools para AWS Lambda.

  2. Para obter exemplos completos e instruções de configuração, consulte a documentação do utilitário de Parâmetros. Para mais detalhes, consulte Gerenciando permissões no AWS Lambda.

  3. Defina configurações opcionais por meio de variáveis de ambiente.

As permissões do IAM obrigatórias são as mesmas que para a abordagem de extensão. O utilitário manipulará automaticamente o armazenamento em cache e as chamadas de API para o Secrets Manager com base na sua configuração.