
Джанака Бондаря

Вычисление! У него, безусловно, очень длинная, яркая (и подчас неуклюжая) история. Некоторые ключевые вехи включают в себя:

Согласно всему этому, парадигмы программного обеспечения также резко изменились. Начиная от программирования на основе аппаратного обеспечения до монолитов, модульности, SOA, облака, а теперь… без сервера.
В настоящее время «бессерверный» обычно означает FaaS (функции как услуга). А FaaS практически означает AWS Lambda, как с точки зрения популярности, так и с точки зрения внедрения.
Следовательно, не будет преувеличением утверждать, что популярность бессерверной разработки может быть связана с простотой использования Lambda. Или это?

Что ж, Lambda существует с 2015 года. Она уже встроена в огромную часть экосистемы AWS и употребляется в производстве сотками (если не тыщами) компаний. Итак, Lambda должна быть достаточно интуитивно понятной и простой в использовании, не правда ли?
Ну, в моем случае, казалось, нет.
И поскольку «мой случай» был одним из официальных примеров AWS, я не совсем уверен, что Lambda достаточно дружественна для новичков.
Для начала я хотел реализовать свой вариант создания миниатюр AWS без следуя их собственному гиду, чтобы увидеть, как далеко я могу зайти.
Как программист, я, естественно, начал с консоли управления Lambda. Код уже был написан щедрыми разработчиками AWS, и зачем изобретать колесо? Копировать, вставлять, хранить, запускать. Та да!
Хм, похоже, мне нужно немного повзрослеть.
Мастер «Создать функцию» привлек внимание с таким количеством готовых чертежей. Жаль, что у него еще не было примера поколения эскиза S3, иначе эта история могла закончиться прямо на этом!
Так что я просто пошел дальше с опцией «Автор с нуля», используя название s3-thumbnail-generator
.
Подождите, что это за роль? Это тоже нужно. К счастью, в нем есть опция «Создать новую роль из шаблонов», которая спасет меня.
Успокойся. «Название роли»: s3-thumbnail-generator-role
. Но как насчет «шаблона политики»?
Возможно, мне стоит найти что-то связанное с S3, поскольку моя Lambda полностью S3.
Сюрприз! Единственное, что я получаю, когда ищу S3, это «разрешение только для чтения объектов S3». Не имея другого выбора, я просто выхватил его. Посмотрим, как далеко я смогу зайти, пока не упаду на лицо!
Пора нажать «Создать функцию».

Ого, их дизайнер Lambda смотрится очень круто!

«Приветствую! Ваша лямбда-функция «s3-thumbnail-generator» была успешно создана. Теперь можно изменить его код и конфигурацию. Нажмите кнопку «Тестировать», чтобы ввести тестовое событие, когда вы будете готовы проверить свою функцию.
Ладно, время для моей миссии копирования и вставки. «Скопировать» исходный код образца, Ctrl+A
и Ctrl+V
в редакторе кода Lambda. Просто!
Всё зеленое (без красных). Хорошо знать.
«Сохранить» и «Тестировать».

О, я должен был лучше знать. Да, если я собираюсь «Тестировать», мне нужен «Тестовый вход». Очевидно.
Я знал, что проверить мою новенькую Lambda будет не так-то просто. Но я не ожидал, что мне придется собрать JSON-сериализированное событие вручную.
К счастью, разработчики AWS проделали отличную работу и здесь, предоставив готовый шаблон события «S3 Put». Что бы я еще выбрал?

Как и ожидалось, первый запуск был неудачным:
{ "errorMessage": "Cannot find module 'async'", "errorType": "Error", "stackTrace": [ "Function.Module._load (module.js:417:25)", "Module.require (module.js:497:17)", "require (internal/module.js:20:19)", "Object. (/var/task/index.js:2:13)", "Module._compile (module.js:570:32)", "Object.Module._extensions..js (module.js:579:10)", "Module.load (module.js:487:32)", "tryModuleLoad (module.js:446:12)", "Function.Module._load (module.js:438:3)" ]}
Блин, я должен был это заметить require
линии.
И в любом случае это моя беда. Страница, где я скопировал образец кода, имела большое толстое название «Создайте лямбда Пакет развертывания«, и ясно объяснили, как объединить образец в zip-файл, который можно разворачивать на Lambda.
Итак, я создал локальный каталог, содержащий мой код, и package.json
и запустил npm install
(хорошо, что я имел node
и npm
предварительно установлено!).
Создание, архивирование и загрузка программы было достаточно простым, и надеюсь, мне не придется проходить через миллион и один такой цикл, чтобы заставить мой Lambda работать.
(Кстати, я хотел бы сделать это в их встроенном редакторе. Жаль, что я не мог найти способ добавить зависимости.)
Во всяком случае, пришло время для моего второго испытания.
{ "errorMessage": "Cannot find module '/var/task/index'", "errorType": "Error", "stackTrace": [ "Function.Module._load (module.js:417:25)", "Module.require (module.js:497:17)", "require (internal/module.js:20:19)" ]}
index
? Откуда это взялось?
Подожди… беда, беда.

Вроде того Обработчик параметр все еще сохраняет значение по умолчанию index.handler
. В моем случае так должно быть CreateThumbnail.handler
(filename.method
).
Давайте попробуем еще раз.

Серьезно? Ни в коем случае!
Ах так. Бревно не врут.
2018-02-04T17:00:37.060Z ea9f8010-09cc-11e8-b91c-53f9f669b596 Unable to resize sourcebucket/HappyFace.jpg and upload to sourcebucketresized/resized-HappyFace.jpg due to an error: AccessDenied: Access DeniedEND RequestId: ea9f8010-09cc-11e8-b91c-53f9f669b596
Справедливо. я не имею sourcebucket
или sourcebucketresized
но, вероятно, кто-то другой. Отсюда и отказ в доступе. Имеет смысл.
Так что я создал собственные ведра, s3-thumb-input
и s3-thumb-inputresized
отредактировал мои введенные события (благодаря нисходящему списку «Настроить тестовое событие») и попробовал снова.
2018-02-04T17:06:26.698Z bbf940c2-09cd-11e8-b0c7-f750301eb569 Unable to resize s3-thumb-input/HappyFace.jpg and upload to s3-thumb-inputresized/resized-HappyFace.jpg due to an error: AccessDenied: Access Denied
Доступ запрещен? Снова?
К счастью, на основе ввода события я понял, что 403 действительно может указывать на ошибку 404 (не найдено), поскольку мое ведро на самом деле не содержало HappyFace.jpg
файл.
Подожди, дорогой читатель, пока я устремлюсь к консоли S3 и загрузу свое счастливое лицо в свое новое ведро. Минутку!
Ладно, готов к следующему раунду тестирования.
2018-02-04T17:12:53.028Z a2420a1c-09ce-11e8-9506-d10b864e6462 Unable to resize s3-thumb-input/HappyFace.jpg and upload to s3-thumb-inputresized/resized-HappyFace.jpg due to an error: AccessDenied: Access Denied
Точно такая же ошибка? Снова? Давай!
Для меня это не имело смысла. Зачем мне собственный Лямбда работает в моем собственный Учетная запись AWS не имеет доступа к моему собственный Ведро S3?
Подождите, может ли это быть связано с ролью исполнения? Часть, где я вслепую назначил S3 только для чтения разрешения?
Немного поисков Google привел меня к чрезвычайно полной документации AWS IAM для Lambda. Там я узнал, что Lambda играет свою роль IAM. Мне пришлось бы вручную настроить роль на основе того, какие службы AWS я буду использовать.
Что хуже, чтобы настроить роль, мне нужно пройти весь путь к консоли управления IAM. К счастью, это уже связано с нисходящим меню роли исполнения. Что еще более важно, он открывается в новой вкладке.

Держим пальцы, пока не загрузится страница специальной роли.

О нет… Больше редактирования JSON?
В оригинальном руководстве разработчики AWS, казалось, также определили роль исполнения. Но было удивительно, что там не было ни одного упоминания о S3 (кроме названия). Они что-нибудь пропустили?
Ладно, впервые в истории я создаю собственную роль IAM!
Благослови этих инженеров AWS! Быстрый поиск в Google обнаружил их драгоценность для генератора политик. Именно то, что мне нужно.
Но лишение синтаксиса JSON решает только небольшую часть проблемы. Как я могу узнать, какие мне разрешения нужны?
Google, друг? что-то?
Ой… Вернуться к документам AWS? Прекрасно…
Ну, это было не так уж плохо, благодаря руководству по разрешениям S3.
Хотя это было несколько ошеломляюще, я догадался, что мне нужны некоторые разрешения на «сделки с объектами». К счастью, у дока был хороший стол, предположив, что мне нужно s3:GetObject
и s3:PutObject
(отвечает к s3.getObject(...)
и s3.putObject(...)
вызовы в коде).

После некоторых размышлений я получил «Политику IAM» с указанными выше разрешениями на моем ведре (название с скучным синтаксисом arn:aws:s3:::s3-thumb-input
):
{ "Version": "2012-10-17", "Statement": [ { "Sid": "Stmt1517766308321", "Action": [ "s3:PutObject" ], "Effect": "Allow", "Resource": "arn:aws:s3:::s3-thumb-inputresized" }, { "Sid": "Stmt1517766328849", "Action": [ "s3:GetObject" ], "Effect": "Allow", "Resource": "arn:aws:s3:::s3-thumb-input" } ]}
Я вставил и сохранил его в редакторе ролей IAM (что автоматически вернуло меня на страницу консоли Lambda – как хорошо!)
Попробуйте снова…
Та же ошибка?!
Просматривая документ о разрешениях S3, я заметил, что разрешения объекта содержат звездочку (/*
суффикс, который, вероятно, указывает на файлы) под названием ресурса. Давайте попробуем это с помощью новой специальной политики:
{ "Version": "2012-10-17", "Statement": [ { "Sid": "Stmt1517766308321", "Action": [ "s3:PutObject" ], "Effect": "Allow", "Resource": "arn:aws:s3:::s3-thumb-inputresized/*" }, { "Sid": "Stmt1517766328849", "Action": [ "s3:GetObject" ], "Effect": "Allow", "Resource": "arn:aws:s3:::s3-thumb-input/*" } ]}
Снова! (это начинает звучать как Whiplash):
2018-02-04T17:53:45.484Z 57ce3a71-09d4-11e8-a2c5-a30ce229e8b7 Successfully resized s3-thumb-input/HappyFace.jpg and uploaded to s3-thumb-inputresized/resized-HappyFace.jpg
УУ-УУ!!!
Верьте или нет, а resized-HappyFace.jpg
файл только что появился в моем s3-thumb-inputresized
ведро! О да!
Теперь как я могу настроить мой Lambda на автоматический запуск, когда я опускаю файл в свое ведро?
К счастью, консоль Lambda (с ее интуитивно понятной компоновкой «триггер-функция-разрешения») ясно показала, что мне нужен триггер S3. Я добавил один из «Объект создан (все)» как «Тип события» и «jpg» как суффикс, сохранил все и сразу забросил файл JPG в свое ведро.

Да, работает как шарм.
Чтобы увидеть, сколько времени занял весь процесс (в фактическом исполнении, в отличие от «тестов»), я щелкнул ссылку «журналы» на (предыдущей) панели результатов выполнения и перешел к новейшему «потоку журналов», который там отображается. Ничего!
И еще более подозрительно, что последний журнал в новейшем потоке журнала был журналом «доступ запрещен», хотя я прошел этот момент и даже достиг успешного изменения размера.
Возможно, мое последнее изменение нарушило способность журналирования Lambda?
Благодаря Google и StackOverflow я обнаружил, что моя роль в исполнении также должна содержать некоторые разрешения, связанные с журналированием.
Теперь я помню, что были некоторые разрешения в текстовом поле редактора разрешений, когда начал создавать свою настраиваемую роль. Снова я был достаточно невеждой, чтобы наклеить свои политики S3 прямо поверх них.
Еще один раунд редактирования политики:
{ "Version": "2012-10-17", "Statement": [ { "Sid": "Stmt1517766308321", "Action": [ "s3:PutObject" ], "Effect": "Allow", "Resource": "arn:aws:s3:::s3-thumb-inputresized/*" }, { "Sid": "Stmt1517766328849", "Action": [ "s3:GetObject" ], "Effect": "Allow", "Resource": "arn:aws:s3:::s3-thumb-input/*" }, { "Action": [ "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents" ], "Effect": "Allow", "Resource": "arn:aws:logs:*:*:*" } ]}
Еще одно удаление файла, и на этот раз и изменение размера, и журналы работали безупречно… Наконец-то!
Теперь, когда все отлажено, и мой миниатюра ждет в назначенном ведре, я запустил свой браузер, набрал (согласно документам виртуального хостинга S3). Я нажал клавишу Enter, ожидая хорошей миниатюры в ответ.
<Error> <Code>AccessDenied</Code> <Message>Access Denied</Message> <RequestId>C8BAC3D4EADFF577</RequestId> <HostId>PRnGbZ2olpLi2eJ5cYCy0Wqliqq5j1OHGYvj/ HPmWqnBBWn5EMrfwSIrf2Y1LGfDT/7fgRjl5Io=</HostId></Error>
Устал от сообщения «Доступ запрещен»!
Очевидно, хотя мой код генерирует файл, он не делает файл общедоступным (но какая польза от приватной миниатюры, а?)
Копаясь в документах AWS, я вскоре обнаружил ACL
параметр putObject
операция, позволяющая загруженному S3 файлу быть общедоступным. Надеясь, что это решит все проблемы на планете, я быстро обновил свой код, чтобы установить ACL файл на public-read
:
s3.putObject({ Bucket: dstBucket, Key: dstKey, Body: data, ContentType: contentType, ACL: 'public-read' }, next); }
Сохраните функцию и нажмите кнопку Test:
2018-02-04T18:06:40.271Z 12e44f61-19fe-11e8-92e1-3f4fff4227fa Unable to resize s3-thumb-input/HappyFace.jpg and upload to s3-thumb-inputresized/resized-HappyFace.jpg due to an error: AccessDenied: Access Denied
Снова?? Вы шутите?
К счастью, на этот раз я знал достаточно, чтобы сразу перейти к руководству с разрешений S3, который сразу обнаружил, что мне тоже нужно иметь s3:PutObjectAcl
разрешение в моей политике, чтобы использовать ACL
параметр в моем putObject
вызов.
Итак, еще одно путешествие к редактору политики, к информационной панели IAM и обратно к консоли Lambda.
2018-02-04T18:15:09.670Z 1d8dd7b0-19ff-11e8-afc0-138b93af2c40 Successfully resized s3-thumb-input/HappyFace.jpg and uploaded to s3-thumb-inputresized/resized-HappyFace.jpg
И на этот раз, к моему большому удовольствию, браузер с удовольствием показал мне миниатюру моего счастливого лица, когда я передал URL-адрес хостинга в это.
В общем я доволен тем, что наконец-то смог решить головоломку самостоятельно, сложив все разбросанные кусочки вместе.
Но я не могу не представить, как было бы круто, если бы я мог создать свою Lambda в свободном стиле, а AWS заботился бы о ролях, разрешениях и прочем, самостоятельно, не получая меня бегать по кварталу.
Возможно, я должен следовать этому официальному руководству с самого начала…
… но опять же, где в этом веселье?! 🙂