Veltioblog

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 | AWS

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 環境にデプロイできそうです。

ではやっていきましょう 👀

Serverless Framework で al2023 arm64 を設定する

以下のように設定します。

provider:
  name: aws
  runtime: provided.al2023
  architecture: arm64

見てわかる通り、公式ドキュメントの識別子と同じなのでそのまんまの設定やなといった感じですね。これで 1 つ目の条件は満たせました。

参考: general-function-settings

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: サンプルリポジトリを作ってリンクを貼る