🍡

Serverless FrameworkでGolangのAWS Lambda関数を作る

2022/03/25に公開

環境

$ sw_vers
ProductName:    macOS
ProductVersion: 11.6
BuildVersion:   20G165
$ go version
go version go1.18 darwin/arm64
$ serverless --version
Framework Core: 3.7.6
Plugin: 6.1.5
SDK: 4.3.2

Serverless Frameworkのインストール

npm install serverless

プロジェクトの作成

以下のコマンドでテンプレートを指定してプロジェクトを作成できる。

serverless create -u [テンプレート] -p [プロジェクト名]

今回はgolangのテンプレートを使用するため以下のようにする。プロジェクト名は任意のものを設定する。

serverless create -u https://github.com/serverless/serverless-golang/ -p [プロジェクト名]

プロジェクトのビルド

作成されたプロジェクトのディレクトリに移動してさっそくビルドする。

$ cd [プロジェクト名]
$ GOOS=linux go build -o bin/main
go: go.mod file not found in current directory or any parent directory; see 'go help modules'

go.mod file not found in current directoryというエラーが出たため、とりあえず以下を実行。

go env -w GO111MODULE=off

再度ビルドする。

$ GOOS=linux go build -o bin/main
main.go:4:2: cannot find package "github.com/aws/aws-lambda-go/lambda" in any of:

今度はlambdaのパッケージがないとのエラーを吐いたので以下を実行。

go get github.com/aws/aws-lambda-go/lambda

再度ビルドしたらエラーが出ずに完了。

$ GOOS=linux go build -o bin/main

プロジェクトのデプロイ

次にAWS Lambdaへのデプロイを試す。

IAMユーザーの作成

以下を参考にAWS側のセットアップをする。
https://www.serverless.com/framework/docs/providers/aws/guide/credentials

  1. Serverles Framework用のIAMユーザーを作成する(アクセスキーをメモしておく)
  2. 作成したIAMユーザーに適切なポリシーをアタッチする(AdministratorAccessをアタッチするか、権限を制限したければ独自にポリシーを作成してもよい)
  3. IAMユーザーのアクセスキーをローカルの環境変数に設定する
export AWS_ACCESS_KEY_ID=[AWS_ACCESS_KEY_ID]
export AWS_SECRET_ACCESS_KEY=[AWS_SECRET_ACCESS_KEY]

デプロイ

セットアップが完了したら以下のデプロイコマンドを実行する。
以下のコマンドの場合、リージョンはap-northeast-1になる。他のリージョンにデプロイしたければ変更する。

$ serverless deploy --region ap-northeast-1

※ちなみに、AWS側の設定をしていないと、以下のようにAWSのcredentialsがセットアップされてないといわれる。

Error:
AWS provider credentials not found. Learn how to set up AWS provider credentials in our docs here: <http://slss.io/aws-creds-setup>.

デプロイ(今回は2分かかった)が完了したら、AWS Lambdaのコンソールで該当のリージョンを確認すると、以下のようにFunctionが作成されている。

実行テスト

AWS Lambdaのコンソールからテストを実行して、正しくデプロイできているかを確認する。
コンソールからテストを実行したら以下のようなエラーを返した。

{
  "errorMessage": "fork/exec /var/task/bin/main: exec format error",
  "errorType": "PathError"
}

原因はMacOSでビルドしたものをそのままデプロイしたためで、go buildを実行する際に以下のようにCPUアーキテクチャを指定すればOKだった。

GOARCH=amd64 GOOS=linux go build -o bin/main

上記でビルドし、再度デプロイした上でテストを実行すると以下のように正常に動作することが確認できた。

{
  "message": "Go Serverless v1.0! Your function executed successfully!"
}

参考

Discussion