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. 1回目のデプロイは普通にjs, css等がS3に配置される
  2. 画像をlightsailからS3のimages/articlesに移し、動作確認をする
  3. デザイン面で微修正したくなりcssを改修
  4. cssを更新するため、2回目のデプロイ
  5. 再度、動作確認をしたら画像が表示されない
  6. コードや設定など色々確認したが問題がない
  7. 最後にS3を確認したら画像が軒並み消えていた...

発生した時、頭は真っ白になり、次に血の気が引き、嫌な汗が出てきました。

驚き

なかなか状況を飲み込めませんでしたが、調べた結果4番の2回目のデプロイで消えていました。

なぜなのか

デプロイ時、ローカルのlocal_filesフォルダ配下のファイルをS3のpublic_readにアップロードする前に、destinationKeyPrefixで指定したS3のpublic_read配下を、CDKは一旦全て削除してくれるのです。そのため記事画像images/articles配下は綺麗さっぱり消えていました。

リセット

どうすればよかったか

本当にCDK管理下に置いてあるlocal_files/assetslocal_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を使われる方は、参考にしていただければと思います。

こんな記事も読まれています