Salta al contenuto

Perché la mia rotazione Lambda di Secrets Manager non è riuscita?

5 minuti di lettura
0

Ho configurato una funzione di rotazione AWS Lambda per utilizzare un ruolo assunto allo scopo di ruotare il mio segreto di AWS Secrets Manager o di ruotare tra account AWS. La funzione, tuttavia, non ha ruotato il segreto.

Breve descrizione

Nel dicembre 2024, Secrets Manager ha cambiato il modo in cui convalida le entità che chiamano l'azione API PutSecretValue nell'ambito del processo di rotazione. Questa modifica influisce sia sulla rotazione tra account che sui ruoli assunti.

La funzione deve passare un token di rotazione in modo che Secrets Manager possa convalidare l'identità dell'entità. Dopodiché le funzioni di rotazione Lambda possono chiamare PutSecretValue.

Se non hai aggiornato il codice della funzione di rotazione prima di dicembre 2024, è consigliabile aggiornarlo. Controlla in AWS CloudTrail se è presente un evento RotationFailed con il messaggio "Pending secret version VERSION_ID for Secret SECRET_ARN wasn't created by Lambda LAMBDA_ARN. Remove the AWSPENDING staging label and restart rotation". Se trovi l'evento RotationFailed, aggiorna la funzione Lambda per utilizzare il parametro RotationToken.

Nota: se non utilizzi la rotazione tra account o un ruolo assunto, non sono necessarie modifiche.

Risoluzione

Scarica il codice della funzione Lambda

Completa i seguenti passaggi:

  1. Apri la console Lambda.
  2. Nel pannello di navigazione, scegli Funzioni.
  3. In Nome funzione, seleziona la funzione Lambda che ruota il segreto.
  4. In Scarica, scegli una delle seguenti opzioni:
    File .zip del codice della funzione
    File AWS SAM
    Entrambi
  5. Scegli OK per salvare la funzione sul computer locale.

Modifica il codice della funzione Lambda

Apri il tuo editor di codice e modifica il codice della funzione Lambda. I seguenti esempi sono modifiche al codice che potresti dover apportare.

Modifica il codice lambda_handler

Includi il parametro rotation_token nel passaggio create_secret per la rotazione tra account:

def lambda_handler(event, context):
    """Secrets Manager Rotation Template

    This is a template for creating an AWS Secrets Manager rotation lambda

    Args:
        event (dict): Lambda dictionary of event parameters. These keys must include the following:
            - SecretId: The secret ARN or identifier
            - ClientRequestToken: The ClientRequestToken of the secret version
            - Step: The rotation step (one of createSecret, setSecret, testSecret, or finishSecret)
            - RotationToken: the rotation token to put as parameter for PutSecretValue call

        context (LambdaContext): The Lambda runtime information

    Raises:
        ResourceNotFoundException: If the secret with the specified arn and stage does not exist

        ValueError: If the secret is not properly configured for rotation

        KeyError: If the event parameters do not contain the expected keys

    """
    arn = event['SecretId']
    token = event['ClientRequestToken']
    step = event['Step']
    # Add the rotation token
    rotation_token = event['RotationToken']

    # Setup the client
    service_client = boto3.client('secretsmanager', endpoint_url=os.environ['SECRETS_MANAGER_ENDPOINT'])

    # Make sure the version is staged correctly
    metadata = service_client.describe_secret(SecretId=arn)
    if not metadata['RotationEnabled']:
        logger.error("Secret %s is not enabled for rotation" % arn)
        raise ValueError("Secret %s is not enabled for rotation" % arn)
    versions = metadata['VersionIdsToStages']
    if token not in versions:
        logger.error("Secret version %s has no stage for rotation of secret %s." % (token, arn))
        raise ValueError("Secret version %s has no stage for rotation of secret %s." % (token, arn))
    if "AWSCURRENT" in versions[token]:
        logger.info("Secret version %s already set as AWSCURRENT for secret %s." % (token, arn))
        return
    elif "AWSPENDING" not in versions[token]:
        logger.error("Secret version %s not set as AWSPENDING for rotation of secret %s." % (token, arn))
        raise ValueError("Secret version %s not set as AWSPENDING for rotation of secret %s." % (token, arn))
    # Use rotation_token
    if step == "createSecret":
        create_secret(service_client, arn, token, rotation_token)

    elif step == "setSecret":
        set_secret(service_client, arn, token)

    elif step == "testSecret":
        test_secret(service_client, arn, token)

    elif step == "finishSecret":
        finish_secret(service_client, arn, token)

    else:
        raise ValueError("Invalid step parameter")

Modifica il codice create_secret

Aggiorna la funzione create_secret per accettare e utilizzare il parametro rotation_token:

# Add rotation_token to the function
def create_secret(service_client, arn, token, rotation_token):
"""Create the secret

This method first checks for the existence of a secret for the passed in token. If one does not exist, it will generate a
new secret and put it with the passed in token.

Args:
service_client (client): The secrets manager service client

arn (string): The secret ARN or other identifier

token (string): The ClientRequestToken associated with the secret version

rotation_token (string): the rotation token to put as parameter for PutSecretValue call

Raises:
ResourceNotFoundException: If the secret with the specified arn and stage does not exist

"""
# Make sure the current secret exists
service_client.get_secret_value(SecretId=arn, VersionStage="AWSCURRENT")

# Now try to get the secret version, if that fails, put a new secret
try:
service_client.get_secret_value(SecretId=arn, VersionId=token, VersionStage="AWSPENDING")
logger.info("createSecret: Successfully retrieved secret for %s." % arn)
except service_client.exceptions.ResourceNotFoundException:
# Get exclude characters from environment variable
exclude_characters = os.environ['EXCLUDE_CHARACTERS'] if 'EXCLUDE_CHARACTERS' in os.environ else '/@"\'\\'
# Generate a random password
passwd = service_client.get_random_password(ExcludeCharacters=exclude_characters)

# Put the secret, using rotation_token
service_client.put_secret_value(SecretId=arn, ClientRequestToken=token, SecretString=passwd['RandomPassword'], VersionStages=['AWSPENDING'], RotationToken=rotation_token)
logger.info("createSecret: Successfully put secret for ARN %s and version %s." % (arn, token))

Carica il codice della funzione Lambda aggiornato

Dopo aver aggiornato il codice della funzione Lambda, carica il codice per ruotare il segreto.

Informazioni correlate

Rotazione tramite funzione Lambda

La mia funzione di rotazione Lambda ha chiamato una seconda funzione per ruotare un segreto di Secrets Manager ma non è riuscita. Perché la seconda funzione Lambda non è riuscita?

AWS UFFICIALEAggiornata 10 mesi fa