Closed MustaphaU closed 8 months ago
Answer generated by a 🤖
Hello @3coins, @jasondotparse, @hwchase17,
I understand that you're having trouble with the Bedrock class not being able to load your AWS credentials when called from a Lambda function. This issue is likely due to the difference in how AWS credentials are loaded in a local environment versus a Lambda function.
In your local environment, the Bedrock class is able to load your AWS credentials from the ~/.aws/credentials
file or the ~/.aws/config
file. However, when running in a Lambda function, these files are not available. Instead, AWS Lambda functions use IAM roles for permissions. The IAM role associated with your Lambda function needs to have the necessary permissions to access the Bedrock service.
To resolve this issue, you should ensure that the IAM role associated with your Lambda function has the necessary permissions to access the Bedrock service. If you're using the default AWS SDK for Python (boto3) client, it will automatically use the credentials associated with the IAM role of the Lambda function.
Here's the relevant part of the code that loads the credentials:
try:
import boto3
if values["credentials_profile_name"] is not None:
session = boto3.Session(profile_name=values["credentials_profile_name"])
else:
# use default credentials
session = boto3.Session()
client_params = {}
if values["region_name"]:
client_params["region_name"] = values["region_name"]
if values["endpoint_url"]:
client_params["endpoint_url"] = values["endpoint_url"]
values["client"] = session.client("bedrock", **client_params)
except ImportError:
raise ModuleNotFoundError(
"Could not import boto3 python package. "
"Please install it with `pip install boto3`."
)
except Exception as e:
raise ValueError(
"Could not load credentials to authenticate with AWS client. "
"Please check that credentials in the specified "
"profile name are valid."
) from e
In this code, if credentials_profile_name
is not provided, it defaults to using the default credentials which, in the case of a Lambda function, would be the IAM role associated with the function.
There was a similar issue raised in the LangChain repository: AmazonKendraRetriever "Could not load credentials" error in latest release which was resolved by ensuring the IAM role associated with the Lambda function had the necessary permissions.
I hope this helps! Let me know if you have any other questions.
This response is meant to be useful, save you time, and share context. It is not meant to be a precise solution, but rather a starting point for your own research.
Help me be more useful! Please leave a 👍 if this is helpful and 👎 if it is irrelevant.
Sorry I don't think it's an access issue since the IAM role associated with the Lambda function has full access to bedrock. Please see below:
Answer generated by a 🤖
Hello,
The issue you're experiencing is due to how the Bedrock class is handling AWS credentials. When running in your local environment, the Bedrock class is able to access your AWS credentials from the ~/.aws/credentials
file or ~/.aws/config
files. However, in the AWS Lambda environment, these files are not available and the credentials are provided through environment variables.
The Bedrock class should be modified to use the default credentials when the credentials_profile_name
is not provided. This will allow it to use the IAM role associated with the Lambda function. Here is the modified code:
@root_validator()
def validate_environment(cls, values: Dict) -> Dict:
"""Validate that AWS credentials to and python package exists in environment."""
if values["client"] is not None:
return values
try:
import boto3
if values["credentials_profile_name"] is not None:
session = boto3.Session(profile_name=values["credentials_profile_name"])
else:
# use default credentials
session = boto3.Session()
client_params = {}
if values["region_name"]:
client_params["region_name"] = values["region_name"]
if values["endpoint_url"]:
client_params["endpoint_url"] = values["endpoint_url"]
values["client"] = session.client("bedrock", **client_params)
except ImportError:
raise ModuleNotFoundError(
"Could not import boto3 python package. "
"Please install it with `pip install boto3`."
)
except Exception as e:
raise ValueError(
"Could not load credentials to authenticate with AWS client. "
"Please check that credentials in the specified "
"profile name are valid."
) from e
return values
In this code, if credentials_profile_name
is not provided, it will use the default session which will automatically use the credentials provided by the IAM role associated with the Lambda function.
Please try this modification and let me know if it resolves your issue. If you have any further questions, feel free to ask.
Best, Dosu
This response is meant to be useful, save you time, and share context. It is not meant to be a precise solution, but rather a starting point for your own research.
Help me be more useful! Please leave a 👍 if this is helpful and 👎 if it is irrelevant.
Hi @MustaphaU,
In the end, did you find a solution? I would also be interested in running Bedrock from Lambda and I guess I am going to run in the same problem...
Hi @jonathan260589 , I haven't found a solution till date.
I haven't actually tried this in Lambda, but are you packaging the boto3 that comes with Bedrock with your Lambda function?
I ran around in circles for a bit running locally with the real error being this line:
values["client"] = session.client("bedrock", **client_params)
...because the boto3 client that is the default pip install doesn't have support for the "bedrock" service. Once I made sure to use the bedrock-aware boto3 my auth issues went away.
Hi,
I've faced a same issue and solved it via this link : https://github.com/aws-samples/amazon-bedrock-workshop/blob/77abc340c4548ae014f2b948bb607c7c3b8cf89c/00_Intro/bedrock_boto3_setup.ipynb
Bedrock service is not available in live is still in preview, you have to install manually a specific version of Boto3 to access this new feature.
I've tested and everything works fine.
Good Luck.
I haven't actually tried this in Lambda, but are you packaging the boto3 that comes with Bedrock with your Lambda function?
I ran around in circles for a bit running locally with the real error being this line:
values["client"] = session.client("bedrock", **client_params)
...because the boto3 client that is the default pip install doesn't have support for the "bedrock" service. Once I made sure to use the bedrock-aware boto3 my auth issues went away.
Yes, both new wheels (boto3 and botocore) are in my deployment package. The issue is not with bedrock
being unsupported, otherwise the error would read "Unknown service: 'bedrock'. bedrock
is an unknown service ........"
Hi,
I've faced a same issue and solved it via this link : https://github.com/aws-samples/amazon-bedrock-workshop/blob/77abc340c4548ae014f2b948bb607c7c3b8cf89c/00_Intro/bedrock_boto3_setup.ipynb
Bedrock service is not available in live is still in preview, you have to install manually a specific version of Boto3 to access this new feature.
I've tested and everything works fine.
Good Luck.
Yes, both new wheels (boto3 and botocore) are in my deployment package. The issue is not with bedrock
being unsupported, otherwise the error would read "Unknown service: 'bedrock'. bedrock
is an unknown service ........"
Fine if you already have done with package installation then you could write something like that :
from boto3
from langchain.llms import Bedrock
session = boto3.Session(region_name = 'us-west-2')
boto3_bedrock = session.client(service_name="bedrock")
# Langchain LLM
llm = Bedrock(client=boto3_bedrock, model_id="anthropic.claude-v2", region_name='us-west-2')
in this case you bypass your first issue and your needs credential are provided by lambda role and not from profile. I made it works on Lambda and it works for me
That Exception block will swallow the unknown service exception and replace it with the generic credentials one:
except Exception as e: raise ValueError( "Could not load credentials to authenticate with AWS client. " "Please check that credentials in the specified " "profile name are valid." ) from e
As a test you could do the code like @hghandri suggests, that boto3_bedrock = session.client() call will tell you for sure if those Bedrock boto3 dependencies are really included or not.
Fine if you already have done with package installation then you could write something like that :
from boto3 from langchain.llms import Bedrock session = boto3.Session(region_name = 'us-west-2') boto3_bedrock = session.client(service_name="bedrock") # Langchain LLM llm = Bedrock(client=boto3_bedrock, model_id="anthropic.claude-v2", region_name='us-west-2')
in this case you bypass your first issue and your needs credential are provided by lambda role and not from profile. I made it works on Lambda and it works for me
Unfortunately, I had tried this in one of my attempts to fix the issue but it didn't work as I was faced with another error. "Unknown service": ''bedrock. bedrock
is an unknown service......, even though the boto wheels were installed in the deployment package. Here is a snapshot of the deployment package used to build the lambda function.
That Exception block will swallow the unknown service exception and replace it with the generic credentials one:
except Exception as e: raise ValueError( "Could not load credentials to authenticate with AWS client. " "Please check that credentials in the specified " "profile name are valid." ) from e
As a test you could do the code like @hghandri suggests, that boto3_bedrock = session.client() call will tell you for sure if those Bedrock boto3 dependencies are really included or not.
Unfortunately, I had tried this in one of my attempts to fix the issue but it didn't work as I was faced with another error. "Unknown service": ''bedrock. bedrock
is an unknown service......, even though the boto wheels were installed in the deployment package.
Here is a snapshot of the deployment package used to build the lambda function.
And here is the query function in my main.py:
Note: I do not encounter any of these issues when working in a SageMaker notebook or other environments.
Not sure what to tell you, that error you seeing is almost assuredly because it doesn't have the right version of boto3.
Not sure what to tell you, that error you seeing is almost assuredly because it doesn't have the right version of boto3.
Hence, my confusion. Perhaps lambda overrode the installed (custom) boto wheels with the default? Not sure.
Hi @MustaphaU, Here it's clearly an issue with version of Boto3 and botocore. Did you install all specific dependencies like in documentation ?
Here the code :
#!/bin/sh
set -e
echo "(Re)-creating directory"
rm -rf ./dependencies
mkdir ./dependencies
cd ./dependencies
echo "Downloading dependencies"
curl -sS https://d2eo22ngex1n9g.cloudfront.net/Documentation/SDK/bedrock-python-sdk.zip > sdk.zip
echo "Unpacking dependencies"
# (SageMaker Studio system terminals don't have `unzip` utility installed)
if command -v unzip &> /dev/null
then
unzip sdk.zip && rm sdk.zip && echo "Done"
else
echo "'unzip' command not found: Trying to unzip via Python"
python -m zipfile -e sdk.zip . && rm sdk.zip && echo "Done"
fi
Did you use docker image with Lambda ? Because all the library you need are too heavy to deployed simply in standard lambda package. Max allowed package size is 50MB. On my side I have attached an EFS to my Lambda where everything installed on it.
@hghandri No, I didn't use a docker image. My package size is 48 MB but I had increased the memory allocated to the function to more than twice the package size. Please see below.
I haven't actually tried this in Lambda, but are you packaging the boto3 that comes with Bedrock with your Lambda function? I ran around in circles for a bit running locally with the real error being this line:
values["client"] = session.client("bedrock", **client_params)
...because the boto3 client that is the default pip install doesn't have support for the "bedrock" service. Once I made sure to use the bedrock-aware boto3 my auth issues went away.
Yes, both new wheels (boto3 and botocore) are in my deployment package. The issue is not with
bedrock
being unsupported, otherwise the error would read "Unknown service: 'bedrock'.bedrock
is an unknown service ........"
How did you overcome the unknown service error? I was trying to access the bedrock from boto3 from wheel file. I was able to run in my local but getting the unknown service error in the lambda container image. can you provide any steps I could I follow to overcome this issue?
I haven't actually tried this in Lambda, but are you packaging the boto3 that comes with Bedrock with your Lambda function? I ran around in circles for a bit running locally with the real error being this line:
values["client"] = session.client("bedrock", **client_params)
...because the boto3 client that is the default pip install doesn't have support for the "bedrock" service. Once I made sure to use the bedrock-aware boto3 my auth issues went away.
Yes, both new wheels (boto3 and botocore) are in my deployment package. The issue is not with
bedrock
being unsupported, otherwise the error would read "Unknown service: 'bedrock'.bedrock
is an unknown service ........"How did you overcome the unknown service error? I was trying to access the bedrock from boto3 from wheel file. I was able to run in my local but getting the unknown service error in the lambda container image. can you provide any steps I could I follow to overcome this issue?
Ensure you're using the boto3 and botocore wheels that support Bedrock. Refer to page 21 of the Amazon Bedrock User Guide . The required files are boto3-1.28.21-py3-none-any.whl
and botocore-1.31.21-py3-none-any.whl
available in the bedrock python sdk. Note that these wheels aren't on the official PIP repository, so you'll need to download and install them manually.
I still am having this issue with the production release of boto3. Gave my test lambda admin credentials. Is anyone having success with this?
I'm facing the same problem, locally with my credentials in the ~/.aws/credentials
it works just fine, but in the Lambda it fails with:
"errorMessage": "1 validation error for Bedrock\n__root__\n Could not load credentials to authenticate with AWS client. Please check that credentials in the specified profile name are valid. (type=value_error)",
I don't think the upgrades above about boto3
make sense anymore since it is already in version 1.28.63 and clearly already supports bedrock.
UPDATE
Nevermind this, ended up finding out that the docker environment wasn't getting the latest version for the image that I was publishing. Once it got the latest, it works.
Hi, @MustaphaU,
I'm helping the LangChain team manage their backlog and am marking this issue as stale. From what I understand, you encountered a problem with the Bedrock class not being able to load AWS credentials when used within a Lambda function, despite working fine when used directly. It seems that I suggested modifying the Bedrock class to use default credentials when the credentials_profile_name
is not provided, allowing it to use the IAM role associated with the Lambda function. Other users also shared their experiences and suggestions, such as ensuring the correct version of boto3 and botocore are used and checking for the latest version of the docker environment.
Could you please confirm if this issue is still relevant to the latest version of the LangChain repository? If it is, please let the LangChain team know by commenting on the issue. Otherwise, feel free to close the issue yourself, or the issue will be automatically closed in 7 days. Thank you!
Issue you'd like to raise.
Bedrock can't seem to load my credentials when used within a Lambda function. My AWS credentials were set up in my local environment using environment variables. When I use the bedrock class directly, it is able to load my credentials and my code runs smoothly. Here is the RetrievalQA function that utilizes the bedrock class:
The above code runs without issues when used directly. However, when used within a lambda function, it fails. The scripts file used to build my lambda function uses the bedrock class as written above, however, I run into the
validation errors
when I invoke the Lambda function.{ "errorMessage": "1 validation error for Bedrock\n__root__\n Could not load credentials to authenticate with AWS client. Please check that credentials in the specified profile name are valid. (type=value_error)", "errorType": "ValidationError", "requestId": "b772f236-f582-4308-8af5-b5a418d4327f", "stackTrace": [ " File \"/var/task/main.py\", line 62, in handler\n response = qa(query)\n", " File \"/var/task/main.py\", line 32, in qa\n llm = Bedrock(model_id=\"amazon.titan-tg1-large\", region_name='us-east-1',) #client=BEDROCK_CLIENT)\n", " File \"/var/task/langchain/load/serializable.py\", line 74, in __init__\n super().__init__(**kwargs)\n", " File \"pydantic/main.py\", line 341, in pydantic.main.BaseModel.__init__\n raise validation_error\n" ]
As clearly indicated by the error message, bedrock couldn't load credentials.
Suggestion:
I have looked at the official documentation of the bedrock class but still do not understand why my code fails. Any help will be appreciated. @3coins @jasondotparse @hwchase17