Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
DynamoDBの"Replacement"時にデータが消されないようにCustom Reso...
Search
morimorikochan
October 31, 2024
Technology
1.5k
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
DynamoDBの"Replacement"時にデータが消されないようにCustom Resource Provider Frameworkでカスタムリソース作ってみた件
"クラスメソッドのCDK事情大公開スペシャル#1" の際に登壇した内容です
https://classmethod.connpass.com/event/332020/
morimorikochan
October 31, 2024
More Decks by morimorikochan
See All by morimorikochan
Claude Designがめちゃくちゃ便利なので使ってほしい
diggymo
1
450
実装だけじゃない! CCA-F取得エンジニアが教えるClaude Code開発プロセス活用術
diggymo
2
1.4k
Claude in Chromeで始める自律的フロントエンド開発
diggymo
1
1.2k
HonoとJSXを使って管理画面をサクッと型安全に作ろう
diggymo
0
580
バッチ処理で悩むバックエンドエンジニアに捧げるAWS Glue入門
diggymo
3
820
LIFF CLIとngrokを使ったLIFF/LINEミニアプリのお手軽実機確認
diggymo
0
1.2k
TypeScriptでモジュラーモノリスやってみた
diggymo
0
800
過去のインプットとアウトプットを振り返る
diggymo
0
540
Amazon BedrockとPR-Agentでコードレビュー自動化に挑戦・実際に運用してみた
diggymo
0
3.3k
Other Decks in Technology
See All in Technology
アクセラレーターで実現するServiceNow活用の高速化 / ServiceNow World Forum 2026
visional_engineering_and_design
0
130
生き様としてのSRE
hokkai7go
1
170
Patterns in AI Driven Software Development
akosma
PRO
0
480
Jev の中身は50行で再現できる。でも本物との差はどこにあるのか
hisuzuya
0
300
【dbts2026】AIエージェントの 判断と探索を変える、 データベース エンジニアリング― 既存DBの処理と依存関係から作る、オペレーショナルオントロジー ―
shisyu_gaku
0
100
Oracle Database Security 詳細解説
oracle4engineer
PRO
1
250
推論基盤と Scale-Up Interconnect の現状と制約から俯瞰する技術動向
markunet
2
800
AIエージェント時代、Kaggleにどう取り組むか
takanao
2
500
レガシーコードに対する loop engineering的なAI開発プロセス導入について
kubell_hr
0
190
SLOを阻む不安
sraku2159
0
220
現場を動かすAIエージェント#2_製造業現場でのAI活用から見た、ハマる罠と実践知
kintotechdev
2
140
これだけは抑えておきたい!後悔しない re:Invent の過ごし方 / AWS re:Invent 2026 prestudy
kinunori
2
700
Featured
See All Featured
世界の人気アプリ100個を分析して見えたペイウォール設計の心得
akihiro_kokubo
PRO
74
43k
Between Models and Reality
mayunak
4
550
Done Done
chrislema
187
17k
Building a Scalable Design System with Sketch
lauravandoore
464
34k
My Coaching Mixtape
mlcsv
0
380
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
46
3.1k
Being A Developer After 40
akosma
PRO
92
590k
Java REST API Framework Comparison - PWX 2021
mraible
34
9.8k
Automating Front-end Workflow
addyosmani
1370
210k
We Are The Robots
honzajavorek
0
430
Why Your Marketing Sucks and What You Can Do About It - Sophie Logan
marketingsoph
0
450
エンジニアに許された特別な時間の終わり
watany
109
250k
Transcript
DynamoDBの"Replacement"時にデータ が消されないように Custom Resource Provider Frameworkで カスタムリソース作ってみた件 クラスメソッド株式会社 リテールアプリ共創部 マッハチーム
morimorikochan
名前 morimorikochan 所属 クラスメソッド株式会社 リテールアプリ共創部 マッハチーム🚀 趣味 Switchのゲーム X @marooon88 ⼀⾔
中古7万の椅⼦でQoL爆上 ⾃⼰紹介
1. 結論 2. 問題提起 3. Custom Resources 4. Custom Resource
Provider Framework 5. 実装した 6. まとめ 内容
• CDKでDynamoDBのテーブル置換時、テーブルのデータが全件削除され て困っていた • CDKのcustomresources.Provider(通称Custom Resource Provider Framework)を使って新テーブルへのコピーを⾃動で⾏えるようにした • 処理時間も早く、CIへの影響も少ない
• 課題 ◦ Lambda関数のIAMロールがちょっとガバってしまう ◦ レースコンディション発⽣する 📚結論
DynamoDBのPrimaryKey/SortKeyこんな感じやろか とりあえず cdk deploy して開発開始や! ⸻⸻数⽇後⸻⸻ PrimaryKey/SortKey間違ってたわ、直して
cdk deploy っと... ほなさいなら...(データ全削除) うわあぁぁぁぁぁぁ動作確認⽤のデータが消えたあぁぁぁぁぁぁ 🤨こんなことないですか
🤨こんなことないですか
🤨こんなことないですか
📚こんなことないですか 🤔 CDKの⼒でなんとかならん?
📚こんなことないですか 💡 Custom Resource Provider Framework
カスタムリソースを使⽤すると、CloudFormation テンプレートにカスタムプロビジョニン グロジックを記述し、スタックを作成、更新 (カスタムリソースを変更した場合)、または削 除するたびに CloudFormation にそのロジックを実⾏させることができます。これは、プロ ビジョニング要件に、CloudFormation の組み込みリソースタイプでは表現できない複雑な ロジックやワークフローが含まれる場合に役⽴ちます。
カスタムリソースプロバイダーの定義⽅法 • SNS ◦ 1. メッセージが送られる ◦ 2. SNSのバックエンド側で受信し処理 ◦ 3. バックエンド側がS3にファイルをPUTし応答する • Lambda ◦ 1. Lambda関数が実⾏される ◦ 2. Lambda関数内で処理 ◦ 3. Lambda関数内でS3にファイルをPUTし応答する 🤔Custom Resourcesとは?
CDKでの定義⽅法は4種類 1. sns.Topic ◦ 前ページの処理を⾏うSNSを定義 2. lambda.Function ◦ 前ページの処理を⾏うLambdaを定義 3.
core.CustomResourceProvider ◦ 2を使いやすくした便利ラッパー(?) ◦ エラーハンドリングや応答をLambda関数の結果から⾃動で⾏ってくれる ◦ 15分のタイムアウト制限がある ◦ アプリケーション実装者には推奨されていない 4. customresources.Provider(Custom Resource Provider Framework) ◦ 3をさらに使いやすくした便利ラッパー(?) ◦ 別途“処理が終わったかどうかを判定する”ためのLambda関数 (isCompleteHandler)を定義可能なので、実質15分のタイムアウトがない >aws-cdk-lib module · AWS CDK 🤔CDKでどうやってCustom Resourcesを定義する?
🤔カスタムリソースプロバイダーにCRPFを使った場合 1. CloudFormation実⾏中にLambda関数が呼び出され、 同時にカスタムリソースが作成中/更新中/削除中になる 2. Lambda関数が応答する 3. カスタムリソースが完了状態になる ※isCompleteHandlerを利⽤しない場合
• DynamoDBがリソース置換されたことをカスタムリソースが検知し • Lambda関数を実⾏させる • Lambda関数内では以下の処理を⾏う ◦ 1. 旧テーブルからScanして全アイテムを取得 ◦
2. 新テーブルに全アイテムをBatchWriteItem この⽅法の他にも、AWSのAPI経由で旧テーブルからS3へコピーしそれを新 テーブルへコピーする⽅法もあったが⾒送り • 処理時間がかかる • DMSがややこしそう(DMSエアプ) 💡今回の課題へ適⽤すると...
const lambdaFunction = new nodejsLambda.NodejsFunction(/*略*/) lambdaFunction.addToRolePolicy( new iam.PolicyStatement({ effect: iam.Effect.ALLOW,
actions: ["dynamodb:Scan"], resources: ["*"], }) ); props.ddbTable.grantWriteData(lambdaFunction); const provider = new cr.Provider(this, "CustomResourceProvider", { onEventHandler: lambdaFunction, }); new cdk.CustomResource(this, "CustomResource", { serviceToken: provider.serviceToken, properties: { tableName: props.ddbTable.tableName, } as ResourceProperties, }); 利⽤イメージ(CDK側)
const lambdaFunction = new nodejsLambda.NodejsFunction(/*略*/) lambdaFunction.addToRolePolicy( new iam.PolicyStatement({ effect: iam.Effect.ALLOW,
actions: ["dynamodb:Scan"], resources: ["*"], }) ); props.ddbTable.grantWriteData(lambdaFunction); const provider = new cr.Provider(this, "CustomResourceProvider", { onEventHandler: lambdaFunction, }); new cdk.CustomResource(this, "CustomResource", { serviceToken: provider.serviceToken, properties: { tableName: props.ddbTable.tableName, } as ResourceProperties, }); 利⽤イメージ(CDK側) const originalTable = new dynamodb.Table(/* 略 */) new DynamoDbTableItemsRestorer(this,'OriginalTableItemsRestorer',{ ddbTable: originalTable }) 利⽤例
テーブルが置き換わる場合(=物理IDが変化した場合)のみ Lambdaを実⾏したい 🤔Lambda関数どう実装する? テーブルの変化 旧テーブルから新テーブルへ コピーさせるか テーブル作成時 ❌ テーブル更新時 (置換なし)
❌ テーブル更新時 (置換あり) テーブル削除時 ❌
/** Lambdaのエントリーポイント */ export const handler: CdkCustomResourceHandler<ResourceProperties> = async (event)
=> { logger.info("リソースが変化しました ", {event}); switch (event.RequestType) { case "Update": await copyAllItems({ fromTableName: event.OldResourceProperties.tableName, newTableName: event.ResourceProperties.tableName, }); return { PhysicalResourceId: event.ResourceProperties.tableName }; case "Create": case "Delete": return {}; } }; 利⽤イメージ(Lambda側)
/** Lambdaのエントリーポイント */ export const handler: CdkCustomResourceHandler<ResourceProperties> = async (event)
=> { logger.info("リソースが変化しました ", {event}); switch (event.RequestType) { case "Update": await copyAllItems({ fromTableName: event.OldResourceProperties.tableName, newTableName: event.ResourceProperties.tableName, }); return { PhysicalResourceId: event.ResourceProperties.tableName }; case "Create": case "Delete": return {}; } }; 利⽤イメージ(Lambda側) new cdk.CustomResource(this, "CustomResource", { serviceToken: provider.serviceToken, properties: { tableName: props.ddbTable.tableName, } as ResourceProperties, });
前回からPhysicalResourceId(物理ID)変化させた場合 • CloudFormationが”カスタムリソースが置換された”と認識する ◦ もしロールバックが発⽣した場合はCloudFormationがDeleteを実⾏する 前回から変化させなかった場合 • CloudFormationが”カスタムリソースが更新された”と認識する ◦ もしロールバックが発⽣した場合はCloudFormationが
パラメータを逆にしてUpdateを実⾏し、元の状態に戻そうとする 今回の要件では、ロールバック時に処理をさせる必要はないのでコードがシ ンプルになるよう”PhysicalResourceIdを変化させる” Update時に返却する物理IDについて
const copyAllItems = async (props: { fromTableName: string, newTableName: string,
} ) => { logger.info("データをコピーします ", {fromTableName: props.fromTableName, newTableName: props.newTableName}); const oldTableReadableStream = new DynamoDBReadableStream(ddbClient, props.fromTableName); const newTableWritableStream = new DynamoDBWritableStream(ddbClient, props.newTableName); await pipeline(oldTableReadableStream, newTableWritableStream) if (newTableWritableStream.errorChunks.length > 0) { logger.error("コピーに失敗したアイテムがあります ", {errorChunks: newTableWritableStream.errorChunks}) throw new Error(`${newTableWritableStream.errorChunks.length}件のデータをコピーでき ませんでした `) } } 利⽤イメージ(Lambda側)
💪実⾏してみた テーブルの置換
💪実⾏してみた カスタムリソース(Lambda) のポリシー変更
💪実⾏してみた カスタムリソースが実⾏されてる 物理IDが変化しているので、 カスタムリソースが置換されたと 認識されてる
💪実⾏してみた Lambda関数の処理時間 • Item数が少ない場合はだいたい10秒とか • これぐらいならCIへの影響が少ない Lambda関数のIAMロールがちょっとガバってしまう • CDK上で旧テーブル名を保持していないため •
SSM使えばできそうですけど 複雑にしたくない レースコンディション発⽣する(当然) • コピーの途中に旧テーブルにPutItemされると、そのデータは新テーブルにコピーされ ない可能性がある • 本番環境で利⽤する際は、メンテナンスモードなど検討必要 lambdaFunction.addToRolePolicy( new iam.PolicyStatement({ resources: ["*"], }) );
📚まとめ • CDKでDynamoDBのテーブル置換時、テーブルのデータが全件削除され て困っていた • CDKのcustomresources.Provider(通称Custom Resource Provider Framework)を使って新テーブルへのコピーを⾃動で⾏えるようにした •
処理時間も早く、CIへの影響も少ない • 課題 ◦ Lambda関数のIAMロールがちょっとガバってしまう ◦ レースコンディション発⽣する
📚資料 作成したコード • https://github.com/diggymo/ddb-table-item-restorer 参考資料 • aws-cdk-lib module · AWS
CDK ◦ https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib-readme.htm l#custom-resources • CDK で Custom resources を作成する|伊藤忠テクノソリューションズ ◦ https://www.ctc-g.co.jp/solutions/cloud/column/article/84.html
ありがとうございました 🫠おわり