『AWS CDK on Pulumi』でサーバーレス構成を作ってみて、AWS CDKのコードと比較してみる
この記事は 『AWS CDK Advent Calender 2024』 18日目の記事として書いています。
2024年12月2日に『AWS CDK on Pulumi』がGAしました。
今回は『AWS CDK on Pulumi』を利用して、API Gateway & Lambda の構成を実装し、使用感を確かめてみようと思います!
※本記事では、主にリソース定義のコードを紹介します。初期設定など含めて以下の記事が詳しいので、ご参照ください。
実装紹介
API GatewayとLambda構成を作成しました。
いきなりですが、今回の実装を紹介します。
{
"name": "pulumi-cdk-serverless",
"main": "index.ts",
"devDependencies": {
"@types/node": "^18",
"typescript": "^5.0.0",
"esbuild": "^0.24.0"
},
"dependencies": {
"@pulumi/aws": "^6.0.0",
"@pulumi/awsx": "^2.0.2",
"@pulumi/cdk": "^1.3.0",
"@pulumi/docker-build": "^0.0.8",
"@pulumi/pulumi": "^3.113.0",
"aws-cdk-lib": "^2.173.2",
"aws-lambda": "^1.0.7"
}
}
import * as pulumicdk from '@pulumi/cdk';
import { NodejsFunction } from 'aws-cdk-lib/aws-lambda-nodejs';
import { Runtime } from 'aws-cdk-lib/aws-lambda';
import * as apigateway from 'aws-cdk-lib/aws-apigateway';
import { RemovalPolicy } from 'aws-cdk-lib';
class ServerlessApiStack extends pulumicdk.Stack {
constructor(app: pulumicdk.App, id: string, options?: pulumicdk.StackOptions) {
super(app, id, options);
// Lambdaの定義
const lambda = new NodejsFunction(this, 'handler', {
entry: 'src/index.ts',
handler: 'handler',
runtime: Runtime.NODEJS_20_X,
});
// APIGatewayの定義
const restApi = new apigateway.RestApi(
this,
'PulumiCdkRestApi',
{
defaultCorsPreflightOptions: {
allowOrigins: apigateway.Cors.ALL_ORIGINS,
allowMethods: apigateway.Cors.ALL_METHODS,
allowHeaders: apigateway.Cors.DEFAULT_HEADERS,
},
cloudWatchRole: false, // errorが出るため、Role作成は除外しました
},
);
restApi.root
.addResource('sample')
.addMethod(
'GET',
new apigateway.LambdaIntegration(lambda, {
proxy: true,
}),
);
}
}
const app = new pulumicdk.App('app', (scope: pulumicdk.App) => {
const stack = new ServerlessApiStack(app, 'ServerlessApiStack', {});
});
AWS CDKに慣れている方は気付いたと思います。ほとんどAWS CDKでの書き方同じように書けます。
Pulumiのコード内部で、aws-cdk-lib
のConstructを使えるため、同じ書き方ができます。
AWS CDKの書き方と並べて、異なる点も紹介しようと思います。
まずはStackクラスです。
import * as pulumicdk from '@pulumi/cdk';
class ServerlessApiStack extends pulumicdk.Stack {
import {
Stack
} from 'aws-cdk-lib';
class ServerlessApiStack extends Stack {
次に、Appクラスです。
import * as pulumicdk from '@pulumi/cdk';
const app = new pulumicdk.App('app', (scope: pulumicdk.App) => {
const stack = new ServerlessApiStack(app, 'ServerlessApiStack', {});
});
import * as cdk from 'aws-cdk-lib';
import { ServerlessApiStack } from '../lib/hoge-stack';
const app = new cdk.App();
new ServerlessApiStack(app, 'ServerlessApiStack');
CDKではbin配下にapp定義用のファイルを配置しますが、Pulumiでは一緒になっているだけです。
どちらも@pulumi/cdk
を利用しているだけで、大きな差はありません。
動作検証
デプロイし、動作を確認します。
pulumi up # Pulumiのデプロイコマンド
デプロイ結果はCLIで確認できます。
さらに、PulumiCloudを利用することでブラウザ上でも確認することができます。
curlで対象のAPI Gatewayの動作を確認します。
curl https://sampleId.execute-api.ap-northeast-1.amazonaws.com/prod/sample
{"message":"Hello AWS CDK on Pulumi"}
無事動作確認ができました。
所感
AWS CDKの知識を活かして実装ができる点は良かったです。
PulumiはAWS以外のリソースも定義できます。
CloudFlareやAuth0といったサービスの定義・別クラウドサービスのリソース定義ができます。
AWS CDKしか触ったことのない人でも、Pulumiを使うことでAWSとAWS外のサービスのIaC構築にCDKの知識を活かせるのが良い点だと思います。
私は基本的にAWS環境で構築を行い、AWS外のサービスは手動で定義しています。AWS CDK on Pulumiを利用すれば学習コストを抑えて、全てIaCで定義することも出来そうです。
Pulumi特有のデプロイサイクルやコマンドを覚えるのは少し大変ですが、覚える価値はありそうです!
AWS CDKと同じ書き方が出来ることは分かったので、Pulumi側でどのようにAWS CDKのConstructを解釈しているのか、今後調べてみたいと思います!
Discussion