跳至內容

如何對嘗試使用跨帳戶 Lambda 函式調用 Amazon Bedrock 時,收到的 "botocore.errorfactory.AccessDeniedException" 錯誤進行疑難排解?

2 分的閱讀內容
0

我想在 AWS 帳戶中調用 Amazon Bedrock 模型。我嘗試將跨帳戶 AWS Lambda 函式與 Python 執行時期結合使用。但是,我收到 "botocore.errorfactory.AccessDeniedException" 錯誤訊息。

簡短描述

當您使用跨帳戶 Lambda 函式調用 Amazon Bedrock 時,可能會收到以下錯誤訊息:

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

若要解決此錯誤,請執行下列動作:

  • 在帳戶 A (擁有 Amazon Bedrock 模型的帳戶) 中建立 AWS Identity and Access Management (IAM) 角色。然後,將 AmazonBedrockFullAccess 政策附加到該角色,以允許其存取帳戶 B (擁有 Lambda 函式的帳戶)。
  • 在帳戶 B 中建立一個 IAM 角色。然後,將該 IAM 角色與基本執行政策建立關聯,以允許其承擔的角色存取帳戶 A 中的 IAM 角色。

**注意:**使用 Amazon Bedrock 基礎模型時,請務必查看賣方的定價條款

確保在帳戶 A 中請求存取您的 Amazon Bedrock 模型。確認存取狀態變更為已授予存取權

解決方法

設定帳戶 A

為擁有 Amazon Bedrock 模型的帳戶完成以下步驟:

  1. 開啟 IAM console (IAM 主控台)。
  2. 為帳戶 A 建立 IAM 角色
  3. AmazonBedrockFullAccess 政策附加到 IAM 角色。
  4. 附加一個信任關係政策,允許 Lambda 函式在帳戶 B 中的角色代入帳戶 A 中的角色。
    信任關係政策範例:
    {    
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Principal": {
                    "AWS": "arn:aws:iam::Account_B_ID:role/my-lambda-execution-role"
                },
                "Action": "sts:AssumeRole"
            }
        ]
    }
    **注意:**將 Account_B_ID 替換為您的帳戶 B ID,並將 my-lambda-execution-role 替換為您的 Lambda 函式執行角色。

設定帳戶 B

為擁有 Lambda 函式的角色完成以下步驟:

  1. 開啟 IAM console (IAM 主控台)。
  2. 建立一個 IAM 角色,供 Lambda 函式在該帳戶中執行時使用。
  3. AWSLambdaBasicExecutionRole 政策附加到該角色。
  4. 附加一項政策,允許帳戶 B 中的 IAM 角色代入帳戶 A 中的 IAM 角色。
    政策範例:
    {    
        "Version": "2012-10-17",
        "Statement": {
            "Effect": "Allow",
            "Action": "sts:AssumeRole",
            "Resource": "arn:aws:iam::Account_A_ID:role/role-on-source-account"
        }
    }
    **注意:**將 Account_A_ID 替換為您的帳戶 A ID,並將 role-on-source-account 替換為帳戶 A 中 IAM 角色的名稱。

如需跨帳戶最佳實務的資訊,請參閱 IAM 中的安全最佳實務

建立 Lambda 函式

建立 Lambda 函式。Lambda 函式會擔任帳戶 A 具有可以存取 Amazon Bedrock 模型的 IAM 角色。然後,函式會使用所擔任角色的憑證來建立與 Amazon Bedrock 模型互動的 Amazon Bedrock 執行時期用戶端。

您的 Lambda 函式應該會類似以下的 Python 範例函式:

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')
     }