2023/1 本ブログをサーバレス化する際にやらかしたこと
脱Lightsailしサーバーレスへの移行について紹介しましたが、移行中にCDKを使ったやらかしをしたので教訓的な意味合いで紹介します。
何をやらかしたかと言うと、全ての記事画像ファイルを消してしまいました。。。
デプロイフォルダ構成
CDKの設定誤りが原因となるのですが、まずはローカル環境での画像周りのフォルダ構成について紹介します。
local_files # 公開用のフォルダ
├─ assets # js, css
└─ images
├─ static # 会社ロゴ画像
└─ articles # 記事画像※
この中でjs, css, 会社ロゴ画像ファイルを、S3にCDKで管理・デプロイできるように以下のようにしました。記事画像はデプロイ対象外ですが、S3上でも同様のフォルダ構成でimages/articles
配下に画像をためます。
new BucketDeployment(scope, 'BucketDeploy',{
sources: [
Source.asset(`./local_files`, {
exclude: [
'.DS_Store'
]
})
],
destinationBucket: bucket,
destinationKeyPrefix: 'public_read/'
});
CDKではこのような実装で、ローカルのlocal_files
フォルダ配下のファイルを、S3のpublic_read
配下にアップロードしてくれます。CDKビギナーでしたのでこの実装ができるまで苦戦しましたが、実現できた時の喜びはひとしおでした。
事件発生フロー
しかし、先ほどのCDK設定には問題があり画像が消えてしまうのですが、実装・構築の段階では気づけず、結果以下のような流れで、画像が消えてしまいました。
- 1回目のデプロイは普通にjs, css等がS3に配置される
- 画像をlightsailからS3の
images/articles
に移し、動作確認をする - デザイン面で微修正したくなりcssを改修
- cssを更新するため、2回目のデプロイ
- 再度、動作確認をしたら画像が表示されない
- コードや設定など色々確認したが問題がない
- 最後にS3を確認したら画像が軒並み消えていた...
発生した時、頭は真っ白になり、次に血の気が引き、嫌な汗が出てきました。
なかなか状況を飲み込めませんでしたが、調べた結果4番の2回目のデプロイで消えていました。
なぜなのか
デプロイ時、ローカルのlocal_files
フォルダ配下のファイルをS3のpublic_read
にアップロードする前に、destinationKeyPrefix
で指定したS3のpublic_read
配下を、CDKは一旦全て削除してくれるのです。そのため記事画像images/articles
配下は綺麗さっぱり消えていました。
どうすればよかったか
本当にCDK管理下に置いてあるlocal_files/assets
とlocal_files/images/static
それぞれのBucketDeploymentを作成するべきでした。
new BucketDeployment(scope, 'BucketDeployAssets',{
sources: [
Source.asset(`./local_files/assets`, {
exclude: [
'.DS_Store'
]
})
],
destinationBucket: bucket,
destinationKeyPrefix: 'public_read/assets/'
});
new BucketDeployment(scope, 'BucketDeployStatic',{
sources: [
Source.asset(`./local_files/images/static`, {
exclude: [
'.DS_Store'
]
})
],
destinationBucket: bucket,
destinationKeyPrefix: 'public_read/images/static/'
});
BucketDeploymentを利用する際には、慎重なS3フォルダ設計が必要であると感じました。
もし、同じフォルダに記事画像とjs・ロゴ画像を混在させるような設計をしていたら、アプリケーションの改修やDB内の過去データの修正など、解決にはもっと時間がかかっていたでしょう。
最後に
まだ移行前のlightsailを閉じていなかったため、復旧は可能でした。 もっと後になって発覚しなかったことは不幸中の幸いですし、今回のやらかしも今では貴重な経験をできたと思っています。
もしBucketDeploymentを使われる方は、参考にしていただければと思います。