AWS Lambda – Golang – Custom Runtime
Natywny runtime funkcji Lambda dla języka GO oparty jest o Amazon Linux 1, który „chyli się ku upadkowi„. ;-). Pociąga to za sobą między innymi brak możliwości korzystania z Lambda Extensions oraz uruchamianie kodu tylko w środowisku x86_64. Możemy zapomnieć o arm64, czyli procesorach Graviton. W przypadku innych języków większość natywnych środowisk uruchomieniowych została zmigrowana do Amazon Lunux 2, w przypadku Go jednak tak nie jest.
Jak, w łatwy sposób wykorzystać custom runtime dla funkcji Lambda napisanej w języku Go? Pokażę to w tym artykule.
Na początek
Tworzymy funkcję Lambda
Wykorzystamy tym razem Serverless Application Model. Uruchamiamy polecenie
sam init --runtime go1.x --name aws-lambda-go-runtime
wybieramy AWS Quick Start Templates oraz Hello World Example
i po chwili powinniśmy mieć utworzony template dla naszego projektu. Będzie w nim między innymi funkcja Lambda i API Gateway.
Resources: HelloWorldFunction: Type: AWS::Serverless::Function Properties: CodeUri: hello-world/ Handler: hello-world Runtime: provided.al2 Architectures: - x86_64 Events: CatchAll: Type: Api Properties: Path: /hello Method: GET
Teraz możemy skompilować funkcję. W katalogu ze źródłami wykonujemy polecenie GOOS=linux GOARCH=amd64 go build -o hello-world main.go
Jeżeli mamy Dockera możemy lokalnie przetestować aplikację. Uruchamiamy nasze API za pomocą polecenia sam local start-api
i powinniśmy móc się do niego połączyć curl http://localhost:3000/hello
Jeżeli wszystko zadziałało zrobimy teraz
Deployment do AWS
Jeżeli nie macie bucketa S3 przeznaczonego do tego celu, tworzymy go za pomocą polecenia aws s3 mb s3://lambda-runtime-deployments --region eu-central-1
Teraz możemy już spakować nasz kod za pomocą polecenia
sam package --template-file template.yaml --s3-bucket lambda-runtime-deployments --output-template-file packaged.yaml
i zdeployować go na naszym koncie AWS
sam deploy --template-file packaged.yaml --capabilities CAPABILITY_IAM --stack-name lambda-go-runtime --region eu-central-1
Po chwili powinniśmy dostać między innymi adres naszego endpointa APIGateway
Spróbujmy więc go wywołać
Jak widać, wszystko zadziałało, spróbujmy więc wykorzystać
Lambda Custom Runtime
Na początek możemy spróbować ustawić ręcznie runtime na custom. W konsoli przestawiamy
na
Po wywołaniu funkcji dostaniemy jednak błąd mówiący o tym, że Lambda nie była w stanie znaleźć bootstrapa.
Bootstrap
Wykorzystanie customowego runtime pociąga za sobą konieczność podania do usługi logiki koniecznej do wywołania Lambdy. Logika ta musi być zawarta w pakiecie kodu wykonywalnego o nazwie bootstrap.
Na początek zmiany konfigurację środowiska uruchomieniowego w pliku template.yaml
HelloWorldFunction: Type: AWS::Serverless::Function Properties: CodeUri: hello-world/ Handler: hello-world Runtime: provided.al2 Architectures: - x86_64 Events: CatchAll: Type: Api Properties: Path: /hello Method: GET
I skompilujmy jeszcze raz kod naszej funkcji zapisując wynik kompilacji w bliku o nazwie bootstrap
GOOS=linux GOARCH=amd64 go build -o bootstrap ./...
Ponownie pakujemy i deployujemy funkcję
sam package --template-file template.yaml --s3-bucket lambda-runtime-deployments --output-template-file packaged.yaml sam deploy --template-file packaged.yaml --capabilities CAPABILITY_IAM --stack-name lambda-go-runtime --region eu-central-1
Teraz runtime funkcji Lambda powinien być już ustawiony na custom
Robimy request do naszej funkcji poprzez APIGateway
Arm64
Kompilacja dla architektury Arm64 wymaga ponownie tylko zmiany w w pliku template.yaml
HelloWorldFunction: Type: AWS::Serverless::Function Properties: CodeUri: hello-world/ Handler: hello-world Runtime: provided.al2 Architectures: - arm64 Tracing: Active Events: CatchAll: Type: Api Properties: Path: /hello Method: GET
oraz ponownego przekompilowania kodu funkcji
GOOS=linux GOARCH=arm64 go build -o bootstrap ./...
Po ponownym deploymencie powinniśmy mieć poniższą konfigurację dla naszej Lambdy
a wszystko powinno ciągle poprawnie działać.