はじめに
AWS CDK(Cloud Development Kit)は、クラウドリソースをコードで定義し、デプロイするためのオープンソースのソフトウェア開発フレームワークです。この記事では、AWS CDK for Goを使用してGo言語で書かれたLambda関数を定期的に実行するスケジュールを設定する方法を説明します。
前提条件
- AWSアカウントがすでに設定されていること。
- AWS CDKを操作するCLIがインストールされていること。
CDKのCLIのインストールについてはこちらをご覧ください
環境
- Go 1.20
プロジェクトの初期化
新しいディレクトリを作成し、その中に移動します。
mkdir go-lambda-cdk
cd go-lambda-cdk
以下のコマンドを実行して新しいCDKプロジェクトを初期化します。
cdk init app --language=go
初期化すると次のようなファイルが生成されます。
.
├── README.md
├── cdk.json
├── go-lambda-cdk.go
├── go-lambda-cdk_test.go
├── go.mod
└── go.sum
次に必要なAWS CDKライブラリをインポートします。
go mod tidy
Lambda関数の作成
Go言語でLambda関数を書きます。詳しくはこちらをご覧ください。
ファイルを作成します。
mkdir handler
touch handler/main.go
handler/main.go
を以下のように編集しました。
package main
import (
"context"
"github.com/aws/aws-lambda-go/lambda"
)
func HandleRequest(ctx context.Context) (*string, error) {
message := "Hello World!"
return &message, nil
}
func main() {
lambda.Start(HandleRequest)
}
呼び出されるとHello World
を出力する単純な関数です。
CDKでLambdaリソースの定義
go-lambda-cdk.go
を編集します。
package main
import (
"os"
"os/exec"
"github.com/aws/aws-cdk-go/awscdk"
"github.com/aws/aws-cdk-go/awscdk/awslambda"
"github.com/aws/constructs-go/constructs/v3"
"github.com/aws/jsii-runtime-go"
"github.com/joho/godotenv"
)
type GoLambdaCdkStackProps struct {
awscdk.StackProps
}
func NewGoLambdaCdkStack(scope constructs.Construct, id string, props *GoLambdaCdkStackProps) (awscdk.Stack, error) {
var sprops awscdk.StackProps
if props != nil {
sprops = props.StackProps
}
stack := awscdk.NewStack(scope, &id, &sprops)
// Goのビルド
buildCmd := exec.Command("go", "build", "-tags", " lambda.norpc", "-o", "bin/bootstrap", "handler/main.go")
buildCmd.Env = append(os.Environ(), "GOOS=linux", "GOARCH=amd64")
if err := buildCmd.Run(); err != nil {
return nil, err
}
// Lambda関数の定義
awslambda.NewFunction(stack, jsii.String("golang-lambda"), &awslambda.FunctionProps{
FunctionName: jsii.String("golang-lambda-function"),
Runtime: awslambda.Runtime_PROVIDED_AL2(),
Code: awslambda.Code_FromAsset(jsii.String("bin"), nil),
Handler: jsii.String("main"),
})
return stack, nil
}
func main() {
defer jsii.Close()
// envファイルの読み込み
if err := godotenv.Load(); err != nil {
panic(err)
}
app := awscdk.NewApp(nil)
_, err := NewGoLambdaCdkStack(app, "GoLambdaCdkStack", &GoLambdaCdkStackProps{
awscdk.StackProps{
Env: env(),
},
})
if err != nil {
panic(err)
}
app.Synth(nil)
}
func env() *awscdk.Environment {
return &awscdk.Environment{
Account: jsii.String(os.Getenv("AWS_ACCOUNT")),
Region: jsii.String(os.Getenv("AWS_REGION")),
}
}
ランタイムにはprovided.al2
を指定しています。また、実行ファイルには bootstrap
という名前をつける必要があるため、ビルド時に指定しています。詳しくはこちらをご覧ください。
環境変数からaccount_idとregionを指定しています。
デプロイ
以下のコマンドでデプロイされます。
cdk deploy
AWSの画面からデプロイされているのが確認できると思います。
定期実行のスケジュール設定
次に定期実行のスケジュール設定します。
func NewGoLambdaCdkStack(scope constructs.Construct, id string, props *GoLambdaCdkStackProps) (awscdk.Stack, error) {
var sprops awscdk.StackProps
if props != nil {
sprops = props.StackProps
}
stack := awscdk.NewStack(scope, &id, &sprops)
// Goのビルド
buildCmd := exec.Command("go", "build", "-tags", " lambda.norpc", "-o", "bin/bootstrap", "handler/main.go")
buildCmd.Env = append(os.Environ(), "GOOS=linux", "GOARCH=amd64")
if err := buildCmd.Run(); err != nil {
return nil, err
}
// Lambda関数の定義
lambdaFunc := awslambda.NewFunction(stack, jsii.String("golang-lambda"), &awslambda.FunctionProps{
FunctionName: jsii.String("golang-lambda-function"),
Runtime: awslambda.Runtime_PROVIDED_AL2(),
Code: awslambda.Code_FromAsset(jsii.String("bin"), nil),
Handler: jsii.String("main"),
})
// 定期実行の設定
rule := awsevents.NewRule(stack, jsii.String("lambda-batch-rule"), &awsevents.RuleProps{
Schedule: awsevents.Schedule_Cron(&awsevents.CronOptions{
Minute: jsii.String("*/5"),
}),
})
rule.AddTarget(awseventstargets.NewLambdaFunction(lambdaFunc, nil))
return stack, nil
}
NewGoLambdaCdkStack
の中身を編集しました。定期実行のスケジュールは、CloudWatch Eventsのルールを使用しており、5分に一度Lambda関数が実行されます。
再デプロイ
再びデプロイします。
cdk deploy
指定したスケジュールでLambda関数が実行されるようになります。
参考