AWS CDK on PulumiがGAしました!
はじめに
製造ビジネステクノロジー部の佐藤智樹です。
本記事はAWS CDK Advent Calendar 2024の6日目の記事です。
今回は2024年12月2日にGAしたAWS CDK on Pulumi(以降CDK on Pulumi)について紹介します。Pulumiについては詳しい知識がないため、CDKとの関係性を調査しながら情報を共有します。
発表記事
パブリックプレビュー発表時の記事
CDK on Pulumiとは
Pulumiは、Pulumi自体の記法でCDKのようにマルチクラウドのリソース構築やステート管理が可能なサービスです。これは元々CDKとは独立したものです。では、CDKはどの部分に関わるのでしょうか?GA前の記事を読むと、Pulumi上でCDKのConstructを使えます。
CDK on PulumiではCDKの記述方法やコンストラクトを使用しながら、CloudFormationを経由せずにリソースをデプロイできます。CDKは基本CloudFormationを実行することでしばしば実行時間の問題などに悩まされていました。これからは、CDKのオーケストレーションツールとしてPulumiも使えるようになります。裏側ではCloud Control APIを使うので以下のようなイメージになります。
ここでは百聞は一見にしかずなので、まずPulumi上でCDKを活用してみます。
やってみた
まずサンプルを真似てApp Runnerを動かしてみます。先にAWSのクレデンシャルを設定します。
現状、以下のissueを見たり実際に試したところMFAでの認証やAWS_SESSION_TOKENでの認証には対応していないようなので、純粋なIAMユーザを作成し、アクセスキーを発行します。(OIDC連携などは対応しているので本番ではそちらを使ってください)
発行したアクセスキーに以下の権限を付与します。CloudFormation経由でデプロイはしないのですが、App Runnerでcloudformation:CreateResource
の実行権限が必要だったので付与しています。なお、今回は検証目的のため強い権限を付けています。
- AWSAppRunnerFullAccess
- AWSCloudFormationFullAccess
- IAMFullAccess
上記の権限でアクセスキーの設定ができたら、次にローカル環境の設定に移ります。アクセスキーを以下のように設定します。
[cdk-on-pulumi-test]
aws_access_key_id = <ACCESS_KEY>
aws_secret_access_key = <SECRET_KEY>
設定後以下のドキュメントに従ってPulumiのTypeScriptアプリのベースラインを作成します。今回はパッケージ管理でnpmを選択します。
% brew install pulumi/tap/pulumi
% pulumi new aws-typescript -s <org名>/<project名>/dev #devはStack名
次にCDK on Pulumiを入れていきます。CDK on Pulumiは pulumicdk
のパッケージで提供されているので導入します。
# CDK on Pulumiの導入
% npm i @pulumi/cdk --save
# 今回使用するApp Runner用のライブラリ追加
% npm i @aws-cdk/aws-apprunner-alpha --save
% npm i @pulumi/docker-build --save
CDK on Pulumiは内部的にCloud Control API(以降CC API)を利用するため、Pulumiの設定もCC APIを使う前提で設定していきます。また通常のPulumi側でもリージョンとプロファイルを読ませるため環境変数を追加します。
% pulumi config set aws-native:region ap-northeast-1
% pulumi config set aws-native:profile cdk-on-pulumi-test # アクセスキーを登録したプロファイル
% export AWS_PROFILE=cdk-on-pulumi-test
% export REGION=ap-northeast-1
最後にPulumi上でApp RunnerのConstructを呼び出して実装してみます。GA記事のサンプルを真似てますが、いくつか実態と異なる部分があったのでこちら参考に設定してみてください。
import * as pulumi from '@pulumi/pulumi';
import * as pulumicdk from '@pulumi/cdk';
import { Service, Source } from '@aws-cdk/aws-apprunner-alpha';
class AppRunnerStack extends pulumicdk.Stack {
url: pulumi.Output<string>;
constructor(app: pulumicdk.App, id: string, options?: pulumicdk.StackOptions) {
super(app, id, options);
const service = new Service(this, 'service', {
source: Source.fromEcrPublic({
imageConfiguration: { port: 8000 },
imageIdentifier: 'public.ecr.aws/aws-containers/hello-app-runner:latest',
}),
});
this.url = this.asOutput(service.serviceUrl);
}
}
const app = new pulumicdk.App('app', (scope: pulumicdk.App): pulumicdk.AppOutputs => {
const stack = new AppRunnerStack(app, 'AppRunnerStack', {});
return {
url: stack.url,
};
});
export const url = app.outputs['url'];
上記のソースを読むと、pulumicdk
上のAppRunnerStack
内部でCDKの純粋なConstructを呼び出して使っています。では、呼び出したConstructがどのようにデプロイされるのか見ていきます。以下のコマンドでデプロイを実行します。
$ pulumi up
すると、CloudFormationのリソースを確認してもスタックの更新などは行われず、Pulumi上のコンソールを見るとデプロイが進んでいてステートもPulumi上で管理できるようになっていることがわかります。
実際にApp RunnerのURLにアクセスすると以下のようにちゃんとデプロイされていることが確認できます。
一部対応していないリソース(Lambda::Permissionなど)もCC APIを拡張することで使えるようです。詳細は、以下のリンクをご確認ください。
所感
CDK on Pulumiを使うと、既存のCDK Constructを使ってCloudFormationを経由せずに、AWSリソースを作成することができます。α版リソースなど既存のCDKの抽象化層を使いながらプログラムでIaCを書くことができるので、もしかしてこれが俺達が本当に欲しかったCDK for Terraformなのでは?という感じでした。Pulumiの利用はコスト感を考えないとなかなか難しいですが、CDKの開発体験でありながら裏側でCloud Control APIを使ってくれる体験はかなり良かったです。
CloudFormationの実行時間は改善されていますが、気になる方は是非試しに使ってみてください!