• CloudPouch NEW!
  • Blog
  • O stronie
  • Home

Pierwsza funkcja Lambda


Pierwsza funkcja Lambda

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!

Ten artykuł jest częścią większego cyklu: Kurs Serverless

Na cały cykl składają się następujące artykuły. Jeśli jesteś tutaj pierwszy raz, to dobrze będzie zacząć od początku 😄
  1. Jak zainstalować Serverless Framework?
  2. Jak skonfigurować AWS CLI?
  3. Pierwsza funkcja Lambda
  4. Jak stworzyć usługę sieciową (webserwis) za pomocą AWS Lambda?
  5. "Śledź Paczkę" - wideokurs serverless

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
2
mkdir slspl
cd 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
2
3
4
5
6
7
8
9
10
11
Serverless: Generating boilerplate...
Serverless: Generating boilerplate in "/home/pawel/slspl/pierwsza-lambda"
_______ __
| _ .-----.----.--.--.-----.----| .-----.-----.-----.
| |___| -__| _| | | -__| _| | -__|__ --|__ --|
|____ |_____|__| \___/|_____|__| |__|_____|_____|_____|
| | | The Serverless Application Framework
| | serverless.com, v1.36.0
-------'

Serverless: Successfully generated boilerplate for template: "aws-nodejs"

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
2
3
4
5
6
7
8
9
10
11
12
13
serverless create --help 

Available templates:
"aws-clojure-gradle", "aws-clojurescript-gradle", "aws-nodejs", "aws-nodejs-typescript",
"aws-alexa-typescript", "aws-nodejs-ecma-script", "aws-python", "aws-python3",
"aws-groovy-gradle", "aws-java-maven", "aws-java-gradle", "aws-kotlin-jvm-maven",
"aws-kotlin-jvm-gradle", "aws-kotlin-nodejs-gradle", "aws-scala-sbt", "aws-csharp",
"aws-fsharp", "aws-go", "aws-go-dep", "aws-go-mod", "aws-ruby", "azure-nodejs",
"cloudflare-workers", "cloudflare-workers-enterprise", "fn-nodejs", "fn-go",
"google-nodejs", "kubeless-python", "kubeless-nodejs", "openwhisk-java-maven",
"openwhisk-nodejs", "openwhisk-php", "openwhisk-python", "openwhisk-ruby",
"openwhisk-swift", "spotinst-nodejs", "spotinst-python", "spotinst-ruby",
"spotinst-java8", "plugin" and "hello-world"

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

[serverless.yml]
1
2
3
4
5
6
7
service: pierwsza-lambda 
provider:
name: aws
runtime: nodejs8.10
functions:
hello:
handler: handler.hello

Na te siedem linijek kodu przypadają 3 sekcje:

  • service - nazwa naszego projektu / usługi - mikroserwisu
  • provider - definiuje naszego dostawcę chmury oraz język w jakim będziemy pisać funkcje.
  • functions - tutaj definiujemy swoje funkcje, w tym wypadku hello to nazwa logiczna (w konfiguracji) naszej funkcji, a handler 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.

[handler.js]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
'use strict';

module.exports.hello = async (event, context) => {
return {
statusCode: 200,
body: JSON.stringify({
message: 'Go Serverless v1.0! Your function executed successfully!',
input: event,
}),
};

// Use this code if you don't use the http event with the LAMBDA-PROXY integration
// return { message: 'Go Serverless v1.0! Your function executed successfully!', event };
};

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 HTTP
  • body - w którym będziemy mieli wiadomość message oraz cały obiekt event w postacie JSONa. Zwracanie body 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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
Serverless: Packaging service...
Serverless: Excluding development dependencies...
Serverless: Creating Stack...
Serverless: Checking Stack create progress...
.....
Serverless: Stack create finished...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading artifacts...
Serverless: Uploading service .zip file to S3 (387 B)...
Serverless: Validating template...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
...............
Serverless: Stack update finished...
Service Information
service: pierwsza-lambda
stage: dev
region: us-east-1
stack: pierwsza-lambda-dev
api keys:
None
endpoints:
None
functions:
hello: pierwsza-lambda-dev-hello
layers:
None

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:

  1. Spakował nasz kod źródłowy (handler.js) do pliku zip.
  2. 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.
  3. 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).
  4. Wysłał plik zip do wiaderka S3.
  5. Ustawił kod źródłowy z pliku zip jako aktualną wersję kodu naszej funkcji Lambda.
  6. 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
2
3
4
{
"statusCode": 200,
"body": "{\"message\":\"Go Serverless v1.0! Your function executed successfully!\",\"input\":{}}"
}

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
2
3
4
5
{
"statusCode": 200,
"body": "{\"message\":\"Go Serverless v1.0! Your function executed successfully!\",
\"input\":{\"parameter\":\"Serverless Polska jest super\"}}"
}

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ę.
Lista funkcji
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.
Szczegóły funkcji

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.
Szczegóły funkcji
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
2
3
4
5
6
Serverless: Getting all objects in S3 bucket...
Serverless: Removing objects in S3 bucket...
Serverless: Removing Stack...
Serverless: Checking Stack removal progress...
..........
Serverless: Stack removal finished...

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!




Cześć

Nazywam się Paweł Zubkiewicz i cieszę się, że tu jesteś!
Od ponad 18 lat profesjonalnie tworzę oprogramowanie, a od 2016 roku pasjonuje się Serverless.
Tą stronę stworzyłem z myślą o Tobie i o nas wszystkich, którzy uważają, że trend serverless trwale zmieni sposób tworzenia oprogramowania.
Więcej o tej stronie...

Kategorie

Pobierz bezpłatny PDF

Poradnik 12 Rzeczy o Serverless

Wybrane artykuły