CDKでAwsCustomResourceを使っていて、わりとハマってしまったので、メモしておきます。
公式の説明は以下の通りです。
Defines a custom resource that is materialized using specific AWS API calls. These calls are created using a singleton Lambda function. class AwsCustomResource (construct)
要は、AWSのAPIを呼び出して、リソースを作成するためのカスタムリソースというこです。
わかりやすく言うとCloudFormationやCDKは出来上がったCloudFormationからリソースを作成するのに対して、AwsCustomResourceはAWSのAPIを直接呼び出してリソースを作成するということです。 このやり方は、AWSのAPIから直接リソースを作成するTerraformと一緒ですね。
CDKはAWS純正のサービスですので、ほとんどのリソースはCDKで作成できますし、constructsがない場合でも低レベルのCDKを使えばリソースを作成できます。 なので、基本はAwsCustomResourceを使うことはないと思いますし、できれば避けたいところです。
しかし、以下のような場合に使うことがあります。
既存のリソースを新たにCDKで管理する場合です。
例えば、最初はAWSコンソールからポチポチ作成していたリソースをCDKで管理したい場合です。cognito
とかそのケースがありありかもしれません。
新規でもリージョンも移行しないしAWSアカウントもそのままなら、わざわざ移行の手間をかける必要はないので既存のリソースをそのまま使うということもありますね。
こんな感じで書いちゃえば済む話なので。
// 既存のUserPoolを取得
const iUserPool: IUserPool = UserPool.fromUserPoolId(
this,
"UserPool",
"既存のUserPoolId",
);
this.userPool = iUserPool as UserPool;
これで既存のUserPoolをCDKで管理できるようになりますが、これでデプロイするとデフォルトのUserPoolの設定になってしまいます。
例えば、これに追加のlambdaトリガーを追加したい場合、純粋にCDKのclassを使用するとエラーになります。これはあくまでも新規のリソースを作成するためのもので、既存のリソースを管理するためのものではないからです。私もこのエラーに当たりました。もうリソースはあるよって感じのエラーを吐かれました(たしか…)。
そこで、この場合は既存のリソースを管理したあとに追加の設定をするにはAwsCustomResourceかlambdaでAWSのAPIを使うかのどっちかですね。
まぁ、AwsCustomResourceのほうが簡単なので、ここではAwsCustomResourceを使っていきます。
AwsCustomResourceはCDKではなくAWSのAPIを使うのでSDKを見て、そのまま追加する機能を書いてやればいいです。
例えば、以下のようにUserPoolの設定を変更する場合は以下のように書けます。例えば、管理者のみがユーザーを作成できるようにする場合です。
ServiceとActionはAWSのSDKを見て、それに合わせて書いていきます。あとはポリシーの設定と、physicalResourceId
を設定してやればOKです。
new AwsCustomResource(this, "UpdateUserPool", {
onUpdate: {
service: "CognitoIdentityServiceProvider", // 対象のサービス
action: "UpdateUserPoolCommand", // 対象のAPI
parameters: {
UserPoolId: "既存のUserPoolId",
DeletionProtection: "ACTIVE",
// 管理者のみがユーザーを作成できるようにする
AdminCreateUserConfig: {
AllowAdminCreateUserOnly: true,
},
},
physicalResourceId: PhysicalResourceId.of(Date.now().toString()),
},
policy: AwsCustomResourcePolicy.fromSdkCalls({
resources: AwsCustomResourcePolicy.ANY_RESOURCE,
}),
});
AwsCustomResourceはこのやり方をざっくり知っていれば、あとはAWSのSDKを見て、どのAPIを使うかを調べて、それに合わせて書いていけばSDKとか普段から書いている人であれば特に問題ないと思います。
ですが、気をつけて欲しいのがAwsCustomResourceを書いているときは、TypeScriptの型が効いてないということを忘れないでください。まぁ、コードみればわかるよと思うと思いますが、それでも気をつけてください。
私は思いっきりハマって数時間溶かしてしまいました。なんで、設定が反映されていないし、デプロイでもエラーがでないんだと思ったらparameters
の中のAdminCreateUserConfig
をadminCreateUserConfig
と書いていました。CDKのバグじゃないのかと思って、リポジトリを見ていてたら結局はタイプミスというオチ、、、
AwsCustomResourceはCDKの型の恩恵を受けられないので、なにかしらのミスをしてもエラーが出ないので、気をつけてください。