

CDKロジカルIDの255文字制限、実は240文字+8桁ハッシュの内訳だった
この記事は、構成と文章の整理にAIを使っています。
あくまで読みやすくするための補助で、内容そのものをAIにすべて任せて書いているわけではありませんが、ところどころ相談しながら整えています。
結論
CDKが生成するロジカルIDは最大255文字で合ってるけど、内訳がある。
- 人間が読める部分(construct pathを連結したもの): 最大240文字
- 一意性確保用のハッシュ: 8文字固定
<human-readable-portion><8-character-hash> で合計255文字。ここを「255文字まで」としか覚えてないと、長いconstruct IDを付けたときにどこで削られるか分からなくなる。
あと、ロジカルIDの制約とS3バケット名・Lambda関数名みたいな物理名の制約は完全に別物。ここを一緒くたにすると勘違いする。
ロジカルIDの生成アルゴリズム
CDKの公式ドキュメントによると、生成手順はこう。
- construct treeのpath要素を連結する(スタック自身は除く)
- 読みやすくするためのヒューリスティックを適用する
- パス全体の8文字ハッシュを末尾に付けて一意性を確保する
flowchart TD
A[construct path\nStack1/DataBucket/Resource] --> B[パス連結\nスタック名は除外]
B --> C[ヒューリスティック適用\nDefault除去・Resource除去等]
C --> D[8文字ハッシュ付加]
D --> E[ロジカルID\nDataBucketXXXXXXXX]
ハッシュが必要な理由は、A/B/C と A/BC みたいに連結すると同じ文字列になるパスを区別するため。CloudFormationのロジカルIDは英数字のみでスラッシュが使えないから、単純連結だと衝突する。
スタック直下(パスが単一要素)のリソースは、名前が255文字以下ならハッシュなしでそのまま使われる。
ヒューリスティックの中身
人間可読部分を作る際、CDKは以下を適用する。
Defaultというpath要素は人間可読部分からもハッシュ計算からも完全に除去される- 既存constructを新しいconstructで包んで、内側のIDを
Defaultにすると元と同じロジカルIDになる。リファクタ時に既存リソースを置き換えずに済む仕組みはこれ
- 既存constructを新しいconstructで包んで、内側のIDを
Resourceというpath要素は人間可読部分からは隠されるが、ハッシュ計算には含まれる- L1 construct(CfnXxx)は慣習的に
ResourceというIDを使う
- L1 construct(CfnXxx)は慣習的に
- 連続する重複要素は片方が省略される
物理名の制約はロジカルIDとは別物
ここを混同しがちだけど、ロジカルID(CloudFormationテンプレート内の識別子)と物理名(実際にAWS上で使われる名前)は制約が別。
- S3バケット名: 3〜63文字、小文字・数字・ピリオド・ハイフンのみ
- Lambda関数名: 64文字
CDKが自動生成する物理名には、スタック名やハッシュが追加されることがあるので、bucketName や functionName を明示指定しない場合、想定より長くなって物理名の制約に引っかかることがある。特にネストスタック配下だと <root-stack-name>-XXXXXXXXXXXX-<construct-name> みたいな形式になりやすく、Lambda関数名の64文字制限に普通に当たる。
実務上の注意点
- construct IDは短く保つ。長いパスは読みやすさのためのヒューリスティックだけでは吸収しきれない
- 物理名を明示的に指定したいリソースは
bucketName/functionNameなどのプロパティで直接渡す - ロジカルIDを変えるとCloudFormationはリソースを作り直す(削除→作成)。既存リソースのIDは不用意に変更しない
- 既にロジカルIDが変わってしまったケースは
cdk refactorで旧IDと新IDのマッピングができる(実機で試してはいない)