🔧

ブログをZolaに移行、AWSの後始末

に公開

技術検証目的で1年ほどNext.js + Amazon Amplify構成のブログを運用していました。目的も達成したので静的サイトジェネレーター(以下、SSGと記載)に移行しましたが、意外と移行先の選定やAWSの後始末に手間取りました。その記録を残します。

Zolaへの移行

移行先のSSGには Zola を選びました。

Python系(Pelican, Nikola)は以前使った経験があり、遅さに辟易していたので避けました。Hugo も使用経験があるため、比較的新しく人気のあるZolaを選びました。Rust製のシングルバイナリで、node_modulesやpip installが不要です。

MDX形式の200記事程度あったので、Markdownへの変換は、Claude Codeで作成した 移行ツール で対応しました。

ホスティング先はCloudflareを想定していました。

サービス Zola 対応 備考
Cloudflare Pages V1 のみ V2/V3 で zola: not found エラー
Netlify あり 2025年9月〜 月20デプロイ制限
GitHub Pages GitHub Actions 制限なし、無料

しかし、Cloudflare PagesはV2以降で ZOLA_VERSION 環境変数を無視する問題があり、Issue も2年放置されています。Netlifyは無料プランのデプロイ制限が厳しいため、GitHub Pages + Cloudflare CDNを採用しました。

AWSリソースの調査と閉鎖

移行で最も手間がかかったのはAWSの閉鎖です。Amplifyは便利ですが、裏でCloudFront、S3、IAMロールなど多くのリソースを自動生成します。管理コンソールでは複数サービスの画面を行き来することになり、見落としやすいと感じました。そのため、今回はすべてCLIで調査・削除しました。

まず、Amplifyが作成した可能性のあるリソースを網羅的に確認します。

# Amplify アプリ一覧(リージョン指定必須)
aws amplify list-apps --region ap-northeast-1

# CloudFront ディストリビューション
aws cloudfront list-distributions \
  --query 'DistributionList.Items[*].[Id,Origins.Items[0].DomainName,Status]' \
  --output table

# S3 バケット(Amplify が作成したバケットを探す)
aws s3 ls | grep -E 'amplify|blog'

# IAM ロール(Amplify 関連)
aws iam list-roles \
  --query 'Roles[?contains(RoleName,`amplify`)].RoleName' --output table

# ACM 証明書(カスタムドメイン用、us-east-1 固定)
aws acm list-certificates --region us-east-1 \
  --query 'CertificateSummaryList[*].[DomainName,CertificateArn]' \
  --output table

今回確認されたリソースと、Amplifyアプリ削除時の自動削除有無は以下の通りです。

サービス リソース 自動削除
Amplify blog-yostos アプリ -
CloudFront Amplify 管理のディストリビューション
S3 amplify-xxx-deployment バケット
IAM AmplifySSRLoggingRole 等
ACM blog.yostos.org 証明書

調査が終わったら、リソースを削除していきます。

Amplify Hosting(WEB_COMPUTEタイプ)の場合、アプリを削除するとCloudFrontとS3バケットは自動削除されます。

# アプリ ID を確認して削除
aws amplify list-apps --region ap-northeast-1 \
  --query 'apps[?name==`blog-yostos`].appId' --output text
aws amplify delete-app --app-id <APP_ID> --region ap-northeast-1

IAMロールは自動削除されないため、手動で削除します。ロールを削除する前に、アタッチされているポリシーをすべてデタッチする必要があります。

# ロールにアタッチされたポリシーを確認
aws iam list-attached-role-policies --role-name <ROLE_NAME>
aws iam list-role-policies --role-name <ROLE_NAME>

# ポリシーをデタッチしてからロールを削除
aws iam detach-role-policy --role-name <ROLE_NAME> --policy-arn <POLICY_ARN>
aws iam delete-role --role-name <ROLE_NAME>

ACM証明書はCloudFrontで使用中だと削除できないため、CloudFront削除後に実行します。ACM証明書はus-east-1リージョン固定です。

aws acm list-certificates --region us-east-1 \
  --query 'CertificateSummaryList[?DomainName==`blog.yostos.org`]'
aws acm delete-certificate --certificate-arn <CERT_ARN> --region us-east-1

DNSはFastmailで管理していたため、Amplify用のCNAMEレコードを削除し、GitHub Pages用の設定に変更しました。

削除後は、各リソースが消えていることを確認します。CloudTrailで削除イベントも確認できます。

# CloudFront(Amplify 管理分が消えていること)
aws cloudfront list-distributions \
  --query 'DistributionList.Items[*].Id' --output text

# S3(amplify 関連バケットが消えていること)
aws s3 ls | grep amplify

# CloudTrail で削除イベントを確認
aws cloudtrail lookup-events \
  --lookup-attributes AttributeKey=EventName,AttributeValue=DeleteApp \
  --region ap-northeast-1

まとめ

Zolaはシングルバイナリで依存関係がなく、node_modulesの管理から解放されます。Rust製で高速、テンプレートエンジンもJinja2ライクで書きやすいです。プラグインなしでSASSコンパイルやシンタックスハイライトまで対応しており、長期運用での保守コストの低さも魅力です。GitHub Pages + Cloudflare CDNの構成も安定しています。

Amazon Amplifyは構築が簡単な反面、閉鎖時には複数サービスにまたがるリソースの確認が必要です。CloudFrontとS3はAmplifyアプリ削除時に自動削除されますが、IAMロール、ACM証明書、DNSレコードは手動での削除が必要です。管理コンソールでは見落としが発生しやすく、かといって個人ブログでCloudFormationを使うほどでもない。そんなケースではCLIで網羅的に確認し、ログに残しながら作業を進めると安心です。

GitHubで編集を提案

Discussion