/dev/null

脳みそのL1キャッシュ

Go 言語で書かれた Lambda 関数を Terraform で管理する

プロジェクト構造

成果物は https://github.com/d2verb/lambda-golang-terraform にあります。

$ tree .
.
├── golang
│   ├── artifacts
│   │   ├── sample.exe
│   │   └── sample.zip
│   └── src
│       ├── go.mod
│       ├── go.sum
│       └── main.go
├── lambda.tf
├── provider.tf
└── terraform.tfstate

Go 言語の場合は Python や Node.js などのスクリプト型言語と違って、実行バイナリをデプロイする必要があることに気をつけてください。

ビルド & アーカイブ

lambda.tf 内の以下の部分で実行ファイルのビルドとアーカイブを行っています。

resource "null_resource" "go_build" {
  triggers = {
    always_run = "${timestamp()}"
  }

  provisioner "local-exec" {
    command = "cd golang/src && GOOS=linux GOARCH=amd64 go build -o ../artifacts/sample.exe main.go"
  }
}

data "archive_file" "go" {
  depends_on  = [null_resource.go_build]
  type        = "zip"
  source_file = "golang/artifacts/sample.exe"
  output_path = "golang/artifacts/sample.zip"
}

気をつける点として、まず以下があります。null_resource は一度生成されるとその後変化しません。これでは Go 言語のソースファイルを変更しても反映されないので、以下で timestamp が変わるたびに null_resource を再生成するようにしています。

  triggers = {
    always_run = "${timestamp()}"
  }

次に、気をつける点として、以下があります。特に GOOS=linux GOARCH=amd64 の箇所です。Go 言語はコンパイル型言語で、実行バイナリを用意する必要があります。生成された実行バイナリが Lambda の実行環境とマッチしない場合、実行が失敗してしまいますので、実行バイナリの形式を指定する必要があります。

    command = "cd golang/src && GOOS=linux GOARCH=amd64 go build -o ../artifacts/sample.exe main.go"

デプロイ & 動作確認

まずは、terraform apply を実行してリソースを作成します。

$ terraform apply
...
Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes
...

後は、マネジメントコンソールでテキトーなテストを実行し、Hello World とログに出力されれば動作確認完了です。