
この記事はFIXER Advent Calendar 2019 18日目の記事です。 昨日の前田さんの記事は こちらです。読んだ感想としては、 普段バックエンドを余程 C# で書いている私にとってはすごく新鮮で興味の湧く内容でした。同じ言語でバックからフロントまで統一できるのは良いですね。開発もスムーズに進みそうです。
あまり TypeScript や JavaScript を書かない人にこそ読んでほしい記事です。
本日は Azure Blob Storage による Web アプリケーションのホスティングが結構良かったので、それを記事にしました。
Azure Blob Storage で静的ページをホストするメリット
(以下、Azure Blob Storage を Blob Storage と省略します。)
Blob Storage を使う主なメリットは4つあります。
- 料金がかなり安い
- SPAの際にルーティング設定が不要
- リクエスト処理が高速
- デプロイが簡単
App Service プランを利用しないので料金も安く、簡単にデプロイできるので個人でサクッと作ったモノなどをホストするのには非常に向いていると思います。ということで実際にホストしていきます。
ストレージアカウントの作成
まずはAzure Portalからストレージアカウントを作成します。このときに気を付けることはストレージアカウントを作成する際にアカウントの種類を StorageV2(汎用 v2)にすることです。でないとホスト出来ません。

静的なwebサイトの有効化と手動でのデプロイ
さて、ストレージアカウントの作成が完了したら作成したリソースに移動します。するとストレージアカウントの設定に「静的な Web サイト」という項目があるので、有効にしてインデックス ドキュメント名を設定します。
保存を押すと、プライマリエンドポイントが生成されているので、予めコピーしておきます。

有効にしたら、$webというコンテナーが追加されているので、コンテナー直下にhtml、css、jsファイルなどをアップロードします。今回は Vue を使ったのでローカルビルドして生成されたdistフォルダの中身をアップロードします。フォルダのアップロードは Microsoft Azure Storage Explorerなどを使うと良いです。

コピーしたURLにアクセスします。すると早速デプロイされてました。SSLも有効化されてます。
ただ、毎回手動でビルドしてファイル(フォルダ)アップロードしてって結構辛いですよね。なのでCI/CDを組んで楽しましょう。

Azure DevOpsを利用したCI/CDの構築
今回は Github と連携して build ブランチにマージされたときに自動で Blob Storage にデプロイされるようにします。今回は Azure DevOps や pipeline の説明は割愛させてもらいます。まず build pipeline の設定です。build pipeline の ymlファイルを以下のように設定します。
trigger:
- develop
pr:
- none
pool:
vmImage: 'ubuntu-latest'
steps:
- task: NodeTool@0
inputs:
versionSpec: '10.14'
displayName: 'Install Node.js'
- task: Npm@1
displayName: 'npm install'
inputs:
command: 'install'
- task: Npm@1
displayName: 'npm test'
inputs:
command: 'custom'
customCommand: 'test'
- task: Npm@1
displayName: 'npm build'
inputs:
command: 'custom'
customCommand: 'run-script build'
- task: PublishBuildArtifacts@1
inputs:
PathtoPublish: '$(Build.SourcesDirectory)/dist'
ArtifactName: 'blob'
publishLocation: 'Container'
何をしているかというと、
まず Node をインストール、次に npm install、npm test、npm build を走らせます。ビルドの成果物は$(Build.SourcesDirectory) に格納されるので、最後の task でその中のdistフォルダの中身を release pipeline 用に publish します。発行の際に zip 圧縮などは特にしません。
次に release pipeline の設定をします。設定するタスクは Azure file copy だけです。以下のように設定します。

Source は build pipeline で publish した場所を指定します。Azure Subscription で使用しているサブスクリプションを選択、RM Storage Account で先ほど作成した ストレージアカウントを選択して Container Name で $web を指定します。 これで Github と連携して build ブランチにマージされたときに自動で先ほど作成したストレージアカウントの $web コンテナーにデプロイされるようになりました。
これで設定は以上です。trigger などは良しなに変えて下さい。
負荷テストをやってみる
実際に Blob Storage と App Service の両方で負荷テストを行ってみます。負荷テストには Azure DevOps の Load Test を利用して、 URL based test を行いました。負荷テストの設定は以下のように設定しています。
- Run duration (minutes) → 10
- Load pattern → constant
- Max v-users → 100
- Warmup duration (seconds) → 0
- Browser mix → IE - 60% Chrome - 40%
- Geo-location → East Asia
結果は以下のようになりました。


Blob Storage の方が AVG. RESPONSE TIME が結構早いですね。Blob Storage だからといって性能が劣るわけではなさそうです。
まとめ
Blob Storage 、単純に Blob を格納するだけでなくこういった事もできます。用途に応じて App Service などとの使い分けをしていきたいですね。
カスタムドメインなどは結構めんどくさいイメージです。今度また調査してブログにします。