При использовании локальной DynamoDB с докер-сетью SDK не может найти ресурс

Я использую AWS SAM для создания своего приложения, и мне нужно протестировать его локально. Мне удалось воссоздать это сообщение в блоге Как развернуть локальное бессерверное приложение с помощью AWS SAM. Выполняя те же шаги в другом проекте, я сталкиваюсь с ошибками. Я создал сеть докеров,

docker network create project-name

локальный экземпляр Dynamodb,

docker run --network project-name --name dynamodb -d -p 8000:8000 amazon/dynamodb-local

и стол

aws dynamodb create-table --table-name Cache-local --attribute-definitions AttributeName=ItemId,AttributeType=S --key-schema AttributeName=ItemId,KeyType=HASH --provisioned-throughput ReadCapacityUnits=5,WriteCapacityUnits=5 --endpoint-url http://localhost:8000.

Затем я создаю и локально вызываю лямбда-функцию DBSan.

sam build use-container

APP_ENV=local sam local invoke DBScan --docker-network project-name --profile poto

и получите ошибку {"errorMessage": "An error occurred (ResourceNotFoundException) when calling the DescribeTable operation: Cannot do operations on a non-existent table", "errorType": "ResourceNotFoundException", "stackTrace": [" File \"/var/task/app.py\", line 27, in dbScan\n print(table.creation_date_time)\n", " File \"/var/runtime/boto3/resources/factory.py\", line 339, in property_loader\n self.load()\n", " File \"/var/runtime/boto3/resources/factory.py\", line 505, in do_action\n response = action(self, *args, **kwargs)\n", " File \"/var/runtime/boto3/resources/action.py\", line 83, in __call__\n response = getattr(parent.meta.client, operation_name)(*args, **params)\n", " File \"/var/runtime/botocore/client.py\", line 357, in _api_call\n return self._make_api_call(operation_name, kwargs)\n", " File \"/var/runtime/botocore/client.py\", line 676, in _make_api_call\n raise error_class(parsed_response, operation_name)\n"]}

вот как я настраиваю соединение:

template.yaml

  DBScan:
    Type: AWS::Serverless::Function 
    Properties:
      CodeUri: src/
      Handler: app.dbScan
      Runtime: python3.8
      MemorySize: 512
      Timeout: 600
      Layers: 
        - !Ref DependenciesLayer
      Environment:
        Variables:
          APP_ENV: !Ref AppEnv
          REGION_NAME: us-east-2
      Events:
        DBScan:
          Type: Api 
          Properties:
            Path: /dbScan
            Method: GET
      Policies:
        - AWSLambdaBasicExecutionRole
        - DynamoDBCrudPolicy:
            TableName: !Ref CacheTable

app.py

app_env = os.environ['APP_ENV']
if app_env == 'local':
    print('in local environment')
    dynamo = boto3.resource('dynamodb', endpoint_url='http://dynamodb:8000/')
else:
    dynamo = boto3.resource('dynamodb', region_name=region_name)
def dbScan(event, context):
    print("Recieved event: " + json.dumps(event, indent=2))
    table_name = 'Cache-local'
    table = dynamo.Table(table_name)
    print(table.creation_date_time)
    return respond(None, res='test')

Я могу видеть динамо-машину и взаимодействовать с ней через Dynamodb-admin, я вручную ввел некоторые тестовые данные. Также когда я бегу

aws dynamodb scan --table-name Cache-local --endpoint-url http://localhost:8000 Я могу успешно сканировать Dynamodb. Когда я изменил endpoint_url='http://localhost:8000', я получаю другую ошибку

{"errorMessage": "Could not connect to the endpoint URL: \"http://localhost:8000/\"", "errorType": "EndpointConnectionError", "stackTrace": [" File \"/var/task/app.py\", line 27, in dbScan\n print(table.creation_date_time)\n", " File \"/var/runtime/boto3/resources/factory.py\", line 339, in property_loader\n self.load()\n", " File \"/var/runtime/boto3/resources/factory.py\", line 505, in do_action\n response = action(self, *args, **kwargs)\n", " File \"/var/runtime/boto3/resources/action.py\", line 83, in __call__\n response = getattr(parent.meta.client, operation_name)(*args, **params)\n", " File \"/var/runtime/botocore/client.py\", line 357, in _api_call\n return self._make_api_call(operation_name, kwargs)\n", " File \"/var/runtime/botocore/client.py\", line 662, in _make_api_call\n http, parsed_response = self._make_request(\n", " File \"/var/runtime/botocore/client.py\", line 682, in _make_request\n return self._endpoint.make_request(operation_model, request_dict)\n", " File \"/var/runtime/botocore/endpoint.py\", line 102, in make_request\n return self._send_request(request_dict, operation_model)\n", " File \"/var/runtime/botocore/endpoint.py\", line 136, in _send_request\n while self._needs_retry(attempts, operation_model, request_dict,\n", " File \"/var/runtime/botocore/endpoint.py\", line 253, in _needs_retry\n responses = self._event_emitter.emit(\n", " File \"/var/runtime/botocore/hooks.py\", line 356, in emit\n return self._emitter.emit(aliased_event_name, **kwargs)\n", " File \"/var/runtime/botocore/hooks.py\", line 228, in emit\n return self._emit(event_name, kwargs)\n", " File \"/var/runtime/botocore/hooks.py\", line 211, in _emit\n response = handler(**kwargs)\n", " File \"/var/runtime/botocore/retryhandler.py\", line 183, in __call__\n if self._checker(attempts, response, caught_exception):\n", " File \"/var/runtime/botocore/retryhandler.py\", line 250, in __call__\n should_retry = self._should_retry(attempt_number, response,\n", " File \"/var/runtime/botocore/retryhandler.py\", line 277, in _should_retry\n return self._checker(attempt_number, response, caught_exception)\n", " File \"/var/runtime/botocore/retryhandler.py\", line 316, in __call__\n checker_response = checker(attempt_number, response,\n", " File \"/var/runtime/botocore/retryhandler.py\", line 222, in __call__\n return self._check_caught_exception(\n", " File \"/var/runtime/botocore/retryhandler.py\", line 359, in _check_caught_exception\n raise caught_exception\n", " File \"/var/runtime/botocore/endpoint.py\", line 200, in _do_get_response\n http_response = self._send(request)\n", " File \"/var/runtime/botocore/endpoint.py\", line 269, in _send\n return self.http_session.send(request)\n", " File \"/var/runtime/botocore/httpsession.py\", line 343, in send\n raise EndpointConnectionError(endpoint_url=request.url, error=e)\n"]}

Кроме того, когда я создаю автономный скрипт, я могу успешно подключиться к Dynamodb.

import boto3

dynamodb = boto3.resource('dynamodb', endpoint_url='http://localhost:8000')
table = dynamodb.Table('Cache-local')
print(table.creation_date_time)

>>> 2021-06-17 09:23:44.157000-06:00


person Andrew    schedule 17.06.2021    source источник
comment
Отвечает ли это на ваш вопрос? Подключиться к контейнеру Docker MySQL с локального хоста?   -  person petey    schedule 20.06.2021
comment
Нет, это не совсем то, что я ищу.   -  person Andrew    schedule 21.06.2021