2024年12月、「Azure CDN from Edgioが廃止される」という突然の通知に驚き、移行作業に追われた方も多いのではないでしょうか。私もその1人でした。Webスタティックホスティング用途で「Azure Blobストレージ+Azure CDN」を複数のサイトで利用していたため、急遽、別のCDNへの移行が必要になりました。
Azure Front Doorへの移行が推奨されていますが、私の用途ではオーバースペックでコストが見合わず※1、最終的にAmazon S3+CloudFrontへの移行を選びました。その過程で、Pythonスクリプトを用いて効率よく移行を行う方法を開発しました。
※1 Azure Front Doorは高機能で優れた選択肢ですが、基本料金が高額で、小規模なWebサイトでは費用対効果が低い場合があると思います。
課題と解決策
移行作業では、AWS DataSyncも試しましたが、自由度が低く、私の求める柔軟性を満たせませんでした。そのため、自作のPythonスクリプトを使い、以下の機能を実現しました。
- Azure Blobストレージから(ローカル環境へ)のデータ取得
- Amazon S3へのアップロード
- 実行時のログやエラーを管理
このあと、CloudFrontでHTTPS対応のホスティングを設定する作業は説明資料に従って進めてください。
スクリプトは以下のGitHubリポジトリで公開しています。興味がある方はぜひご覧ください。
本スクリプトおよび資料は、現状のまま(AS IS)で提供されており、いかなる保証も行いません。本スクリプトの使用により発生したいかなる損害や問題についても、作成者は一切の責任を負いかねます。ご利用は自己責任でお願いいたします。
説明資料
詳細な手順はREADME.mdに記載しています。以下にもその内容を転載しておきます。
https://cdn.blog.st-hatena.com/images/theme/og-image-1500.png
Azure Blob to S3 Migration
このプロジェクトは、Azure Blobストレージからファイルをダウンロードし、Amazon S3にアップロードするためのPythonスクリプトを提供します。
また、アップロードした後に、Amazon S3をスタティック(静的)なWebサイトホスティングサービスとして構成し、Amazon CloudFrontによりCDNで配信されるようにし、AWS Certificate Manager(ACM)により生成し自動更新されるHTTPS用のSSL証明書を設定するまでの作業手順も、このREADME.mdファイルに掲載しています。
ただし、スクリプトはWindows環境で実行しているため、それ以外の環境での動作は保証できません。細かい調整が必要な場合は、スクリプトを修正することで対応してください。
※本スクリプトの実行は自己責任で行ってください。いかなる責任も負いません。また、本スクリプトにPR(プルリクエスト)やIssue(問題報告)を送られても、一切対応しませんので、あしからずご了承ください。
構成
requirements.txt
: 必要なPythonパッケージのリスト。config.ini
: 認証情報を含む設定ファイル。AzureBlobDownload.py
: Azure Blobストレージからファイルをダウンロードします。AwsS3Upload.py
: ダウンロードされたファイルをAmazon S3にアップロードします。BlobS3Compare.py
: 念のため、Azure BlobストレージとAmazon S3の内容を比較します。開発者が3サイトで実施して失敗はなかったため不要かもしれません。
ログファイル
<Blob名>_download_log.txt
: Azure Blobストレージからのダウンロードに関するログ。<S3名>_upload_log.txt
: Amazon S3へのアップロードに関するログ。<S3名>_compare_log.txt
: Azure BlobストレージとAmazon S3の内容比較に関するログ。
リトライ機能
※本プロジェクト開発者が試した限りでは、失敗が発生したことがないため、リトライ機能は実装済みですが、正常に稼働するかは検証されていません。
- ダウンロードやアップロードに失敗したファイルは、リトライ用のファイルに記録されます。
- 次回実行時にリトライ用のファイルを読み込み、前回失敗した処理を再試行します。成功した処理は再試行しません。
- 全てのファイルが成功した場合、リトライ用のファイルは削除されます。
前提条件
Azure BlobストレージをWebサーバとして活用してスタティックなWebページや画像を配信していることを前提としています。また、Azure CDNなどでCDNとSSLの自動更新を対応している場合もカバーしています。
既存のAzure Blobストレージが存在するあることを前提としています。また、同名のAmazon S3バケットを以下の手順で作成しておいてください。
S3バケットを作る手順
作成時に以下の内容を指定することを前提とします。
- AWS リージョンは「アジアパシフィック (東京) ap-northeast-1」とします。
- AWSコンソールでS3の[汎用バケット]を開き、[バケットを作成]をクリックします。
- [バケットタイプ]は「汎用」を選択します。
- [バケット名]はAzure Blobストレージアカウントと同じ名前にします。例:
remasahiko
- [ACL無効]を選択してください。
- [パブリックアクセスをすべてブロック]のチェックを外してください。
- [バケットのバージョニング]は「有効にする」にしてください。
- [タグ - オプション]でキーは「Name」、値は「<任意のプロジェクト名(例:
masahiko.info
)>」でタグを追加してください。 - 他はデフォルトのまま[バケットを作成]をクリックしてください。
- これでS3バケットの作成は完了です。
必要なPythonパッケージ
以下のコマンドを使用して、必要なパッケージをインストールしてください。
pip install -r requirements.txt
認証情報の設定
Azure Blobストレージアカウントの接続文字列の取得
- Azureで対象のストレージアカウントを開き、左のメニューから[セキュリティとネットワーク]-[アクセスキー]を選択します。
- [接続文字列]をコピーします。
AWSのアクセスキーの取得
AWSのアクセスキーはユーザーごとに取得します。セキュリティの問題もあるので、全ての作業が終わったら無効化もしくは削除するのがお勧めです。
- AWS Management Consoleにログインし、IAMサービスに移動します。
- 左側のメニューから[ユーザー]を選択します。
- 該当のユーザー名をクリックします。
- 上部の[セキュリティ認証情報]タブを開きます。
- [アクセスキーを作成]をクリックします。
- [ユースケース]は「ローカルコード」を選択します。
- [説明タグ値]は空のままで[アクセスキーを作成]をクリックします。
- これにより、アクセスキーIDとシークレットキーが発行されるので、確実にどこかに記述してください。
config.iniの編集
ご自身の環境に合わせて修正してください。
ConnectionString
: Azure Blob Storageの接続文字列を設定します。BlobStorageName
: Blobストレージ名を指定します。S3BucketName
: 比較対象のS3バケット名を設定します。AccessKeyId
: AWSアクセスキーIDを設定します。SecretAccessKey
: AWSシークレットアクセスキーを設定します。Region
: AWSリージョンを設定します。
使用方法
AzureBlobDownload.pyの使用方法
(1) AzureBlobDownload.py
を実行して、Azure Blobストレージからファイルをダウンロードします。
python AzureBlobDownload.py
注意点として、パブリックアクセスが 'container' 以外のコンテナ(プライベートやBLOBなど)はスキップする仕様なので注意してください。必要があればプログラムを書き換えてください。
(2) ダウンロードされたファイルは、指定されたローカルディレクトリに保存されます。
AwsS3Upload.pyの使用方法
(1) AwsS3Upload.py
を実行して、ダウンロードされたファイルをAmazon S3にアップロードします。
python AwsS3Upload.py
(2) アップロードの成功または失敗はログファイルに記録されます。
BlobS3Compare.pyの使用方法
(1) BlobS3Compare.py
を実行して、Azure BlobストレージとAmazon S3の内容を比較します。
python BlobS3Compare.py
(2) 比較の結果はログファイルに記録されます。
全て成功すれば作業は完了です。
S3バケットをスタティックなWebサイトホスティングサービスにするまでの手順
注意事項
- パブリックアクセスを有効化する際はセキュリティに注意してください。不要なデータが公開されないように。
- 公開したくないファイルはそもそもアップロードしない方がよいでしょう。このスクリプトではもともとAzure Blobストレージでパブリックに公開されていたBlobのみを移行する仕様になっていますので、基本的には新たに不要なデータが公開されることはないはずです。
手順 1: 静的Webサイトホスティングを有効化
- AWSコンソールで対象のS3バケットを選択します。
- 上部メニューの[プロパティ]をクリックしてください。
- [静的Webサイトホスティング]セクションの[編集]をクリック。
- 「静的Webサイトホスティング」の「有効にする」を選択します。
- [ホスティングタイプ]jは、「静的ウェブサイトをホストする」を選択します。
- [インデックスドキュメント](例:
index.html
やdefault.html
)を入力。- 必要なら[エラードキュメント](例:
error.html
)も入力。このファイルは基本的にバケットのルート(トップレベル)に配置してください。
- 必要なら[エラードキュメント](例:
- [変更の保存]をクリックします。
サンプルのerror.html
ファイルをこのプロジェクトに含めていますので、これをS3バケットのトップレベルにアップロードしてみてください。
手順 2: ブロックパブリックアクセスをオフにする
この作業は、作成時にオフにしていれば不要です。
- 上部メニューの[アクセス許可]をクリック。
- [ブロックパブリックアクセス (バケット設定)]セクションの[編集]をクリック。
- すべてのチェックボックスをオフにします。
- 保存します。
- 注意: この設定変更により、バケットがパブリックにアクセス可能になるリスクがあります。次のポリシー設定を適切に行いましょう。
手順 3: バケットポリシーを設定
S3バケットをパブリックにアクセス可能にするため、バケットポリシーを記載します。
以下は、特定のS3バケット(例: example-bucket
)内のすべてのオブジェクトをパブリックにするポリシーです。arn:aws:s3:::example-bucket
の部分は「バケット ARN」と呼ばれますが、編集画面上でコピーできます。
{ "Version": "2012-10-17", "Statement": [ { "Sid": "PublicReadGetObject", "Effect": "Allow", "Principal": "*", "Action": "s3:GetObject", "Resource": "arn:aws:s3:::example-bucket/*" } ] }
- 引き続き[アクセス許可]にある[バケットポリシー]セクションの[編集]をクリック。
- 上記のJSONコードを貼り付けます(
example-bucket
を実際のバケット名に変更)。 - 保存します。
手順 4: オブジェクト所有者を確認
S3バケットの[アクセス許可]で[オブジェクト所有者]が「バケット所有者の強制」となっている場合、ACL(アクセスコントロールリスト)は無効になっています。つまり、このバケット内のすべてのオブジェクトは、このアカウントによって所有されます。このバケットとそのオブジェクトへのアクセスは、ポリシーのみを使用して指定されます。
このプロジェクトでは、ACLが無効であることを前提としています。ACLが有効な場合、バケットポリシーを設定しても、オブジェクト(ファイル)がパブリックでない場合があります。
手順 5: WebサイトのURLにアクセス
スタティックWebサイトのURLは、以下の形式になります。
http://{バケット名}.s3-website-{リージョン}.amazonaws.com http://remasahiko.s3-website-ap-northeast-1.amazonaws.com
- 対象のS3バケットの上部メニューの[プロパティ]をクリックしてください。
- 一番下の[静的ウェブサイトホスティング]にある「バケットウェブサイトエンドポイント」のURLを開いてみてください。個別のオブジェクトにアクセスできるかは後で確認します。
- 上部メニューの[オブジェクト]から任意のオブジェクトを開いてください。
- 上部メニューの[プロパティ]を開き、[オブジェクトの概要]の[オブジェクト URL]を開いて、実際にWebアクセスできるかを確認してください。
- これによりHTMLページや画像などが正常に表示されれば、S3のスタティックなWebサイトの公開は完了です。
S3バケットのサイトがCDN(カスタムドメインSSL証明書あり)で配信されるまでの手順
Amazon CloudFrontの手順の中で、AWS Certificate Manager(ACM)を使ってカスタムドメイン用のSSL証明書を取得するようになっています。証明書の発行時にDNS検証を選択することによって、期限切れの60日前に自動更新されます。
Amazon CloudFrontの設定手順
CloudFrontディストリビューションの作成
- AWS Management Consoleにログインし、CloudFrontサービスに移動します。
- [CloudFront ディストリビューションを作成]をクリックします。
- [Origin domain]で、S3バケットのエンドポイントを選択し、それにより表示される[Web サイトのエンドポイントを使用]をクリックします。
- 例:
- <バケット名>.s3-website-<リージョン>.amazonaws.com
- 例:
- [名前]は自動的に入力されます。
- [デフォルトのキャッシュビヘイビア]セクションで[ビューワープロトコルポリシー]を「Redirect HTTP to HTTPS」に設定します。
- [ウェブアプリケーションファイアウォール (WAF) ]セクションで「セキュリティ保護を有効にしないでください」を選択します。追加費用を発生させないためです。必要になったらONにすればよいと思います。
- [設定]セクションの[料金クラス]で、日本メインなら「北米、欧州、アジア、中東、アフリカを使用」を選択します。性能と価格のバランスがよいためです。世界中からアクセスされるなら「すべてのエッジロケーションを使用する (最高のパフォーマンス)」がよいでしょう。
- その下の[代替ドメイン名 (CNAME) - オプション]で、[項目を追加]をクリックして、カスタムドメイン名(例:
re.masahiko.info
)を入力します。 - その下の[Custom SSL certificate - optional]で、[証明書をリクエスト]リンクをクリックします。
- [パブリック証明書をリクエスト]を選択して[次へ]をクリックします。
- [完全修飾ドメイン名]にカスタムドメイン名(例:
re.masahiko.info
)を入力します。 - [検証方法]は「DNS 検証 - 推奨」に必ずしてください。
- 他はデフォルトの推奨設定のままにします。
- リソースグループで管理しやすいように[タグ]も付けるのがお勧めです。キーは「Name」として、値は「masahiko.info」など独自のグループ名を指定します。
- [リクエスト]をクリックします。
- [ステータス]が「保留中の検証」となるので、検証用にDNSのCNAMEの追加が必要です。お使いのDNSの設定箇所で、[ドメイン]内の表で取得できる「CNAME名」からサブドメインまでの部分(例:
_abcdef123456gh7i8j9klm01n2opq345.<subdomain>
)を名前として、「CNAME値」(ドメイン名で場合によっては最後の.
を除いて内容、例:_a0123bcdefghigklmnopqrst45fvwxyz.zfyfvmchrl.acm-validations.aws.
)を値(正規名)として指定してください。 - 30分もしないうちに発行済みになります。[ステータス]に「発行済み」と表示されるまで待ちます。ブラウザーでリロードすると表示が変わる場合があります。
- CloudFrontのディストリビューション作成画面に戻ります。
- [Custom SSL certificate - optional]の右端の更新ボタンをクリックした後で、先ほど作成したSSLを[Custom SSL certificate - optional]で選択します。
- [Default root object - optional]にルート(
/
)でアクセスされたときに自動表示するファイル名(例:index.html
やdefault.html
)を入力。 - [ログ配信]は必要があればオンにしてください。ただし追加費用がかかるため、私の場合はオフにしています。
- [ディストリビューションを作成]をクリックします。
CloudFrontディストリビューションのデプロイ
- ディストリビューションのステータスが「有効」になるまで待ちます。わたしの場合はすぐでしたが、数分かかることがあるようです。
- ディストリビューションのステータスは、CloudFrontのトップページでも確認できます。
CloudFrontディストリビューションの確認
- CloudFrontディストリビューションの[ディストリビューションドメイン名]を使用して、S3に配置したオブジェクトのパスのWebページや画像にアクセスして、無事に表示されるのを確認します(表示されるようになるまでに数分かかります)。例:
d123456abcdef8.cloudfront.net
- [ディストリビューションドメイン名]はCDN設定で使うので、保存しておいてください。
- CloudFrontディストリビューションの[ディストリビューションドメイン名]を使用して、S3に配置したオブジェクトのパスのWebページや画像にアクセスして、無事に表示されるのを確認します(表示されるようになるまでに数分かかります)。例:
カスタムドメインのDNS設定と確認
最後にカスタムドメインでアクセスされるように設定すれば完了です。
カスタムドメインのCNAMEの内容(ドメイン名)に[ディストリビューションドメイン名]を指定してください。[ディストリビューションドメイン名]はCloudFrontで確認できます。
念のため、依然のCNAME内容は一時的に何かに書き写してバックアップしておきましょう。
反映まで1時間ほどかかります。長い場合は72時間程度も時間がかかることがあります。反映されたかはSSL証明書をブラウザから確認すればよいでしょう。もしくは以下のコマンドで確認できます。
nslookup <カスタムドメイン名>
ここまで出来たらAzure BlobストレージとAzure CDNの役目も終了なので、削除しても構いません。が、トラブル回避のため、72時間ほど様子を見てからの方がよいかもしれません。
全ての作業が終わったら、AWSのアクセスキーは無効化するか、削除しておきましょう。
ライセンス
このプロジェクトはApache License 2.0の下で公開されています。詳しくはLICENSEファイルをご確認ください。