ソースコードから理解する技術-UnderSourceCode

手を動かす(プログラムを組む)ことで技術を理解するブログ

aws cdk でGolangのLambdaをデプロイしてみる

前回に引き続き、aws cdkについてです。今回はGolangのLambda FunctionをAWS上にデプロイしてみました。
ソースは以下に上げてあります。
GitHub - SrcHndWng/cdk-lambda

プロジェクトはnpxを使って作成したので、プロジェクトの作成などは以前の下記記事を参照ください。
aws-cdkを触ってみた - ソースコードから理解する技術-UnderSourceCode

以下、ポイントについて説明していきます。

実装のポイント

フォルダ構成について

プロジェクト直下に「lambda」フォルダを作成し、その中にGolangのLambdaのソースを入れました。以下のようになります。(一部だけですが)

- lambda/ ・・・ 新規で作るフォルダ
  - bin/
     - main ・・・ main.goをビルドしたバイナリ。後述します。
  - main.go ・・・ Lambdaのソース
- lib/
  - cdk-lambda-stack.ts
- node_modules/
- README.md

Lambdaについて

先に書いたように、「lambda」フォルダを作成して、その中にGolangのLambdaを実装しました。ソースは以下のようになります。

lambda/main.go
package main

import (
	"context"
	"fmt"
	"time"

	"github.com/aws/aws-lambda-go/lambda"
)

const timeFormat = "2006-01-02 15:04:05"
const messageFormat = "Hello, now is %s!"

// MyEvent ...
type MyEvent struct {
	Name string `json:"name"`
}

// HandleRequest ...
func HandleRequest(ctx context.Context) (string, error) {
	t := time.Now()
	message := createMessage(t)
	return message, nil
}

func createMessage(t time.Time) string {
	return fmt.Sprintf(messageFormat, t.Format(timeFormat))
}

func main() {
	lambda.Start(HandleRequest)
}

単純に現在時刻と挨拶を返すだけの処理です。GolangのLambdaはバイナリでデプロイするため、「lambda」フォルダに移動して以下のコマンドでビルドします。

$ go build -o bin/main

ビルドすると「lambda/bin/main」が作成されます。が、後述するようにcdkのプロジェクトのビルド時に、このコマンドも実行してGolangのビルドもできるようにします。

cdk-lambda-stack.ts

cdkのメイン処理です。ソースは以下のようになります。

lib/cdk-lambda-stack.ts
import * as cdk from '@aws-cdk/core';
import * as lambda from '@aws-cdk/aws-lambda';

export class CdkLambdaStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // The code that defines your stack goes here
    new lambda.Function( this, 'GoFunction', {
      functionName: 'GoFunction',
      runtime: lambda.Runtime.GO_1_X,
      handler: 'main',
      code: lambda.Code.asset('./lambda/bin')
    })
  }
}

「new lambda.Function」がデプロイするLambdaの定義です。Lambda Function名、Runtimeを指定した後

  • handler ・・・ ビルドしたGolangのバイナリ名
  • code ・・・ lambda.Code.assetの引数として、ビルドしたGolangのバイナリ格納先フォルダパス

を指定しています。

package.json

cdkのビルド時にGolangもビルドできるよう、「npm run build」で実行するコマンドを修正します。

(中略)
  "scripts": {
    "build": "tsc; cd lambda; go build -o bin/main",
    "watch": "tsc -w",
    "test": "jest",
    "cdk": "cdk"
  },
(中略)

実行

Lambdaのデプロイをする際には、「bootstrap」も必要になるようです。ビルドも、以下のコマンドでデプロイします。

$ npm run build
$ npx cdk bootstrap
$ npx cdk deploy

削除について

「$ npx cdk destroy」でデプロイしたLambdaは削除されますが、「bootstrap」で作られたCloudFormationは残ってしまいます。このCloudFormationをマネージメントコンソールから削除しようとすると、S3の「cdktoolkit~」バケットが削除できない旨のエラーとなります。

対応としては、「cdktoolkit~」バケットの中身を手動で削除し、CloudFormationを削除することで完全に削除することが出来そうです。