しばやん雑記

ASP.NET Core とメイドさんが大好きなフリーランスのプログラマーのブログ

Azure Storage と Azure Pipelines で静的サイトのホスティングとデプロイ自動化を行う

静的サイトのホスティングを App Service で行うことが多いのですが、まあ高確率で Azure Storage の Static website について言及されます。Static website は便利なんですが、フロントに Azure CDN がほぼ必須かつデプロイが行いにくいので避けてきました。

とはいえ、そろそろデプロイ含め自動化をしたいと思ったので、使い道のないドメインを使って試しておくことにしました。VuePress を使って適当に作ったサイトをデプロイします。

上のリポジトリを Azure Pipelines がビルドして、Azure Storage にデプロイするようにパイプラインを組みます。とはいえビルド部分は割とどうでもよい感じです。

基本的には公式ドキュメントやチュートリアルにある内容なので、デプロイ部分だけが重要です。

今回は手軽さを重視して Azure CDN を使いましたが、Front Door でも同じことが行えます。Front Door は高機能ですがその分設定が少し複雑なので、サクッと試す分には Azure CDN が楽です。

Azure Storage の環境を構築する

ほぼドキュメント通りかつ、Static website の設定は既にいろいろと情報があるので端折ります。GPv2 なストレージアカウントを好きなリージョンに作成しておけば良いです。

Static website を有効化する

デプロイするサイトは VuePress を使っているので、エラードキュメントのパスは 404.html となります。

f:id:shiba-yan:20190716163437p:plain

デフォルトのままで良いはずですが、ちゃんと設定されているか確認しておきます。

Azure Pipelines からデプロイ

VuePress のビルドは前に書いた通りなので省略します。今回も同じように zip にしたものを Artifact としてプッシュするようにしておきます。

リリースパイプラインは以下のように組みました。わざわざ受け渡しを zip にしているのは、ファイル数が多くなった時に固めておいた方が処理が早いからです。

今回は Azure Storage にファイルをコピーする方法として AzCopy を使いました。

f:id:shiba-yan:20190716014820p:plain

Azure Storage にファイルをコピーする方法としては Azure File Copy というタスクもありますが、不要な Blob を削除してくれないので相性が悪いです。

本来ならアトミックにデプロイしたいところですが、Azure Storage だと AzCopy が限界な気がします。

AzCopy v10 は入っていないようなので、以下のようなスクリプトを書いて適当にダウンロードします。Linux 向けを落とすので、ホストは Ubuntu を使います。

wget https://aka.ms/downloadazcopy-v10-linux
tar -xvf downloadazcopy-v10-linux
cp ./azcopy_linux_amd64_*/azcopy ./

ダウンロードした AzCopy を使って Azure Storage とビルドした結果を同期するわけですが、SAS 周りの扱いが割と面倒なのでスクリプトがごちゃごちゃします。

この辺りは AzCopy を使うタスクがあればシンプルに使えそうですが、見当たりませんでした。

end=`date -d "5 minutes" '+%Y-%m-%dT%H:%M:%SZ'`
sas=`az storage container generate-sas -n '$web' --account-name $1 --https-only --permissions dlrw --expiry $end -otsv`
./azcopy sync "$(System.DefaultWorkingDirectory)/dist/" "https://$1.blob.core.windows.net/\$web?$sas" --recursive --delete-destination=true

スクリプトをコピペして、ストレージアカウント名を Arguments として設定すれば終わりです。

f:id:shiba-yan:20190716015218p:plain

適当に新規リリースを作成すると、パイプラインが動いて Azure Storage にファイルがコピーされます。

f:id:shiba-yan:20190716164401p:plain

Static website の URL を確認すると、VuePress で作成したページが表示されます。

f:id:shiba-yan:20190716165641p:plain

これで今回の作業はほぼ終わりです。後はおまけ程度に Azure CDN の設定を行うだけです。

Azure CDN の設定を行う

既に Azure CDN のカスタムドメインや HTTPS については書いているので、今回はさらっと流します。

CDN Endpoint 作成時に Custom origin を選ぶことを忘れないようにすれば大体 OK です。

f:id:shiba-yan:20190716164544p:plain

Storage Account を選ぶと通常の Blob Endpoint になるのは地味に罠っぽいです。

カスタムドメインの設定

Azure DNS を使って Alias record set を作成して対応します。CDN Endpoint がドロップダウンに出てくるので、この辺りは簡単に設定できます。

f:id:shiba-yan:20190716014736p:plain

検証に必要な CNAME を同時に作成してくれるので、Alias record set の作成後は Azure CDN にカスタムドメインを追加すれば完了です。

f:id:shiba-yan:20190716014805p:plain

少し待てば、設定したカスタムドメインでアクセス出来るようになっているはずです。

f:id:shiba-yan:20190716164106p:plain

必要であれば HTTPS の有効化も行いましょう。折角なので最後まで行っておきました。

HTTPS を有効化する

Azure CDN は無料で DigiCert の証明書が使えますが、プロビジョニングに時間がかかるので今回は Key Vault に入っていた Let's Encrypt の証明書を使いました。

適当に Key Vault や証明書、バージョンを選択して保存すれば CDN POP へのデプロイが行われます。

f:id:shiba-yan:20190716015030p:plain

2 時間ぐらいかかるとありますが、実際にはもう少し早く終わることが多い印象です。

証明書のデプロイが終われば、問題なく HTTPS でアクセス出来るようになります。これで完成です。

f:id:shiba-yan:20190716164143p:plain

Azure CDN / Front Door に Key Vault から証明書をデプロイした場合は自動更新されないという弱点がありますが、ロードマップには入っていて来年頭ぐらいに対応予定のようです。

ちょいちょい Azure CDN / Front Door について呟くと、中の人から教えてもらえます。

補足 : Front Door の場合

Front Door はバックエンドは Azure CDN と同じなので、大体は CDN と同じような設定で使えます。Front Door の方が HTTPS リダイレクトが使えたり、複雑なルールも書けるので便利ではあります。

気になった部分については、前にまとめを書いているので参照してください。

追記 : CDN の Purge をリリースパイプラインに入れる

単純に Azure CDN を被せただけだとファイルのキャッシュがなかなか消えてくれないので、Azure Pipelines で CDN キャッシュのパージまで行った方が良かったです。

Azure CLI を使うと、以下のようなコマンドで CDN エンドポイントのパージが行えます。

az cdn endpoint purge -g <resourcegroup> -n <endpoint> --profile-name <cdnprofile> --content-paths '/*'

リリースパイプラインに入れると、Storage へのファイルコピー後にパージを行えるので安心。

f:id:shiba-yan:20190716183557p:plain

Azure CDN の Microsoft / Verizon では 2 分ほど、Akamai だと 10 秒ほどかかるとドキュメントにあります。上のコマンドは --no-wait を付けない限り、完了するまで返ってこないので分かりやすいです。