내용으로 건너뛰기

Secrets Manager Lambda 교체가 실패하는 이유는 무엇입니까?

4분 분량
0

위임된 역할을 사용하여 AWS Secrets Manager 시크릿을 교체하거나 AWS 계정 간에 교체하도록 AWS Lambda 교체 함수를 구성했습니다. 하지만 함수가 시크릿을 교체하지 않았습니다.

간략한 설명

2024년 12월, Secrets Manager에서 교체 프로세스의 일부로 PutSecretValue API 작업을 호출하는 엔티티를 검증하는 방식이 변경되었습니다. 이 변경 사항은 교차 계정 및 위임된 역할 교체에 모두 영향을 미칩니다.

Secrets Manager가 엔티티의 ID를 검증할 수 있도록 함수는 교체 토큰을 전달해야 합니다. 이후 Lambda 교체 함수는 PutSecretValue를 호출할 수 있습니다.

2024년 12월 이전에 교체 함수 코드를 업데이트하지 않았다면 업데이트하는 것이 좋습니다. AWS CloudTrail에서 다음 메시지가 포함된 RotationFailed 이벤트를 확인합니다. "Pending secret version VERSION_ID for Secret SECRET_ARN wasn't created by Lambda LAMBDA_ARN. Remove the AWSPENDING staging label and restart rotation". RotationFailed 이벤트를 찾은 경우 RotationToken 파라미터를 사용하도록 Lambda 함수를 업데이트하십시오.

참고: 교차 계정 교체나 위임된 역할을 사용하지 않는 경우에는 변경이 필요하지 않습니다.

해결 방법

Lambda 함수 코드 다운로드

다음 단계를 완료합니다.

  1. Lambda 콘솔을 엽니다.
  2. 탐색 창에서 함수를 선택합니다.
  3. 함수 이름에서 시크릿을 교체하는 Lambda 함수를 선택합니다.
  4. 다운로드에서 다음 옵션 중 하나를 선택합니다.
    함수 코드 .zip
    AWS SAM 파일
    둘 다
  5. 확인을 선택하여 로컬 컴퓨터에 함수를 저장합니다.

Lambda 함수 코드 편집

코드 편집기를 열고 Lambda 함수 코드를 편집합니다. 다음 예시는 편집이 필요할 수 있는 코드입니다.

lambda_handler 코드 편집

교차 계정 교체를 위해 create_secret 단계에 rotation_token 파라미터 포함:

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

create_secret 코드 편집

create_secret 함수를 업데이트하여 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))

업데이트된 Lambda 함수 코드 업로드

Lambda 함수 코드를 업데이트한 후 코드를 업로드하여 시크릿을 교체합니다.

관련 정보

Lambda 함수에 의한 교체

Lambda 교체 함수가 Secrets Manager 시크릿을 교체하는 두 번째 함수를 호출했지만 실패했습니다. 두 번째 Lambda 함수가 실패한 이유는 무엇입니까?

AWS 공식업데이트됨 일 년 전