#python #amazon-web-services #amazon-s3 #aws-lambda
#python #amazon-веб-сервисы #amazon-s3 #aws-lambda
Вопрос:
Я пытаюсь запустить локальную разработку / отладку AWS Lambda с помощью Python3.8. Я использую vscode, и у меня включено расширение AWS Toolkit. Он отлично работал для базовой лямбда-функции «hello world», которую они вам предоставляют. Теперь я хочу изменить пример, чтобы прочитать некоторый текст из файла в S3, и когда я пытаюсь отладить его локально, я получаю сообщение об ошибке "An error occurred (AccessDenied) when calling the GetObject operation: Access Denied"
, но если я разверну приложение SAM в AWS, оно отлично работает в реальной среде AWS.
Насколько я могу судить, я S3ReadPolicy
правильно добавил файл в template.yaml
файл, потому что (как указано) он отлично работает в AWS при его развертывании — создаваемая роль имеет правильно добавленные разрешения на чтение S3. Но локальные запуски аварийно завершаются и записываются.
Что я делаю не так?
Вот хорошие результаты, которые я вижу, когда тестирую его на AWS после развертывания в AWS:
START RequestId: 8841bcdb-1f3c-4772-82a3-fb47c29ec594 Version: $LATEST
About to get data from s3.
Got some stuff out of s3:
Hello. This is a text file.
May the odds be ever in your favor.
END RequestId: 8841bcdb-1f3c-4772-82a3-fb47c29ec594
REPORT RequestId: 8841bcdb-1f3c-4772-82a3-fb47c29ec594 Duration: 1884.15 ms Billed Duration: 1900 ms Memory Size: 128 MB Max Memory Used: 77 MB Init Duration: 528.07 ms
Вот вывод и сообщение об ошибке, которые я вижу при локальном запуске:
Local invoke of SAM Application has ended.
Preparing to debug 'app___vsctk___debug.lambda_handler' locally...
Building SAM Application...
Build complete.
Starting the SAM Application locally (see Terminal for output)
Running command: [/usr/local/bin/sam local invoke awsToolkitSamLocalResource --template /tmp/aws-toolkit-vscode/vsctkdmFPUi/output/template.yaml --event /tmp/aws-toolkit-vscode/vsctkdmFPUi/event.json --env-vars /tmp/aws-toolkit-vscode/vsctkdmFPUi/env-vars.json -d 5858]
Invoking app___vsctk___debug.lambda_handler (python3.8)
Skip pulling image and use local one: amazon/aws-sam-cli-emulation-image-python3.8:rapid-1.6.2.
Mounting /tmp/aws-toolkit-vscode/vsctkdmFPUi/output/awsToolkitSamLocalResource as /var/task:ro,delegated inside runtime container
START RequestId: d3ff0f84-6f93-1065-b44d-ab9f5f174fdd Version: $LATEST
Waiting for debugger to attach...
Waiting for SAM Application to start before attaching debugger...
Attaching debugger to SAM Application...
Debugger attached
...debugger attached
About to get data from s3.
An error occurred (AccessDenied) when calling the GetObject operation: Access Denied
[ERROR] ClientError: An error occurred (AccessDenied) when calling the GetObject operation: Access Denied
Traceback (most recent call last):
File "/var/task/app___vsctk___debug.py", line 17, in lambda_handler
return _handler(event, context)
File "/var/task/app.py", line 17, in lambda_handler
raise(e)
File "/var/task/app.py", line 13, in lambda_handler
data = s3.get_object(Bucket=bucket, Key=key)
File "/var/task/botocore/client.py", line 357, in _api_call
return self._make_api_call(operation_name, kwargs)
File "/var/task/botocore/client.py", line 676, in _make_api_call
raise error_class(parsed_response, operation_name)
END RequestId: d3ff0f84-6f93-1065-b44d-ab9f5f174fdd
REPORT RequestId: d3ff0f84-6f93-1065-b44d-ab9f5f174fdd Init Duration: 1763.86 ms Duration: 1444.53 ms Billed Duration: 1500 ms Memory Size: 128 MB Max Memory Used: 54 MB
{"errorType":"ClientError","errorMessage":"An error occurred (AccessDenied) when calling the GetObject operation: Access Denied","stackTrace":[" File "/var/task/app___vsctk___debug.py", line 17, in lambda_handlern return _handler(event, context)n"," File "/var/task/app.py", line 17, in lambda_handlern raise(e)n"," File "/var/task/app.py", line 13, in lambda_handlern data = s3.get_object(Bucket=bucket, Key=key)n"," File "/var/task/botocore/client.py", line 357, in _api_calln return self._make_api_call(operation_name, kwargs)n"," File "/var/task/botocore/client.py", line 676, in _make_api_calln raise error_class(parsed_response, operation_name)n"]}
Local invoke of SAM Application has ended.
Вот соответствующие файлы:
lambda_test/hello_world/app.py
import boto3
import json
import time
def lambda_handler(event, context):
s3 = boto3.client('s3')
bucket = "rtb-imaginary-bucket"
key = "a-text-file.txt"
print('About to get data from s3.')
try:
data = s3.get_object(Bucket=bucket, Key=key)
file_content = data['Body'].read().decode('utf-8')
except Exception as e:
print(e)
raise(e)
print('Got some stuff out of s3:')
print(file_content)
return {
"statusCode": 200,
"body": json.dumps({
"message": "hello world",
"file_content": file_content
}),
}
lambda_test/template.yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
lambda_test
Sample SAM Template for lambda_test
# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
Function:
Timeout: 3
Resources:
HelloWorldFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: hello_world/
Handler: app.lambda_handler
Runtime: python3.8
Policies:
- S3ReadPolicy:
BucketName: rtb-imaginary-bucket
Events:
HelloWorld:
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Path: /hello
Method: get
Outputs:
# ServerlessRestApi is an implicit API created out of Events key under Serverless::Function
# Find out more about other implicit resources you can reference within SAM
# https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api
HelloWorldApi:
Description: "API Gateway endpoint URL for Prod stage for Hello World function"
Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/"
HelloWorldFunction:
Description: "Hello World Lambda Function ARN"
Value: !GetAtt HelloWorldFunction.Arn
HelloWorldFunctionIamRole:
Description: "Implicit IAM Role created for Hello World function"
Value: !GetAtt HelloWorldFunctionRole.Arn
.vscode /launch.json
{
"configurations": [
{
"type": "aws-sam",
"request": "direct-invoke",
"name": "lambda_test:app.lambda_handler (python3.8)",
"invokeTarget": {
"target": "code",
"projectRoot": "lambda_test/hello_world",
"lambdaHandler": "app.lambda_handler"
},
"lambda": {
"runtime": "python3.8",
"payload": {
"json": {
"key1": "value1",
"key2": "value2",
"key3": "value3"
}
},
"environmentVariables": {}
}
}
]
}
Комментарии:
1. Вы установили учетные данные AWS в vscode? Прямо сейчас это просто выглядит так, как будто локальная лямбда пытается получить доступ к S3 без каких-либо учетных данных, и ей по праву будет отказано в доступе.
2. @luk2302 Я так думаю? Расширение AWS может корректно исследовать мои объекты (например, можно увидеть мою корзину S3), и в правом нижнем углу я вижу, что он показывает, что мой «AWS: profile: rich personal» используется профиль учетных данных AWS. Должен ли я также поместить его куда-нибудь еще?
3. @luk2302 Да, насколько я могу судить. Я выполнил следующие шаги: docs.aws.amazon.com/toolkit-for-vscode/latest/userguide /… и мои два профиля определенно настроены в файле (в osx) /Users/myusername/.aws/credentials Поскольку палитра команд «AWS: Развертывание приложения SAM» работает правильно, я должен предположить, что он получает надлежащие учетные данные.
4. Настроили ли вы профиль учетных данных в свойствах подключения к aws вашей конфигурации SAM в launch.json? Например (я думаю):
"aws": { "credentials": "profile:knievel" }
5. @jarmod — Это сделало это! Я думаю, потому что я использовал профиль, отличный от профиля по умолчанию, мне пришлось добавить этот раздел туда. Я бы подумал, что он автоматически выбирает выбранный профиль, поскольку все остальное в vscode, похоже, работает, но я думаю, что нет. Для следующего пользователя, изучающего это, в таблице внизу этой страницы есть дополнительная информация: docs.aws.amazon.com/toolkit-for-vscode/latest/userguide /…
Ответ №1:
Насколько я знаю, функциональность SAM не наследует профиль учетных данных, который вы установили для инструментария AWS.
Вы можете явно задать профиль для SAM в вашем launch.json, например:
{
"configurations": [
{
"type": "aws-sam",
"invokeTarget": { ... },
"lambda": { ... },
"aws": {
"credentials": "profile:knievel"
}
}
]
}
Комментарии:
1. В Windows, в командной строке .. aws sso login —profile <myprofile> затем использовал sam local invoke ‘HelloWorldFunction’ —profile <myprofile> и это работает (ошибка недопустимого токена отсутствует…