🍎

LambdaでGoランタイムが使えなくなるのでカスタムランタイムに移行する(Terraform)

2023/08/27に公開

背景

8月某日、AWSからメールが来ました。どうやらAWS LambdaのGoランタイムサポートが2023/12/31にサポート終了するらしいです。

Amazon Linux AMI のメンテナンスサポートが 2023 年 12 月 31 日に終了するのに合わせて、AWS Lambda での Go 1.x ランタイムのサポートを終了します [1]。

Lambda は、provided.al2 ランタイムを使用して Go プログラミング言語を引き続きサポートします。

provided.al2 ランタイムを使用すると、AWS Graviton2 プロセッサのサポートや、より小さなデプロイパッケージとより高速な関数呼び出しパスによる効率的な実装など、go1.x ランタイムに比べていくつかの利点があります。

詳細については、ブログ記事 [2] を参照してください。

Goのランタイムは Amazon Linuxに基づいています。Amazon Linuxのサポートが 2023/12/31に終了するに伴い、Goのランタイムもサポート終了となるようです。

Goのランタイムで動作しているLambda関数は、ランタイムをprovided.al2 (Amazon Linux 2ベースのカスタムランタイム)に移行する必要があります。

何故Amazon Linux 2でGoのランタイムをサポートしてくれなかったんだ。。。。

AWS公式からの見解としては以下です。

Go は、他のマネージドランタイムとは異なる方法で実装されています。Go はネイティブコードにコンパイルされるため、Lambda は Go をカスタムランタイムとして扱います。provided.al2 ランタイムを使用して Go 関数を Lambda にデプロイすることをお勧めします。

Go による Lambda 関数の構築 - AWS Lambda

つまり、「コンパイル後はネイティブコードになるんだからわざわざGoのランタイムとして用意する必要ないやろ」と言うことです。

私が実装したLambdaもGoで動いているものがあるので、カスタムランタイムに変更する必要があります。

また、LambdaをTerraformで管理しているのでTerraformで変更する方法をまとめていきます。

前提

Lambda関数をTerraformで構築するためのディレクトリ構成は以下のようになっています

. 
├── lambda
│   ├── archive // 圧縮後のファイルを保存するディレクトリ
│   ├── build   // バイナリを保存するディレクトリ
│   └── cmd     // goのワーキングディレクトリ
│       ├── go.mod
│       ├── go.sum
│       └── main.go
└── main.tf

変更してみる

aws_lambda_functionのruntime

ランタイムをgo1.xからprovided.al2に変更します。

前述の通り、コンパイル後はネイティブコードになるため、ランタイムはAmazon Linux 2を指定します。

resource "aws_lambda_function" "lambda" {
  function_name    = "go-lambda-sample"
  filename         = "./lambda/archive/sample.zip"
  role             = aws_iam_role.lambda_role.arn
  handler          = "sample"
-  runtime          = "go1.x"         // 変更前
+  runtime          = "provided.al2"  // 変更後
  source_code_hash = data.archive_file.lambda.output_base64sha256
}

ビルド後のファイル名

現状のビルド周りのコードは以下のようになっています。

おそらく、TerraformでGoのLambdaを構築する際の一般的な方法だと思います。

resource "null_resource" "default" {
  triggers = {
    always_run = timestamp()
  }
  provisioner "local-exec" {
    command = "cd ./lambda/cmd/ && GOOS=linux GOARCH=amd64 go build -o ../build/main main.go"
  }
}

data "archive_file" "lambda" {
  type        = "zip"
  source_file = "./lambda/build/main"
  output_path = "./lambda/archive/sample.zip"

  depends_on = [null_resource.default]
}

今回は、go buildの部分を変更します。また、変更後に圧縮するため、圧縮元ファイルも変更します。

カスタムランタイムでは、実行ファイル名はbootstrapである必要があります。なので、go buildは以下のようになります。

cd ./lambda/cmd/ && GOOS=linux GOARCH=amd64 go build -o ../build/main main.go
↓
cd ./lambda/cmd/ && GOOS=linux GOARCH=amd64 go build -o ../build/bootstrap main.go

圧縮元ファイルもbootstrapに変更します。

data "archive_file" "lambda" {
  type        = "zip"
-  source_file = "./lambda/build/main"
+  source_file = "./lambda/build/bootstrap"
  output_path = "./lambda/archive/sample.zip"

  depends_on = [null_resource.default]
}

確認

実際にコンソールから確認してみます!

ランタイムがAmazon Linux 2のカスタムランタイムになっていることが確認できます!

テストでお試し実行してみても問題なく動作することが確認できます!

意外と簡単にGoランタイムからカスタムランタイムに移行できることがわかりました。

急いで移行する必要はないですが、簡単に移行できるので早めに移行することをお勧めします!

GitHub

サンプルコードはこちらに公開しています!
https://github.com/k0825/go-lambda-al2-sample

GitHubで編集を提案

Discussion