Direkt zum Inhalt

Wie behebe ich den "botocore.errorfactory.AccessDeniedException"-Fehler, der mir angezeigt wird, wenn ich versuche, Amazon Bedrock mithilfe einer kontoübergreifenden Lambda-Funktion aufzurufen?

Lesedauer: 3 Minute
0

Ich möchte meine Amazon Bedrock-Modelle in meinem AWS-Konto aufrufen. Ich habe versucht, eine kontoübergreifende AWS Lambda-Funktion mit Python-Laufzeiten zu verwenden. Ich habe jedoch eine "botocore.errorfactory.AccessDeniedException"-Fehlermeldung erhalten.

Kurzbeschreibung

Wenn du eine kontoübergreifende Lambda-Funktion verwendest, um Amazon Bedrock aufzurufen, erhältst du möglicherweise die folgende Fehlermeldung:

"botocore.errorfactory.AccessDeniedException: An error occurred (AccessDeniedException) when calling the InvokeModel operation: You don't have access to the model with the specified model ID."

Gehe wie folgt vor, um diesen Fehler zu beheben:

  • Erstelle eine AWS Identity and Access Management (IAM)-Rolle in Konto A, dem Konto, dem das Amazon Bedrock-Modell gehört. Hänge dann die AmazonBedrockFullAccess-Richtlinie an die Rolle an, damit sie auf Konto B zugreifen kann, das Konto, das die Lambda-Funktion besitzt.
  • Erstelle eine IAM-Rolle in Konto B. Ordne die IAM-Rolle anschließend einer grundlegenden Ausführungsrichtlinie zu, damit die übernommene Rolle auf die IAM-Rolle in Konto A zugreifen kann.

Hinweis: Wenn du Amazon Bedrock Foundation-Modelle verwendest, überprüfe unbedingt die Preisbedingungen des Verkäufers.

Stelle sicher, dass du den Modellzugriff für dein Amazon Bedrock-Modell in Konto A beantragst. Vergewissere dich, dass sich der Zugriffsstatus in Zugriff gewährt ändert.

Lösung

Konto A konfigurieren

Führe die folgenden Schritte für das Konto aus, dem die Amazon Bedrock-Modelle gehören:

  1. Öffne die IAM-Konsole.
  2. Erstelle eine IAM-Rolle für Konto A.
  3. Hänge die AmazonBedrockFullAccess-Richtlinie an die IAM-Rolle an.
  4. Füge eine Vertrauensbeziehungsrichtlinie hinzu, die es der Rolle der Lambda-Funktion in Konto B ermöglicht, die Rolle in Konto A zu übernehmen.
    Beispiel für eine Vertrauensbeziehungsrichtlinie:
    {    
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Principal": {
                    "AWS": "arn:aws:iam::Account_B_ID:role/my-lambda-execution-role"
                },
                "Action": "sts:AssumeRole"
            }
        ]
    }
    Hinweis: Ersetze Account_B_ID durch deine Konto-B-ID und my-lambda-execution-role durch deine Lambda-Funktionsausführungsrolle.

Konto B konfigurieren

Führe die folgenden Schritte für die Rolle aus, der die Lambda-Funktion gehört:

  1. Öffne die IAM-Konsole.
  2. Erstelle eine IAM-Rolle, die die Lambda-Funktion zur Ausführung im Konto verwendet.
  3. Hänge die AWSLambdaBasicExecutionRole-Richtlinie an die Rolle an.
  4. Füge eine Richtlinie hinzu, die es der IAM-Rolle in Konto B ermöglicht, die IAM-Rolle in Konto A zu übernehmen.
    Beispiel für eine Richtlinie:
    {    
        "Version": "2012-10-17",
        "Statement": {
            "Effect": "Allow",
            "Action": "sts:AssumeRole",
            "Resource": "arn:aws:iam::Account_A_ID:role/role-on-source-account"
        }
    }
    Hinweis: Ersetze Account_A_ID durch deine Konto-A-ID und role-on-source-account durch den Namen der IAM-Rolle aus Konto A.

Informationen zu kontoübergreifenden bewährten Methoden findest du unter Bewährte Sicherheitsmethoden in IAM.

Eine Lambda-Funktion erstellen

Eine Lambda-Funktion erstellen. Die Lambda-Funktion nimmt die IAM-Rolle von Konto A an, die Zugriff auf die Amazon Bedrock-Modelle hat. Die Funktion verwendet dann die Anmeldeinformationen der übernommenen Rolle, um die Amazon Bedrock-Laufzeitclients zu erstellen, die mit den Amazon Bedrock-Modellen interagieren.

Deine Lambda-Funktion muss der folgenden Python-Beispielfunktion ähneln:

import boto3import botocore
import json


def lambda_handler(event, context):
    bedrock_role="arn:aws:iam:::role/BedrockLambdaCrossAccount"   
    credentials =
boto3.client('sts').assume_role(RoleArn=bedrock_role,RoleSessionName='assume-role')
    ACCESS_KEY = credentials['Credentials']['AccessKeyId']
    SECRET_KEY = credentials['Credentials']['SecretAccessKey']
    SESSION_TOKEN = credentials['Credentials']['SessionToken']

    bedrock_session = boto3.session.Session(aws_access_key_id=ACCESS_KEY,aws_secret_access_key=SECRET_KEY,aws_session_token=SESSION_TOKEN)
    bedrock = boto3.client(service_name='bedrock', region_name='us-east-1',aws_access_key_id=ACCESS_KEY,aws_secret_access_key=SECRET_KEY,aws_session_token=SESSION_TOKEN)
    print(bedrock)

    bedrock_runtime = boto3.client(service_name='bedrock-runtime', region_name='us-east-1',aws_access_key_id=ACCESS_KEY,aws_secret_access_key=SECRET_KEY,aws_session_token=SESSION_TOKEN)
    foundation_models = bedrock.list_foundation_models()
    print(foundation_models)


    prompt = "Please list the 10 most popular movies from the 90's"

    body = json.dumps({"inputText": "Please list the 10 most popular movies from the 90's"})
    modelId = 'anthropic.claude-v2'
    accept = 'application/json'
    contentType = 'application/json'
    response = bedrock_runtime.invoke_model(body=body, modelId=modelId,
accept=accept,contentType=contentType)
    response_body = json.loads(response.get('body').read())
    print(response_body.get('results')[0].get('outputText'))

    output=response_body.get('results')[0].get('outputText')    
    print(output)
    return {
     'statusCode': 200,
     'headers': {
       'Access-Control-Allow-Headers': '*',
       'Access-Control-Allow-Origin': '*',
       'Access-Control-Allow-Methods': 'OPTIONS,POST,GET'
     },
       'body': response_body.get('results')[0].get('outputText')
     }