Skip to content

Serverless Framework で Go を カスタムランタイム, arm64 環境にデプロイする

Posted on:August 24, 2023 at 12:00 AM

Table of contents

Open Table of contents

TL;DR

arm64 アーキテクチャを利用すればアプリケーションのコストパフォーマンスが上がることが期待できます。 しかし、AWS から提供されている Go のランタイム go1.x は arm64 環境に対応していません。 そこで、この記事では Go で書いた AWS Lambda function を Amazon Linux 2, arm64 環境にデプロイするにはどうすれば良いのかを紹介します。

2023-08-27 追記: AWS Lambda での Go 1.x ランタイムのサポート終了が発表されたので、カスタムランタイムへの移行が必要になりましたね。この記事は実質カスタムランタイムへの移行方法となっているのでもしかしたら参考になるかもしれません。

この記事の背景

最近ではコストパフォーマンスを考えて、クラウドリソースのアーキテクチャを arm64 環境に移行することが増えてきました。

自分はよく、Serverless framework を利用して、AWS Lambda 上に Go で書いた API をデプロイしていたのですが、利用していた go1.x ランタイムは x86_64 しか対応していません。

別言語 (Python や Node.js) であれば、アーキテクチャを変更するだけで良かったのですが、Go はそうはいきませんでした。 しかし、Go はシングルバイナリを生成することができるので、Lambda のカスタムランタイムで実行することができるはずだと思いました。

そこで調べたり、試したりした結果、Lambda のカスタムランタイムで実行することができたので、その方法を紹介します。

実際 arm64 は安いのか

こちらを御覧ください。塵も積もれば山となるってやつですね。

料金 - AWS Lambda | AWS

Lambda のカスタムランタイムとは

利用目的でいうと、Lambda のカスタムランタイムは、Lambda がサポートしていない言語で書かれたコードを実行するために利用するランタイムです。

OS の選択肢には、Amazon Linux, Amazon Linux 2 があります。 このうち、Amazon Linux 2 が arm64 環境に対応していますので、今回はこちらを利用します。

参考: カスタム Lambda ランタイム - AWS Lambda

カスタムランタイムの使用

Lambad のカスタムランタイムドキュメントには、以下のように書かれています。

カスタムランタイムを使用するには、関数のランタイムを provided.al2 に設定します。ランタイムは、関数のデプロイパッケージ、またはレイヤーに含めることができます。

bootstrap という名前のファイルがデプロイパッケージにある場合、Lambda はそのファイルを実行します。そのファイルがない場合、Lambda は関数のレイヤーにランタイムがないかどうかを確認します。ブートストラップファイルが見つからないか、実行可能でない場合、関数は呼び出し時にエラーを返します。

つまり、以下 2 つを満たせば Go の関数を arm64 環境にデプロイできそうです。

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

Serverless Framework で al2 arm64 を設定する

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

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

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

参考: general-function-settings

Package 指定を変更する

package 設定のセクションで artifact を指定するとパッケージング動作を上書きすることが可能です。 ここに、bootstrap という名前のファイルを含んだ function.zip を指定します。

参考: package

functions の下に書くと、その関数のみに設定を適用することができます。今回は functions 下に設定を書いてみます。

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 2, arm64 環境にデプロイする方法を紹介しました。

ちょっと前に、フレームワークの公式ドキュメントを読むのが成長にスキルアップにつながる的な投稿を見たのですが、今回のはまさしく公式ドキュメントを読んで身につけた知見です。 また、実際には何回か試行錯誤したので、その過程もスキルアップに重要な要素なんだろうなと実感しました。

TODO: サンプルリポジトリを作ってリンクを貼る