Direkt zum Inhalt

Warum ist meine Secrets Manager Lambda-Rotation fehlgeschlagen?

Lesedauer: 5 Minute
0

Ich habe eine AWS Lambda-Rotationsfunktion konfiguriert, um eine angenommene Rolle zum Rotieren meines AWS Secrets Manager-Secrets oder zum Rotieren zwischen AWS-Konten zu verwenden. Die Funktion hat das Secret jedoch nicht rotiert.

Kurzbeschreibung

Im Dezember 2024 änderte Secrets Manager die Art und Weise der Validierung von Entitäten, die die PutSecretValue-API-Aktion als Teil des Rotationsprozesses aufrufen. Diese Änderung betrifft sowohl die kontoübergreifende als auch die angenommene Rollenrotation.

Die Funktion muss ein Rotationstoken übergeben, damit der Secrets Manager die Identität der Entität überprüfen kann. Lambda-Rotationsfunktionen können dann PutSecretValue aufrufen.

Wenn du deinen Rotationsfunktionscode nicht vor Dezember 2024 aktualisiert hast, solltest du ihn auf jeden Fall aktualisieren. Überprüfe AWS CloudTrail auf ein RotationFailed-Ereignis mit der Meldung „Pending secret version VERSION_ID for Secret SECRET_ARN wasn't created by Lambda LAMBDA_ARN. Remove the AWSPENDING staging label and restart rotation.“ Wenn du das Ereignis RotationFailed findest, aktualisiere deine Lambda-Funktion, um den Parameter RotationToken zu verwenden.

Hinweis: Wenn du keine kontoübergreifende Rotation oder eine angenommene Rolle verwendest, sind keine Änderungen erforderlich.

Lösung

Den Lambda-Funktionscode herunterladen

Führe die folgenden Schritte aus:

  1. Öffne die Lambda-Konsole.
  2. Wähle im Navigationsbereich Funktionen aus.
  3. Wähle unter Funktionsname deine Lambda-Funktion aus, die das Secret rotiert.
  4. Wähle für Download eine der folgenden Optionen aus:
    Zip-Funktionscode
    AWS SAM-Datei
    Beide
  5. Wähle OK aus, um die Funktion auf deinem lokalen Computer zu speichern.

Den Lambda-Funktionscode bearbeiten

Öffne deinen Code-Editor und bearbeite den Code deiner Lambda-Funktion. Die folgenden Beispiele sind Codeänderungen, die du möglicherweise vornehmen musst.

Code lambda_handler bearbeiten

Füge den Parameter rotation_token in den Schritt create_secret für die kontoübergreifende Rotation ein:

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")

Code create_secret bearbeiten

Aktualisiere die Funktion create_secret, damit der Parameter rotation_token akzeptiert und verwendet wird:

# 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))

Den aktualisierten Lambda-Funktionscode hochladen

Nachdem du deinen Lambda-Funktionscode aktualisiert hast, lade den Code hoch, um dein Secret zu rotieren.

Ähnliche Informationen

Rotation durch Lambda-Funktion

Meine Lambda-Rotationsfunktion hat eine zweite Funktion aufgerufen, um ein Secrets Manager-Secret zu rotieren, aber es ist fehlgeschlagen. Warum ist die zweite Lambda-Funktion fehlgeschlagen?

AWS OFFICIALAktualisiert vor einem Jahr