koudenpaのブログ

趣味のブログです。職業柄IT関連の記事が多いと思います。

VSTSのビルド機能で静的サイトをデプロイする

やりたくてやったこと。

  1. 静的サイトのリソースをビルドする
    • npm install
    • npm run build
  2. リソースを Azure Blob Storage にコピーする
  3. Azure CDN のエンドポイントをパージする

しばらくそれぞれ手動でやっていたのだけれど、何回もやるのは辛くなってきたので自動化した。

世の中には非常に強力なDevOps基盤としてVSTSVisual Studio Team Services)が存在する。

azure.microsoft.com

今回はそのビルド機能を使ってみた。リリース先がAzureなので楽だろう、という目論見だ。

実際楽だった。

f:id:koudenpa:20180611033219p:plain

ウィザードに従ってビルドのタスクを追加していくだけで、やりたかったことを実現できた。

何故Copyタスクが二つあるのか?

唯一躓いたのは、単にAzure File Copyした際に、CSSが妥当なContent-Typeでアップロードされずapplication/octet-streamで配信されてしまった点。

仕方ないので、先にCSSだけContent-Type指定でコピーしてから他のリソースをコピーすることにした。

追記CSSだけだと思っていたが、単に新規のファイルがCSSだけだっただけ(元々設定されていたContent-Typeが適用されていた )で、他のファイル形式も全滅していた。 CSS以外もContent-Type解決設定なしではapplication/octet-streamとなってしまう。 逆に、CSSに関しても /SetContentType オプションのファイル拡張子からの解決で妥当に設定された。

コピータスクが内部で使用しているAzCopyには他にもいろいろオプションはあるが、基本的にはデフォルトで良さそうである。

→だめ。静的サイト配信時には必ず Additional Arguments に /SetContentType を指定する必要がある。

docs.microsoft.com

num run build

install, publish 以外のnpmコマンドは、タスク定義のCommandでcustomを選択し、Command and argumentsに実行したいコマンドと引数を設定してやればよかった。

f:id:koudenpa:20180611031106p:plain

定義のコード管理は現実的か?

正直無理。定義をエクスポートしてみたが、各種UUIDでのリソース参照が大量に含まれており、とても人間がコードを書いて管理できるような定義ではなかった。

エクスポート、インポート時以外に定義をコード(JSON)で見ることはなさそうだ。

f:id:koudenpa:20180611030839p:plain

定義はエクスポートできる。

追記YAMLでの定義がプレビュー中であることを教えていただいた。 有効化して見てみたけれど、結構良さそうだった。 今度切り出してみたい。

Blob Storage + Azure CDNの不足点

Blob Storage + Azure CDN は現状Azureで静的コンテンツを配信する定石だと思うのだが、致命的に不足している点がある。

スタンダードな構成だと //index.html を返却出来ない。

これをやろうとするには、現状Azure CDNのプランをルール定義などできる高級プランにした上で //index.html に関連付けるルールを定義しなくてはならない。

そのためだけに追加のコスト(通常の倍)を支払うのは業腹すぎる。

正直致命的な不足なので、特に縛りがない限りS3 + CloudFront(他に知らないけれど、他にも需要を満たす構成はあるはず)の方が万事良いだろう。 CloudFrontならある程度のエッジコンピューティングが統合されているうえ、リッチなことをやりたければLambda @Edgeを使えばよい。コスト、機能両面で圧倒的であるように感じる。

Azure のCDNはAzureとしてのそれがプレビュー中など、今度より良いものになっていくのだろうが、正直現状は他社のサービスに押されているように思えた。

先駆者もいる。

qiita.com

hawaku.hateblo.jp


2018/07/19追記

slideship.com

ディレクトリへのアクセスでインデックスページが返る

index.html を返す機能が追加されているらしい。 (追記時点ではPreviewとのこと)