AWS Lambda Web Adapter を使ってみよう
きっかけ
最近ずっと React フロントエンド開発をしていますが、ふとバックエンドで何か作ってみたいなぁと思い、久々にGo言語とGinを使ってみんな大好きな Lambda でも作ってみようと思い立ちました。
LambdaでGinを動かすとなるとアダプターが必要ですが、アダプターの仕様を確認しようと調べ始めたところでAWS Lambda Web Adapterを見つけたので試してみました。
AWS Lambda Web Adapter とは
一言で言うと、WebアプリケーションをそのままLambda上で動かせるよ!というアダプターです。
詳しい説明は公式の方がわかりやすいので省きますが、AWSが提供するDockerイメージ、もしくは、Lambdaレイヤーを導入することで、アプリ内にLambdaのアダプターを導入せずにそのままLambda化することが可能です。
仕組みとしては、提供されるLambdaレイヤーまたはDockerイメージ内に Lambda と Webアプリケーションの仲立ちをするプログラムが入っており、その分レイテンシは僅かに劣りますがリクエスト・レスポンスを良しなに処理してくれるようです。
今回はGin(Go言語)を利用した例をご紹介しますが、多くの言語やフレームワークにおける利用例が公開されており、Dockerイメージ、Zipの双方でLambdaをビルド、デプロイする方法を見ることができます。
導入
SAMを利用する例は前述の 公式サンプル をご覧ください。(Go+Ginに限らず、様々な言語、フレームワークに対応するサンプルが公開されています)
DWS では Serverless Framework を利用するプロジェクトが多いので Serverless Framework での利用例となります。
Ginはmain()から Run()
で起動します。aws-lambda-go-api-proxy は使用しません。
公式サンプルと同様 al2 で、せっかくなので ARM 版を試します。
.PHONY: build clean deploy gomodgen
build:
export GO111MODULE=on
go mod tidy
env GOARCH=arm64 GOOS=linux go build -trimpath -ldflags="-s -w" -o ./build/bootstrap ./demo/main.go
zip -jm ./build/artifact.zip ./build/bootstrap
clean:
rm -rf ./bin ./vendor go.sum
deploy: clean build
AWS_SDK_LOAD_CONFIG=1 sls deploy --verbose --aws-profile XXXXXXX
package main
import (
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
r.GET("/demo", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "Hello World!",
})
})
r.Run()
}
service: handson
frameworkVersion: '3'
provider:
name: aws
architecture: arm64
runtime: provided.al2
region: ap-northeast-1
environment:
GIN_MODE: release
AWS_LAMBDA_EXEC_WRAPPER: /opt/bootstrap # 👈ココの追加が必要
package:
artifact: ./build/artifact.zip
functions:
demo:
handler: bootstrap
layers:
- arn:aws:lambda:${aws:region}:753240598075:layer:LambdaAdapterLayerArm64:16 # 👈ココの追加も必要
events:
- httpApi:
path: /demo
method: get
まとめ
環境変数と Lambda レイヤーだけで簡単に導入することができました。
Lambda にする前提で作成していない Web アプリケーションをそのまま Lambda 化したくなった場合などに AWS Lambda Web Adapter を利用することでアプリに手を入れることなく簡単に対応することができます。
既存の Lambda からアダプターを外すことでアプリケーションの可搬性も良くなり、ECS化の必要が出た場合も同じアプリケーションをそのままデプロイ可能となります。
従来 Go を Lambda 上で動かしていたランタイム go1.x のベースになっている初代の Amazon Linux が 2023年12月31日で EOL を迎え非推奨となるため、移行と併せて変更するのも良いかもしれません。