Doszliśmy do wspaniałego momentu kiedy możemy użyć naszych narzędzi i stworzyć projekt, a w nim pierwszą funkcję lambda. Ja używam do pracy Ubuntu (w VirtualBox) oraz VS Code (tutaj możesz przeczytać dlaczego). Ty możesz używać dowolnego systemu operacyjnego, komendy będą praktycznie identyczne.
To zaczynamy!
Tworzymy nowy projekt
Będziemy pracować za pomocą komend w linii poleceń, zatem otwórz terminal w swoim systemie. Przygotujmy sobie folder na dysku, proponuje slspl
- jak “sls” = serverless i “pl” = Polska. :-)
1 | mkdir slspl |
A teraz stwórzmy swój pierwszy projekt.
1 | serverless create --template aws-nodejs -p pierwsza-lambda |
Co da następując efekt:
1 | Serverless: Generating boilerplate... |
Serverless Framework stworzył dla nas w katalogu ~/slspl/pierwsza-lambda
dwa pliki:
serverless.yml
- plik konfiguracyjny, w którym zdefiniujemy naszą lambdę, a w przyszłości zasoby (usługi AWS’owe) dla całej aplikacji.handler.js
- plik źródłowy w JavaScript. Tutaj znajduje się kod, który zostanie umieszczony w Lambdzie zdefiniowanej w pliku powyżej.
Mamy konfigurację dla JavaScript ponieważ z takiego szablonu skorzystaliśmy pisząc --template "aws-nodejs"
. Jest oczywiście mnóstwo innych opcji:
1 | serverless create --help |
Jak widać, framework obsługuje różne chmury publiczne oraz różne języki. Ja korzystam z JavaScript z wielu powodów, o których napisałem w publikacji 12 Rzeczy o Serverless, Które Musisz Wiedzieć Przed Rozpoczęciem Projektu W Chmurze AWS. Jeśli jesteś ich ciekaw to odsyłam Cię do niej, punkt numer 7.
Przyjrzyjmy się wygenerowanym plikom. Pozwoliłem sobie usunąć komentarze z pliku przy pomocy grep -o '^[^#]*' serverless.yml
(uwaga: to pewnie nie zadziała pod Windowsem) aby zwiększyć jego czytelność.
serverless.yml
1 | service: pierwsza-lambda |
Na te siedem linijek kodu przypadają 3 sekcje:
service
- nazwa naszego projektu / usługi - mikroserwisuprovider
- definiuje naszego dostawcę chmury oraz język w jakim będziemy pisać funkcje.functions
- tutaj definiujemy swoje funkcje, w tym wypadkuhello
to nazwa logiczna (w konfiguracji) naszej funkcji, ahandler
definiuje nazwę pliku (z pominięciem rozszerzenia) i metody która będzie wywołana przez AWS gdy nasza Lambda zostanie wywołana.
handler.js
W tym pliku znajduje się kod źródłowy naszej funkcji.
1 | ; |
Należy wspomnieć o tym, co się dzieje w linijce numer 3.
Po pierwsze, module.exports.hello
odpowiada temu hello
z linijki 7 w pliku serverless.yml. module.exports
to jest natywne rozwiązanie JavaScript, natomiast hello
to w tym wypadku nazwa funkcji JavaScript, którą uruchomi AWS gdy wywołamy funkcję Lambda.
Po drugie, słowo async
oznacza, że funkcja jest asynchroniczna. To znów natywne rzeczy JavaScript, które na razie nie są ważne dla nas.
Po trzecie, po async
mamy w nawiasie dwa parametry: event
oraz context
. Są to standardowe parametry interfejsu Lambdy. Przykładowo w event
możemy otrzymać wartości parametrów z jakimi została wywołana Lambda.
Funkcja jest trywialna, zwraca obiekt w którym znajdują się dwie wartości:
statusCode
- który informuje odbiorcę o tym czy funkcja wykonała się poprawnie, są to standardowe kody odpowiedzi HTTPbody
- w którym będziemy mieli wiadomośćmessage
oraz cały obiektevent
w postacie JSONa. Zwracaniebody
to konwencja, zmienna może się nazywać zupełnie inaczej i zawierać co nam się podoba, oczywiście w ramach limitów Lambdy.
Deployment funkcji do chmury
Teraz możemy przystąpić do działania. Aha, jeszcze jedna uwaga jeśli nie chcesz pisać długiej komendy serverless
możesz się posłużyć aliasem sls
. Uruchom komendę sls deploy
, co da efekt jak poniżej:
1 | Serverless: Packaging service... |
Wszystko to trwało minutę i dwadzieścia sekund. Spróbujesz to wyklikać w tym czasie? 😋
Ale tak na poważnie, co się wydarzyło?
Serverless Framework odpowiednio:
- Spakował nasz kod źródłowy (
handler.js
) do pliku zip. - Na podstawie pliku
serverless.yml
wygenerował szablon CloudFormation - to jest język opisu infrastruktury w chmurze AWS. Bardzo popularny i powszechnie używany, jednak dużo bardziej skomplikowany niż “uproszczona” wersja konfiguracji naszego frameworku Serverless. - Korzystając z naszych credentials które skonfigurowaliśmy w poprzedniej lekcji, połączył się do AWS i stworzył dla nas zasoby (a dokładniej uruchomił, wygenerowany wcześniej, szablon CloudFormation).
- Wysłał plik zip do wiaderka S3.
- Ustawił kod źródłowy z pliku zip jako aktualną wersję kodu naszej funkcji Lambda.
- Wyświetlił informację na temat naszego serwisu/usługi (w obrębie jednego serwisu możemy mieć więcej funkcji Lambda).
Uruchomienie funkcji
Teraz pora przetestować, czy to wszystko działa. Napisz proszę sls invoke --function hello
. Parametr --function
służy do określenia, którą funkcję chcemy wywołać (invoke
). Efektem tej komendy będzie następujący JSON:
1 | { |
Hurra 🎉 Kod wywołał się gdzieś w chmurze Amazonu, a my widzimy tylko efekt!
Bez serwerów, bez zaprzątania sobie głowy infrastrukturą!
Wartość pola body
to tak zwany stringified JSON (JSONa w postaci stringa). Zwróć uwagę, że input
jest pustym obiektem {}
, ponieważ wywołaliśmy funkcję bez parametrów.
Spróbujmy podać teraz jakiś parametr:
1 | sls invoke -f hello -d '{"parameter": "Serverless Polska jest super"}' |
Parametr -f
to alias na --function
, a -d
to alias na --data
- który pozwala przesłać jakieś dane do funkcji, w naszym wypadku znów prostą parę klucz: wartość
jako stringified JSON.
Tym razem, nasza Lambda zwróci parametr wejściowy i jego wartość:
1 | { |
Na pewno jesteś oszołomiony tym, że to wszystko działa. Spokojnie, tylko sobie żartuję 😋 Przypuszczam jednak, że jesteś zainteresowany gdzie dokładnie ta Lambda się znajduje i jak to wszystko wygląda od strony AWS.
Gdzie szukać Lambdy?
Ponieważ obecna konfiguracja naszego serwisu jest dosyć uboga (7 linijek) i nie definiuje regionu to Serverless Framework posłużył się domyślnym regionem, czyli N.Virginia (us-east-1).
Wejdź proszę na stronę https://console.aws.amazon.com/lambda/home?region=us-east-1#/functions i zobacz czy widzisz naszą funkcję.
Serverless Framework narzuca pewną konwencję nazewniczą. Jest to <nazwa_serwisu>-<stage>-<nazwa_funkcji> (serwis i projekt rozumiem tutaj jako tożsame), dzięki czemu bardzo łatwo się połapać, gdy ma się dużo funkcji 😎
Klikając na nazwę funkcji możemy zobaczyć jej szczegóły.
Zaznaczyłem kilka ważnych elementów:
- Każdy zasób w AWS ma swoje unikalne id (zamazałem fragment z numerem mojego konta AWS)
- Tak jak wspominałem, framework używa CloudFormation. Funkcja jest częścią stworzonego stacka.
- Po środku widać nazwę funkcji oraz jej powiązania, w chwili obecnej nie ma żadnego triggera ale za to integruje się z CloudWatch aby zapisywać logi - jest to standardowe rozwiązanie do obsługi logów w AWS
Dalej zobaczysz kod funkcji, a poniżej od niego: ustawienia roli, pamięci i timeoutu.
Powyższe ustawienia można (i należy) zdefiniować w pliku serverless.yml
ale o tym w kolejnych lekcjach 😊
Usuwanie funkcji i całej reszty
Serverless Framework stworzył dla nas (za pomocą CloudFormation) następujące zasoby w chmurze:
- funkcje Lambda
- Role IAM
- Grupę logów w CloudWatch
- Wiaderko S3 gdzie umieścił plik zip z kodem źródłowym
To całkiem sporo jak na tak trywialną rzecz. Dlaczego o tym piszę?
Ponieważ chcę, abyś wiedział jak dużo Serverless Framework robi za Ciebie. Uwierz mi, bardzo łatwo jest “zaśmiecić” swoje konto AWS różnymi zasobami, gdy tworzy się je ręcznie. Potem niezmiernie trudno jest ustalić, co z czym jest powiązane i czy w ogóle jest jeszcze potrzebne? Dlatego genialną rzeczą - i oczywiście dobrą praktyką - jest usuwanie wszystkiego co się stworzyło, a nie zamierza się więcej używać. (Z reguły zasoby serverless są bardzo tanie gdy się ich nie używa, ale już w przypadku *”tradycyjnych”* zasobów, takich jak maszyny wirtualne, bazy danych, czy load balancery, koszty takiego zapomnianego zasobu mogą być bardzo duże. Sam w zeszłym roku straciłem blisko 200 USD na zapomnianym przez 3 miesiące kontenerze w AWS Fargate 😞).
Uruchom proszę w swoim terminalu komendę sls remove
.
1 | Serverless: Getting all objects in S3 bucket... |
W taki oto sposób możemy łatwo usunąć cały serwis i jego zasoby z konta AWS.
To wszystko w tej lekcji. Następnym razem pokażę Ci jak wystawiać funkcję AWS Lambda na świat i wywołać ją przez HTTP jak zwykły webserwis.
Dziękuję za uwagę. Miłego dnia!