"""Lambda delete-intermediate-snapshots module.""" import boto3 import sentry_sdk from sentry_sdk.integrations.aws_lambda import AwsLambdaIntegration import config from common.logic import database # noqa from common.utils.logger import log as logger # noqa if config.SENTRY_DSN: sentry_sdk.init( dsn=config.SENTRY_DSN, environment=config.ENVIRONMENT, integrations=[AwsLambdaIntegration(timeout_warning=True)] ) def assume_source_account_role(account_id, role_name): """ Assume IAM role in source account. Args: account_id (str): AWS account ID Returns: dict: dict of AWS credentials """ client = boto3.client('sts') assume_role_response = client.assume_role( RoleArn=f'arn:aws:iam::{account_id}:role/{role_name}', RoleSessionName=config.SERVICE_NAME, ExternalId=config.EXTERNAL_ID, DurationSeconds=3600 ) credentials = assume_role_response['Credentials'] return credentials def get_snapshots_to_delete(event, rds_client): """ Determine which snapshots to delete. Args: event: the lambda event rds_client: the RDS client Returns: list: list of snapshot names to delete """ db_type = event['db_type'] all_snapshots = database.find_matching_snapshots( event['db_name'], db_type, rds_client) execution_id = event['execution_id'] snapshots_to_delete = set() for snapshot in all_snapshots: snapshot_name = snapshot['DBClusterSnapshotIdentifier'] \ if db_type == 'cluster' else snapshot['DBSnapshotIdentifier'] tags = snapshot.get('TagList', []) for tag in tags: if tag['Key'] == 'execution_id' and tag['Value'] == execution_id: snapshots_to_delete.add(snapshot_name) break return snapshots_to_delete def handler(event, _context): """Lambda entry point.""" try: source_account_role = event.get( 'source_account_role', config.CROSS_ACCOUNT_BACKUP_ROLE_NAME) credentials = assume_source_account_role( event['source_account_id'], source_account_role) rds_client = boto3.client( 'rds', region_name=config.AWS_DEFAULT_REGION, aws_access_key_id=credentials['AccessKeyId'], aws_secret_access_key=credentials['SecretAccessKey'], aws_session_token=credentials['SessionToken'] ) snapshots_to_delete = get_snapshots_to_delete(event, rds_client) for snapshot in snapshots_to_delete: database.delete_snapshot( snapshot, event['db_type'], rds_client, wait=False) logger.info(f'Deleted snapshot {snapshot} in account ' f"{event['source_account_id']}") except Exception as error: logger.exception(str(error)) raise error