🔥

Serverless Framework で Go (provided.al2)

2023/10/10に公開

概要

Lambda による Go 専用ランタイム go1.x のサポートは 2023 年いっぱいで終了となっており、provided.al2 に移行する必要があります。

参考) https://aws.amazon.com/jp/blogs/compute/migrating-aws-lambda-functions-from-the-go1-x-runtime-to-the-custom-runtime-on-amazon-linux-2/

BEFORE (go1.x)

Serverless Framework で Go を使った Lambda を作成するための公式のテンプレートを使ってプロジェクトを作成するには、以下のコマンドを実行します。

serverless create --template aws-go
# または
serverless create --template aws-go-dep

このコマンドで作成されたテンプレートは以下のようになっています。make コマンドでソースコードからバイナリーをビルドし、make deploy (sls deploy) で zip 化してデプロイします。

serverless.yml (抜粋)

provider:
  name: aws
  runtime: go1.x

package:
  patterns:
    - '!./**'
    - ./bin/**

functions:
  hello:
    handler: bin/hello
  world:
    handler: bin/world

Makefile (抜粋)

build:
    env GOARCH=amd64 GOOS=linux go build -ldflags="-s -w" -o bin/hello hello/main.go
    env GOARCH=amd64 GOOS=linux go build -ldflags="-s -w" -o bin/world world/main.go

deploy: clean build
    sls deploy --verbose

この場合、複数の Lambda 関数に対して共通の zip パッケージがデプロイされ、各 Lambda 関数の Handler にそれぞれ異なる実行可能ファイルを指定することで処理を変えています。

AFTER (provided.al2)

provided.al2 ランタイムで実行するファイルは固定 (bootstrap) となっており、変更することはできません。そのため Lambda 関数ごとにパッケージを作成してあげる必要があります。

そのため、ビルドに Serverless Framework Go Plugin (serverless-go-plugin) を使用します。Makefile で実行していた Go のビルドコマンドは serverless.yml 内に設定として記述し、各 Lambda 関数の handler にはソースファイルを指定します。(複数のソースファイルで構成される場合はここにワイルドカードや複数指定します。)

serverless-go-plugin のインストール

npm install --save-dev serverless-go-plugin

serverless.yml

provider:
  name: aws
  runtime: provided.al2

plugins:
  - serverless-go-plugin

custom:
  go:
    cmd: GOARCH=amd64 GOOS=linux go build -ldflags="-s -w"
    supportedRuntimes: [ "provided.al2" ]
    buildProvidedRuntimeAsBootstrap: true

package:
  individually: true
  exclude:
    - "./**"

functions:
  hello:
    handler: hello/main.go
  world:
    handler: world/main.go

Makefile

build:
    sls package

deploy: clean build
    sls deploy --verbose

ARM プロセッサを使用する

provided.al2 ランタイムではコストパフォーマンスの良い ARM プロセッサを使用することもできます。ARM プロセッサを使用する場合は、GOARCH=arm64 を指定してビルドします。

serverless.yml

provider:
  name: aws
  architecture: arm64  # Lambda で ARM プロセッサを使用
  runtime: provided.al2

plugins:
  - serverless-go-plugin

custom:
  go:
    cmd: GOARCH=arm64 GOOS=linux go build -ldflags="-s -w"  # ARM プロセッサ用にビルド
    supportedRuntimes: [ "provided.al2" ]
    buildProvidedRuntimeAsBootstrap: true

参考

Discussion