Как стать автором
Обновить

Комментарии 28

AWS SAM прекрасный инструмент, просто другой подход, в отличии от использования terraform, который конкретно мне ближе. :)

Спасибо. Для меня подход с Terraform выглядит как стрельба из пушки по воробьям, да и много операций приходится выполнять руками. С AWS SAM подобная задача решилась бы двумя ресурсами (собственно, функцией и S3 бакетом) и не потребывала прописывания переменных окружения через UI.

Но с Terraform тоже, конечно, вариант.

Посоветую заодно посмотреть CDK, если еще не.

Несколько дополнений:

  • Если вам нужно только хранение файлов то S3 гораздо проще использовать без лямбды.

  • Если нужно еще сохранение метадату то как вариант повесить триггер на S3, который вызывается при добавлении туда объекта.

Оба варианта неуниверсальны, но для определнных юзкейсов будут удобнее, чем сохранение через лямбду.

Ваш подход имеет место быть при одном условии, если S3 bucket имеет публичный доступ, в противном случае без прослойки в виде сервера не обойтись. Иначе не получится организовать аутентификацию.
Можно конечно генерировать временные ссылки на объект, но они имеют ограниченный период действия, точно не помню 24 часа или 3 дня..

Ваш подход имеет место быть при одном условии, если S3 bucket имеет публичный доступ, в противном случае без прослойки в виде сервера не обойтись. Иначе не получится организовать аутентификацию.

API Gateway прекрасно решает эту проблему.

Доступ в S3 можно ограничивать по IAM. Или например использовать Api Gateway+S3. Lambda для этого ненужна.

Доступ извне вы не ограничите по IAM, когда клиенты приходят из разных уголков мира и доступ к entries (заметкам в журнале) в которые вы планируете сохранять картинки через lambda хранятся в виде зарегистрированных юзеров в вашем приложении, к которому необходимо постоянно обращаться, можно ли сохранять или отдавать картинку конкретному пользователю.
Думаю, я не достаточно развернуто описал usecase в статье. :)

Проблема вашего подхода в том, что у вас код авторизации написан прямо внутри лямбды. Это значит, что (а) его придется дублировать из лямбды в лямбду, если у вас много обработчиков и (б) на неавторизованный запрос все равно будет подниматься вся прикладная лямбда (со всем телом запроса), что невыгодно.

А зачем вам вообще VPC?


Ну и да, прогонять через лямбду тело файла, которое вам надо просто положить в S3 — плохая идея, зачем память-то лишний раз тратить?

Без VPC вы не создадите subnet, без subnet вы не создадите TargetGroup и LoadBalancer и в свою очередь сможете настроить Alias в Route53 во время создания записи с красивым uri формата images.myapp.com.

Не соглашусь, что это плохая идея, в зависимости от того какие цели преследуете, например как вы убедитесь, что картинка не та же самая, что уже была загружена для данной заметки? Тут нам нужно посчитать хэш и без сервера не обойтись. Тут конечно, можно рассчитать, что будет выгоднее, хранение одинаковых файлов в S3 bucket или лишний раз загрузить файл в lambda.
И конечно, функционал может быть расширен очень сильно - вычищать метаданные картинки (что делают все уважающие себя соц сети), сжимать и тд.

Без VPC вы не создадите subnet, без subnet вы не создадите TargetGroup и LoadBalancer и в свою очередь сможете настроить Alias в Route53 во время создания записи с красивым uri формата images.myapp.com.

Если цель — сделать красивый адрес, то API Gateway + Custom Domain прекрасно решают задачу без создания лоадбалансера.


Не соглашусь, что это плохая идея, в зависимости от того какие цели преследуете,

Я же специально написал: просто положить в S3.


И конечно, функционал может быть расширен очень сильно — вычищать метаданные картинки (что делают все уважающие себя соц сети), сжимать и тд.

Вот только может так оказаться, что намного эффективнее это делать не в лямбде при загрузке, а в лямбде, которая обрабатывает уже загруженный файл по событию — потому что она может читать файл из S3 чанками, а не обязана съесть все, что пришло в HTTP-запросе.

Если цель — сделать красивый адрес, то API Gateway + Custom Domain прекрасно решают задачу без создания лоадбалансера.

API Gateway + Custom Domain известный подход, думаю тут нужно отталкиваться от инфраструктуры. Аналогов данной статьи я не встречал, где мы имеем VPC с двумя подсетями. Конкретно это подход можно развивать уже далее, размещая сервера в приватную сеть, организовывая доступ через бастион хост и тд.

Вот только может так оказаться, что намного эффективнее это делать не в лямбде при загрузке, а в лямбде, которая обрабатывает уже загруженный файл по событию — потому что она может читать файл из S3 чанками, а не обязана съесть все, что пришло в HTTP-запросе.

Да, как вариант, если нам не нужна авторизация (можно ли сохранять картинку или нет)

Аналогов данной статьи я не встречал, где мы имеем VPC с двумя подсетями.

Так непонятно, зачем это, учитывая, что у вас заявленная задача — "serverless хранение файлов в S3", а S3, насколько я помню, плевать хотел VPC.


Конкретно это подход можно развивать уже далее, размещая сервера в приватную сеть, организовывая доступ через бастион хост и тд.

Зачем это для описанной в посте задачи?


Да, как вариант, если нам не нужна авторизация (можно ли сохранять картинку или нет)

Да нет, эта авторизация прекрасно делается на API Gateway (и, что характерно, она будет униформной для лямбды и для S3).

Зачем это для описанной в посте задачи?

Методы решения задачи могут любые, в данном примере решено через Load Balancer, можно через CloudFront, можно через API Gateway.

Я пытаюсь до вас донести (точнее, не столько до вас, сколько до будущих читателей статьи), что создавать VPC для реализации поставленной в посте задачи — избыточно.

А затраты памяти сопоставимы для Amazon, Google, Microsoft?

Не знаю, я не работал с отличными от AWS облаками.

Не использовал Cloud Functions, по прайсу примерно одно и то же.

НЛО прилетело и опубликовало эту надпись здесь

Предложенный вами подход с генерацией presign url не подходит, так как у них ограниченное время жизни ссылок (как я уже отвечал выше). Допустим для заметки вы загрузили картинку, вставили на нее ссылку в эту заметку, а через 36 часов она не валидна и не отображается.

НЛО прилетело и опубликовало эту надпись здесь

ссылки генерятся на загрузку, а не отдачу, раздача идет через Cloudfront. У Cloudfront другой механизм генерации ссылок (если он вообще нужен).

Но в таком случае доступен только функционал загрузки, но как отдать конечному юзеру файл, в вашем варианте? У Signed URLs необходимо задать публичный ключ, для верификации, это удобно для взаимодействия между сервисами, но не с тысячами пользователей.

НЛО прилетело и опубликовало эту надпись здесь

Во-первых, best practices - это общепринятые решения, потрудитесь мне привести аналог решения моей задачи, либо это голословные утверждения.
Во-вторых, я не AWS архитектор, я могу признать, что решение не оптимальное, но если выше @lair расписал подробно и объяснил его точку зрения. То вы даже не потрудились привести примерный пайплайн решения проблемы, при чем я скинул ссылку на доки где указано, что генератор CloudFront URL требует публичный ключ.

Особенно после следующего утверждения:

ни API Gateway из-за лимита 10Мб/30с, ни короткоживущая лямбда ... не подходят

Интересно послушать как выполнить аутентификацию на стороннем API api.myapp.com, обработать (сжать, конвертировать) изображение и сохранить его в S3 bucket.

НЛО прилетело и опубликовало эту надпись здесь

Выдать короткоживущую ссылку на загрузку с помощью лямбды (которая за api gateway), потом обработать по событию S3 чем угодно.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории