【AWS CDK × サーバレス構築】初学者が KMS と HostedZone で詰まった話
AWS CDK を使って サーバレスフルスタック(ECS Fargate / Aurora Serverless / ALB / CloudFront / Route53 / CodePipeline)を構築する作業で、私は初学者として多数の落とし穴にハマりました。
特に KMS × SSM × CDK カスタムリソース の関係の理解が浅く、これが複数の問題を引き起こしていました。
この記事では、私が実際に経験した問題のうち KMS と HostedZone(二重ゾーン) に絞ってまとめています。
諸先輩方には「初学者こんなに知識が浅い」という参考に使っていただければ幸いです。
CDK × KMS(特に CMK)の落とし穴
AWS には
- AWS 管理キー(aws/*)
- 手動で作成する CMK(Customer Managed Key)
がありますが、
CDK・SSM・CloudFormation・カスタムリソースが絡むと CMK が原因で失敗するケースが非常に多いそうです。
実際に私が詰まったのは次の 4 点でした。
## ① CDK ブートストラップと KMS の扱い
CDKToolkit の暗号化方式を根本的に誤解 → decrypt エラー連発
CDK を deploy するには cdk bootstrap が必要ですが、このとき作られる CDKToolkit バケットの暗号化キーについて私は完全に勘違いしていました。
- 自分で CMK を作成して割り当てる
- CDK が自動生成するキー
- AWS 管理キー(aws/s3)
このうち、どのキーがどの段階で必要とされるのか区別ができていませんでした。自動作成されるはずのキーが見当たらず、相談したに「KMS の S3 マネージドキー作成して良いですよ」と返ってきた言葉をCMK のことだと思い、そのまま突き進み、結果、本来不必要な CMKを作成してしまい、後続のデプロイで decrypt エラーが連発しました。
● 実際に起きた問題
- 不要な CMKを作成
- CloudFormation や CDK の実行ロールには CMK の decrypt 権限なし
- 結果としてすべてのデプロイが失敗
kms:Decrypt is not authorized
CDK の自動生成キーを使っていれば起きない問題でした。
✔ 今回学んだ結論
「CDK Toolkit バケットの暗号化に自前 CMK を使うと失敗しやすい」
「AWS 管理キー or CDK 自動生成キーを使うのが実務では常識」
自前 CMK だと失敗する理由
- CDK のデプロイロールに CMK decrypt 権限がない
- CloudFormation の実行ロールにも権限がない
- KeyPolicy に必要な IAM が登録されていない
- CDK の bootstrap 設計から逸脱している
→ どれか1つでも欠けると kms:Decrypt で落ちる
なぜ危険なのか?
① CloudFormation が decrypt できない
CDKToolkit バケットには
- zip
- アセット
- テンプレート
などが置かれます。
CloudFormation がこれを読む時に decrypt 権限が必要ですが、自前の CMK には CFn ロールが KeyPolicy に入っていないのが普通です。
→ Decrypt failed → デプロイ失敗
② CDK 公式も「CMK は使うな」と言っている
CDK ドキュメントには明記されています。
Bootstrap に追加の CMK を手動設定する必要はない。デフォルトを使うべき。
✔ 教訓
- CDKToolkit の暗号化は AWS 管理キーまたは CDK 自動生成キー一択
## ② SSM パラメータストア(DB ユーザー名/パスワード)× KMS
SSM パラメータの暗号化キーに自前 CMK を設定してしまった結果、Aurora 関連のカスタムリソースがずっと失敗してしまう。
● 起きた問題
- 自前 CMK に decrypt 権限なし
- Aurora のカスタムリソースが毎回失敗
- エラーログ:
Custom::AWS DbAuroraGetDbPassword FAILED
KMS:Decrypt is not permitted
✔ 教訓
- SSM の暗号化も AWS 管理キー一択
- 暗号化キーの変更は「上書きではなく再作成」が必要
## ③ Route53 の HostedZone が二重に存在する問題
(KMS ではないが、ここもハマった落とし穴なので記録)
● 起きた問題
-
同じドメインの HostedZone が 2 つ存在
- registrar で自動作成された zone
- 自分で作った zone
-
CDK は「間違った HostedZone」に CNAME を追加
-
ACM が永遠に検証されない状態に
✔ 今回学んだ HostedZone 二重問題の本質
① AWS は HostedZone 名の重複を禁止していない
Route53 は DNS の委任状態を管理しないため
example.com を何個でも作れる。
② DNS 委任(NS レコード)を AWS は検証しない
NS がつながっていない HostedZone でも普通に作成可能。
③ 複数 HostedZone を使うユースケースがある
- 本番・検証で分けたい
- 複数アカウントで管理したい
- DNS 移行時に並行運用したい
✔ 教訓
-
「本物の HostedZone」=レジストラに登録された NS と一致するゾーン
-
ACM が検証できないときは HostedZone の重複をまず疑う
-
初回のデプロイに失敗すると、“残骸リソース” が第二の災害を生む
-
EIP
-
NAT Gateway
-
Cache
-
失敗した DB クラスター
→ 手動で片付けないと次回も必ず失敗する。
今回の失敗で痛感したのは、
CDK のエラーの多くは KMS(CMK)が原因だった
しかしエラーメッセージがわかりにくく、根本原因に気づきにくい
という事実です。
CDK でサーバレスフルスタックを構築する際は:
- AWS 管理キーを使う
- SSM パラメータは再作成を恐れない
- HostedZone が複数存在しないか必ずチェック
これが重要でした。