Serverless Framework で Go を カスタムランタイム, arm64 環境にデプロイする
Go で書いた AWS Lambda function を カスタムランタイム (Amazon Linux 2023), arm64 環境にデプロイする方法を紹介します。
Table of contents
TL;DR
arm64 アーキテクチャを利用すればアプリケーションのコストパフォーマンスが上がることが期待できます。
しかし、AWS から提供されている Go のランタイム go1.x
は arm64 環境に対応していません。
そこで、この記事では Go で書いた AWS Lambda function を Amazon Linux 2023, arm64 環境にデプロイするにはどうすれば良いのかを紹介します。
2023-08-27 UPDATE: AWS Lambda での Go 1.x ランタイムのサポート終了が発表されたので、カスタムランタイムへの移行が必要になりましたね。この記事は実質カスタムランタイムへの移行方法となっているのでもしかしたら参考になるかもしれません。
2023-11-13 UPDATE: AWS Lambda が Amazon Linux 2023 をサポートするようになりました。al2
と指定する箇所を al2023
に変更するだけです(記事中の表記も書き換えました)。
AWS Lambda adds support for Amazon Linux 2023
この記事の背景
最近ではコストパフォーマンスを考えて、クラウドリソースのアーキテクチャを arm64 環境に移行することが増えてきました。
自分はよく、Serverless framework を利用して、AWS Lambda 上に Go で書いた API をデプロイしていたのですが、利用していた go1.x
ランタイムは x86_64
しか対応していません。
別言語 (Python や Node.js) であれば、アーキテクチャを変更するだけで良かったのですが、Go はそうはいきませんでした。 しかし、Go はシングルバイナリを生成することができるので、Lambda のカスタムランタイムで実行することができるはずだと思いました。
そこで調べたり、試したりした結果、Lambda のカスタムランタイムで実行することができたので、その方法を紹介します。
実際 AWS Lambda の arm64 は安いのか
こちらを御覧ください。塵も積もれば山となるってやつですね。
AWS Lambda のカスタムランタイムとは
利用目的でいうと、Lambda のカスタムランタイムは、Lambda がサポートしていない言語で書かれたコードを実行するために利用するランタイムです。
OS の選択肢には、Amazon Linux, Amazon Linux 2, Amazon Linux 2023 があります。 このうち、Amazon Linux 2 & 2023 が arm64 環境に対応しています。今回は Amazon Linux 2023 を利用します。
参考:
カスタムランタイムの使用
Lambad のカスタムランタイムドキュメントには、以下のように書かれています。
カスタムランタイムを使用するには、関数のランタイムを provided.al2023 に設定します。ランタイムは、関数のデプロイパッケージ、またはレイヤーに含めることができます。
bootstrap という名前のファイルがデプロイパッケージにある場合、Lambda はそのファイルを実行します。そのファイルがない場合、Lambda は関数のレイヤーにランタイムがないかどうかを確認します。ブートストラップファイルが見つからないか、実行可能でない場合、関数は呼び出し時にエラーを返します。
つまり、以下 2 つを満たせば Go の関数を arm64 環境にデプロイできそうです。
- ✅ ランタイムを provided.al2023 に設定する (もちろん、アーキテクチャは arm64 に設定する)
- ✅ デプロイパッケージに bootstrap という名前のファイルを含める
ではやっていきましょう 👀
Serverless Framework で al2023 arm64 を設定する
以下のように設定します。
provider:
name: aws
runtime: provided.al2023
architecture: arm64
見てわかる通り、公式ドキュメントの識別子と同じなのでそのまんまの設定やなといった感じですね。これで 1 つ目の条件は満たせました。
Package 指定を変更する
package 設定のセクションで artifact
を指定するとパッケージング動作を上書きすることが可能です。
ここに、bootstrap という名前のファイルを含んだ function.zip を指定します。
参考: Serverless Framework - Packaging
functions の下に書く場合は、以下のように設定するとその関数のみに設定を適用することができます。
package:
individually: true
functions:
hello:
handler: bootstrap
package:
artifact: bin/function.zip
events:
- httpApi:
method: GET
path: /hello
ビルドスクリプトは適当に Makefile で書いています。
.PHONY: build
build:
GOOS=linux GOARCH=arm64 go build -o bin/bootstrap cmd/lambda/main.go
.PHONY: zip
zip: build
zip -j bin/function.zip bin/bootstrap
make zip
を実行すると、build と zip が実行されて、bin/function.zip
が生成されます。
これで 2 つ目の条件も満たせました 🎉
あとは、sls deploy でデプロイすれば、arm64 環境で動く Lambda function がデプロイされます!
おわりに
今回は、Go で書いた AWS Lambda function を Amazon Linux 2023, arm64 環境にデプロイする方法を紹介しました。
ちょっと前に、フレームワークの公式ドキュメントを読むのが成長にスキルアップにつながる的な投稿を見たのですが、今回のはまさしく公式ドキュメントを読んで身につけた知見です。 また、実際には何回か試行錯誤したので、その過程もスキルアップに重要な要素なんだろうなと実感しました。
TODO: サンプルリポジトリを作ってリンクを貼る