AWS Lambda Layers. Nowość na re:Invent 2018
Artykuł ukazał się pierwotnie na blogu Chmurowiska.
Można chyba śmiało powiedzieć, iż udostępniona światu w listopadzie 2014 roku usługa AWS Lambda zmienia podejście do cloud computingu. Za jej pomocą możemy uruchamiać kod naszych aplikacji bez „zabawy” w zarządzanie infrastrukturą pod spodem.
Utworzenie Lambdy jest prost. Tworzymy nasz kod, dodajemy wszystkie niezbędne zależności, pakujemy to w zip-a i wrzucamy bezpośrednio lub poprzez S3 do usługi.
Kluczowe w poprzednim zdaniu jest sformułowanie wszystkie niezbędne zależności. Tak, zawsze konieczne było uploadowanie wszystkich zależności. Nawet jeżeli zmienialiśmy w naszym kodzie jedną linijkę, to musieliśmy jeszcze raz wrzucać całą, nie rzadko wielomegabajtową paczkę.
I tu z pomocą nadchodzą zaprezentowane na re:Invent 2018
AWS Lambda Layers
Za pomocą AWS Lambda Layers możemy tak skonfigurować naszą funkcję Lambda, aby korzystała z dodatkowego kodu, którego nie ma w samej paczce z funkcją. W takiej warstwie, w formie pliku zip, umieszczamy czy to dodatkowe biblioteki, czy też nasz kod, który możemy współdzielić później w różnych Lambdach.
Funkcja Lambda może korzystać maksymalnie 5 pięciu dodatkowych warstw. Każda z takiej warstwy może mieć wiele wersji.
Możemy korzystać z własnych warstw, z udostępnionych przez innych użytkowników (jest wsparcie dla resource based policies) oraz tych, które przygotował dla nas AWS

Jak dodać swój AWS Lambda Layer
Pokaże to na przykładzie Pythona. Jest to dość proste. Załóżmy, że chcemy po prostu udostępnić jakiś moduł z funkcją. Niech to będzie banalna funkcja dodająca dwie liczby.
def sum(a, b):
return a + b
Zapisujemy ją w pliku np.: sum.py i umieszczamy w jakimś katalogu python. To jest dość ważne, aby była właśnie w katalogu python. Kompresujemy cały katalog np. do pliku python.zip i w konsoli AWS

wybieramy sekcję Layers i Create Layer.
Ukazuje się nam interfejs na którym możemy nazwać naszą warstwę (1), dodać do niej jakiś opis (2)

dodać nasz plik zip z zawartością. Możemy także wybrać te runtime, z którymi nasz Layer może współpracować (4), oraz podać url do ewentualnej licencji.
Po kliknięciu w przycisk Create nasz layer powinien się utworzyć i powinna się nam ukazać konfiguracja pierwszej wersji.

Mamy właściwie wszystko gotowe, aby skorzystać z naszej warstwy.
Jak skorzystać z AWS Lambda Layer
Tworzymy oczywiście jakąś funkcję Lambda. W lekko zmienionej konsoli możemy zarządzać między innymi tym, jakie layers są podłączone pod naszą funkcję Lambda

Jeżeli klikniemy w Layers to pojawi się możliwość ich dodania do lambdy

Klikamy w Add a layer i wybieramy ten layer, który chcemy dodać.

Ja wybrałem swój layer Addder w wersji pierwszej. Po kliknięciu w przycisk Add i zapisaniu zmian w samej Lambdzie, mamy praktycznie wszystko gotowe. Możemy zacząć kodować.
W Pythonie korzystanie z modułów dołączony w layerach jest bardzo proste. Importujemy po prostu naszą funkcję
from sum import sum
i możemy z niej korzystać. Przykładowe wywołanie funkcji Lambda z kodem
from sum import sum
def lambda_handler(event, context):
print(sum(9,6))
skorzysta z funkcji z modułu i zwróci wynik
Function Logs:
START RequestId: caf001a5-fbbc-11e8-a20c-25d4404fa079 Version: $LATEST
15
END RequestId: caf001a5-fbbc-11e8-a20c-25d4404fa079
Co z zależnościami?
AWS Lambda Layers to też znakomity sposób na wykorzystanie zewnętrznych bibliotek i zależności. Wystarczy przygotować sobie pakiet z potrzebnymi modułami, udostępnić go jako layer i zapominamy o każdorazowym dołączaniu do funkcji Lambda wszelkich zależności. Jak to zrobić? Załóżmy, że chcemy skorzystać z naszych Lambdach z pakietu Requests.
- Robimy sobie katalog python
mkdir python
- Wchodzimy do niego i tworzymy sobie virtualenv
cd python
python3 -m venv lambda_layer_environment
source lambda_layer_environment/bin/activate
- Instalujemy nasze requests
pip install requests
- Teraz musimy doinstalować wszystkie pakietu, od których jest zależny requests. Najpierw do pliku requirements.txt zapisujemy wszystkie zależności, a potem doinstalowujemy je.
pip freeze > requirements.txt
pip install -r requirements.txt -t .
- Pozostaje zdezaktywować virtualenv oraz go usunąć.
deactivate
rm -r lambda_layer_environment
W naszym katalogu python powinniśmy mieć teraz wszystkie niezbędne pliki

Pozostaje spakować cały katalog do pliku zip i utworzyć na z jego pomocą nowy Layer.
Po jego dodaniu do funkcji Lambda mogę bez problemu korzystać z modułu Requests, bez konieczności jego dodawania do pakietu.
def lambda_handler(event, context):
req = requests.get('https://chmurowisko.pl')
print(req.text[0:100])
if (req.status_code == 200):
return 'Success'
else:
return 'Error'

Jak to działa
Dokumentacja AWS Lambda Layers mówi, że nasze pakiety trafiają do katalogi /opt. I rzeczywiście. Uruchomiłem w funkcji Lambda poniższy kod:
def lambda_handler2(event, context):
modules = os.popen("find /* -type d | grep '/opt/'").read().split("\n")
return {
'modules': modules
}
a w wynikach pokazały się między innymi nasze moduły

Podsumowanie
Ja jestem bardzo zadowolony z wprowadzenia Layers. Ułatwi to kodowanie i deployment. Łatwiej będzie programując pozostać w zgodzie z DRY (Don’t Repeat Yourself).
Już powstają pierwsze Layers jako Open Source, a pewnie niebawem pojawi się tego jeszcze więcej.
Pamiętajcie też, że korzystając z resource based policies możecie udostępniać Wasze Layers innym.