この記事について
AWS CDKv2でCRUD操作ができるAPIを作る
今回はGoを使う
プロジェクト初期化
CLIのインストール
CLI自体はnodeのものを使う(ので導入済みならスキップ)
npm install -g aws-cdk
cdk --version
バージョンが表示されればOK
CDK Toolkitのデプロイ
初回のみCDKを利用する際に必要となるファイル群のデプロイが必要
→これもやったことがあるならスキップ
cdk bootstrap aws://${ACCOUNT}/${REGION}
以下のように表示されればOK
✅ Environment aws://${ACCOUNT}/${REGION} bootstrapped.
※異なるアカウント、リージョンでCDKを利用する場合はまたこの作業が必要になる
プロジェクト初期化
適当なディレクトリで↓を実行
cdk init app --language go
モジュールのインストール
必要なモジュールをgo.mod
に書き込む
go.mod
module todoapp-go
go 1.16
require (
github.com/aws/aws-cdk-go/awscdk/v2 v2.34.2
github.com/aws/aws-cdk-go/awscdklambdagoalpha/v2 v2.34.2-alpha.0
github.com/aws/aws-lambda-go v1.34.0
github.com/aws/aws-sdk-go-v2 v1.16.7
github.com/aws/aws-sdk-go-v2/config v1.15.14
github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue v1.9.7
github.com/aws/aws-sdk-go-v2/service/dynamodb v1.15.9
github.com/aws/constructs-go/constructs/v10 v10.1.58
github.com/aws/jsii-runtime-go v1.63.0
github.com/google/uuid v1.3.0
)
書いたら↓を実行してgo.sum
が作成されたら完了
go mod tidy
実装
CDKのコードを書く
todoapp-go.go
package main
import (
"fmt"
"github.com/aws/aws-cdk-go/awscdk/v2"
"github.com/aws/aws-cdk-go/awscdk/v2/awsapigateway"
"github.com/aws/aws-cdk-go/awscdk/v2/awsdynamodb"
"github.com/aws/aws-cdk-go/awscdk/v2/awsiam"
"github.com/aws/aws-cdk-go/awscdk/v2/awslogs"
"github.com/aws/aws-cdk-go/awscdklambdagoalpha/v2"
"github.com/aws/constructs-go/constructs/v10"
"github.com/aws/jsii-runtime-go"
)
type TodoappGoStackProps struct {
awscdk.StackProps
}
func NewTodoappGoStack(scope constructs.Construct, id string, props *TodoappGoStackProps) awscdk.Stack {
var sprops awscdk.StackProps
if props != nil {
sprops = props.StackProps
}
stack := awscdk.NewStack(scope, &id, &sprops)
// DynamoDB
table := awsdynamodb.NewTable(stack, jsii.String("TodosTable"), &awsdynamodb.TableProps{
TableName: jsii.String("todoapp-go-todos-table"),
PartitionKey: &awsdynamodb.Attribute{
Name: jsii.String("id"),
Type: awsdynamodb.AttributeType_STRING,
},
RemovalPolicy: awscdk.RemovalPolicy_DESTROY,
})
// Lambda関数
function := awscdklambdagoalpha.NewGoFunction(stack, jsii.String("TodoFunction"), &awscdklambdagoalpha.GoFunctionProps{
FunctionName: jsii.String("todoapp-go-function"),
Entry: jsii.String("src"),
Environment: &map[string]*string{
"TODOS_TABLE_NAME": table.TableName(),
},
})
// LambdaにDynamoDBのCRUD操作権限を付与
function.AddToRolePolicy(awsiam.NewPolicyStatement(&awsiam.PolicyStatementProps{
Effect: awsiam.Effect_ALLOW,
Actions: jsii.Strings(
"dynamodb:Scan",
"dynamodb:PutItem",
"dynamodb:UpdateItem",
"dynamodb:DeleteItem"),
Resources: jsii.Strings(*table.TableArn()),
}))
// LogGroup
awslogs.NewLogGroup(stack, jsii.String("TodoFunctionLogs"), &awslogs.LogGroupProps{
LogGroupName: jsii.String(fmt.Sprintf("/aws/lambda/%s", *function.FunctionName())),
RemovalPolicy: awscdk.RemovalPolicy_DESTROY,
})
// API Gateway
restapi := awsapigateway.NewRestApi(stack, jsii.String("TodoApi"), &awsapigateway.RestApiProps{
RestApiName: jsii.String("todoapp-go-api"),
DefaultCorsPreflightOptions: &awsapigateway.CorsOptions{
AllowOrigins: awsapigateway.Cors_ALL_ORIGINS(),
AllowMethods: awsapigateway.Cors_ALL_METHODS(),
AllowHeaders: awsapigateway.Cors_DEFAULT_HEADERS(),
StatusCode: jsii.Number(200),
},
})
todosResource := restapi.
Root().
AddResource(jsii.String("todos"), nil)
todosResource.AddMethod(jsii.String("GET"), awsapigateway.NewLambdaIntegration(function, nil), nil)
todosResource.AddMethod(jsii.String("POST"), awsapigateway.NewLambdaIntegration(function, nil), nil)
todoIdResource := todosResource.AddResource(jsii.String("{id}"), nil)
todoIdResource.AddMethod(jsii.String("PUT"), awsapigateway.NewLambdaIntegration(function, nil), nil)
todoIdResource.AddMethod(jsii.String("DELETE"), awsapigateway.NewLambdaIntegration(function, nil), nil)
return stack
}
func main() {
app := awscdk.NewApp(nil)
NewTodoappGoStack(app, "TodoappGoStack", &TodoappGoStackProps{
awscdk.StackProps{
Env: env(),
},
})
app.Synth(nil)
}
func env() *awscdk.Environment {
return nil
}
例によって例のごとく今回もLambdaはGo言語専用のモジュールawscdklambdagoalpha
を使っている
こちらについて少し補足↓
awscdklambdagoalphaについて
function := awscdklambdagoalpha.NewGoFunction(stack, jsii.String("TodoFunction"), &awscdklambdagoalpha.GoFunctionProps{
FunctionName: jsii.String("todoapp-go-function"),
Entry: jsii.String("src"),
Environment: &map[string]*string{
"TODOS_TABLE_NAME": table.TableName(),
},
})
EntryにLambdaのコードを置いてあるディレクトリを指定すればOK
また、エントリーポイントとなるファイルの名前はmain.goでなければならない点に注意
todoapp-go
├-go.mod
├-go.sum
├-todoapp-go.go
└-src
└-main.go ←Lambdaのエントリーポイント
Lambdaのコード実装
こちらのサンプルコードを参照
Goはほぼ使った経験がないのであまり参考にならないかもしれない(特にメソッドやパスに応じたルーティングとか)
デプロイ
↓を実行
cdk deploy TodoappGoStack
動作確認
↓を実行
export ENDPOINT="API Gatewayのエンドポイント"
bash tests/test.bash