Quero invocar meus modelos do Amazon Bedrock em minha conta da AWS. Eu tentei usar uma função do AWS Lambda entre contas com runtimes do Python. No entanto, recebi uma mensagem de erro "botocore.errorfactory.AccessDeniedException".
Breve descrição
Quando você usa uma função do Lambda entre contas para invocar o Amazon Bedrock, você pode receber a seguinte mensagem de erro:
"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."
Para resolver esse erro, execute as seguintes ações:
- Crie um perfil do AWS Identity and Access Management (AWS IAM) na conta A, a conta que possui o modelo do Amazon Bedrock. Em seguida, anexe a política AmazonBedrockFullAccess ao perfil para permitir que ela acesse a conta B, a conta que possui a função do Lambda.
- Crie um perfil do IAM na conta B. Em seguida, associe o perfil do IAM a uma política de execução básica para permitir que o perfil assumido acesse o perfil do IAM na conta A.
Observação: ao usar os modelos básicos do Amazon Bedrock, certifique-se de verificar os termos de preços do vendedor.
Certifique-se de solicitar acesso ao seu modelo do Amazon Bedrock na conta A. Confirme se o status de acesso muda para Acesso concedido.
Resolução
Configurar a conta A
Conclua as etapas a seguir para a conta que possui os modelos do Amazon Bedrock:
- Abra o console do IAM.
- Crie um perfil do IAM para a conta A.
- Anexe a política AmazonBedrockFullAccess ao perfil do IAM.
- Anexe uma política de relacionamento de confiança que permita que a função do Lambda na conta B assuma o perfil na conta A.
Exemplo de política de relacionamento de confiança:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::Account_B_ID:role/my-lambda-execution-role"
},
"Action": "sts:AssumeRole"
}
]
}
Observação: substitua Account_B_ID pelo ID da sua conta B e my-lambda-execution-role pelo perfil de execução da função do Lambda.
Configurar a conta B
Conclua as etapas a seguir para o perfil que possui a função do Lambda:
- Abra o console do IAM.
- Crie um perfil do IAM que a função do Lambda usa para ser executada na conta.
- Anexe a política AWSLambdaBasicExecutionRole ao perfil.
- Anexe uma política que permita que o perfil do IAM na conta B assuma o perfil do IAM na conta A.
Exemplo de política:
{
"Version": "2012-10-17",
"Statement": {
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::Account_A_ID:role/role-on-source-account"
}
}
Observação: substitua Account_A_ID pela ID da sua conta A e role-on-source-account pelo nome do perfil do IAM da conta A.
Para obter mais informações sobre as práticas recomendadas entre contras, consulte Práticas recomendadas de segurança no IAM.
Criar uma função do Lambda
Crie uma função do Lambda. A função do Lambda assume o perfil do IAM da conta A que tem acesso aos modelos do Amazon Bedrock. Em seguida, a função usa as credenciais do perfil assumido para criar os clientes de runtime do Amazon Bedrock que interagem com os modelos do Amazon Bedrock.
Sua função do Lambda deve ser semelhante ao exemplo de função Python a seguir:
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')
}