Last Updated:

静的サイトとAzureのマネージドサービスによるサイト構築

azure

当ブログはMicrosoft Azureの各サービスを利用して構築した。ここでは、何をどのように使ったかについてまとめておこうと思う。

コンテンツの管理

当サイトは静的サイトとして構築した。これはStatic Site Generatorと言われるジャンルのソフトウェアを使い、サイトコンテンツを動的(つまり、リクエストが来た時に生成する)のではなく事前にコンテンツを生成しておいてファイルとして送信する手法を使っている。

静的サイトの大きな特徴としては以下の通り

  • リクエストの処理についてはファイルの送信のみになるため、実行時の負荷が極めて低い
  • ローカル環境にサイト構築のために必要となるソフトウェアの準備が必要になる
  • フォームなどの入力に応じて動かす仕組みについては別途用意する必要がある

なお、GatsbyのようにReactとバックグラウンドのAPIを組み合わせて構築する手法(Single Page Applicationとも言われたりする)でもStatic Site Generatorが使われるようになっている。

当サイトでは Hugo というソフトウェアを使ってサイト構築を行なっている。 なお、他にも色々なStatic Site Generatorがあるので、知りたい方は Static Genをご覧いただくのがおすすめ。

コンテンツ作成はVisual Studio Code(以下、VScode)を使いMarkdownで書いている。また、VScodeのHugo用機能拡張hogofyも合わせて使っている。

作業としてはVScodeで記事を書き、Hugoで生成したのち、コンテンツをデプロイするという流れとなる。

なお、配置と関係してくるが、生成されるコンテンツは全て.htmlで終わるようにするため

hugo --uglyURLs

でビルドしている。これに伴い、テンプレートについてもカテゴリーやポストといった記事の一覧へのリンクを修正することになった。これはHugoの機能で解決できそうだが、今回は時間が取れなかったので課題として今後の改善でカバーすることにした。

コンテンツの配置

生成されたコンテンツ、つまりHTMLなどのファイル群はAzure Blob Storageに置いている。

Blob StorageはHTTPまたはHTTPSでアクセスが可能であり、アクセス権限をPublicにすることで不特定多数からのリクエストを受けることができ、簡易なWebサーバのように利用できる特性を持つ。

ただし、Blob StorageをWebサーバのように利用する場合、いくつかBlob Storageの特徴に起因する課題がある。例えば、”ttp://ドメイン/“とアクセスするとデフォルトに当たるindex.htmlが表示されるが、これはWebサーバがよしなに処理してくれている。Blob Storageではこの機能が提供されていない。そこで、このサイトではあくまでBlob Storageをファイル置き場として使っており、コンテンツの配信に一工夫している。

配置作業については、ローカル環境でのファイル生成後にAzure Storage Explorerを使いファイルのアップロードを行なったが、同時並行でのアップロードが行われないため時間がかかる。そこで、Azcopy を利用することにした。

[以下、現在は使えなくなりました。その下に解決方法を書いてあります。]

Azcopyは.NET Coreで書かれておりWindows版とLinux版があるのだが、Mac版が無い。そこで調べたところ導入のTipsを紹介しているブログを見つけた。「AzCopy on Linux 出た記念でOS X(Sierra)でやってみたよ。」 ありがとうMr.Xさん!

最終的にアップロードは以下のようなスクリプトを書いて実行している。

hugo --uglyURLs
azcopy \
    --source ./public \
    --destination <Storage URL> \
    --dest-key <Key> \
    --recursive  \
    --set-content-type

[2018/5/1 追記]

AzCopyのGAに伴い、現在配布されているバージョン7.2ではLinux版をMacOSで利用できなくなりました。これは、AzCopyのインストールを楽にするため明示的に稼働環境を指定したコンパイルがなされているためです。

そこで、hawaku/azcopyとしてDocker Hubに置かれているazcopyのコンテナを利用することにした。(スペシャルサンクス to オルターブース森田さん!)

このようなスクリプトupload.shを作って、実行している。

hugo --uglyURLs
docker run -it --rm -v /Users/pakue/src/pakuecloud/public:/tmp/public hawaku/azcopy:7.2 azcopy \
--source /tmp/public \
--destination https://pakuecloud.blob.core.windows.net/staticsite/ \
--dest-key "<Key>" \
--recursive  \
--set-content-type

dockerコマンド -vを使ってローカルのコンテンツ出力先となるpublicをコンテナ内の/tmp/publicで読めるようにする。コンテナイメージはTagの7.2を付けてAzCopy 7.2が落ちてくるようにする。–sourceには先ほど設定した/tmp/publicを指定し、–destinationにはコンテンツを置くストレージのパスを設定。 –dest-keyにはストレージにアクセスするためのキーを書くこと。/tmp/publicの下を全部対象とするため–recursiveを指定し、さらにアップロード時にcontent-typeの設定もしてもらう。

以下をみると、Dockerを使っているがかなり速度は早いことが分かると思う。

まず、Hugoでコンテンツを生成。その後、出力されたPublicの配下のファイルをこのように全てAzure Storageに送っている。

[2018/9/26 追記]

azcopyの最新版ってどうなったかな?とGithubを見ていたところ、次期バージョンのv10のPreviewリリースを見つけた。

https://github.com/Azure/azure-storage-azcopy

このバージョンはGoで書かれているようでファイル1つで稼働する。サイトではWindows版 Linux版 MacOSX版が公開されていた。

Blob StorageのポータルのShared Access SignanatureでSASトークンの作成を行おう。Blob service の SAS URLに表示されるURLがazcopyで使うことになる。 SAS URLのままではコンテナー名が入っていないのでURLの中程にある?sv=の前にコンテナ名を入れること。つまり・・・

./azcopy cp "/Users/pakue/src/pakuecloud/public" \
        "https://pakuecloud.blob.core.windows.net/staticsite?sv=2017-11-09&ss=b&srt=sco&sp=rwdlac&se=2020-09-26T18:59:40Z&st=2018-09-26T10:59:40Z&spr=https&sig=XXXXXXXXXXXXXXXXXXXX" \
        --recursive=true \
        --overwrite=true

という感じになる。SASトークンの有効期限と権限設定は慎重に行うこと。

コンテンツの配信

Blob Storageからのコンテンツ配信については、前段にAzure Functions Proxyを使用している。 Azure FunctionsはAzureにおけるServerless環境として使うサービスであるが、このサービスには Proxyが付いている。本来であれば、同一のドメインのエンドポイントとFunctionsのエンドポイントを繋ぐのに使うものだが、 この機能を使って裏側にBlob Storageがくる構成を組んでいる。

Functions Proxyでは呼び出し側のURLと裏側のURLを紐付ける設定を行っている。 例えば”/“で終わっているときは”/index.html”を呼び出すよう設定ができ、ルールに”/css/{*path}“と書けば”/css/“以下のパス全てを対象としてマッピングさせることができる。

詳細エディターで表示されるコードを一部抜粋するとこんな感じ。

"pakuecloud": {
    "matchCondition": {
        "route": "/"
    },
    "backendUri": "https://pakuecloud.blob.core.windows.net/staticsite/index.html"
},
"pakuecloud_top": {
    "matchCondition": {
        "route": "/{*path}"
        },
        "backendUri": "https://pakuecloud.blob.core.windows.net/staticsite/{path}"
    },

詳細については 公式ドキュメント に書かれているので目を通すことをお勧めする。

ドメイン管理

Azure Functions Proxyはカスタムドメインを使うことができるので、当サイトの構築に辺り新しくドメインを取得した。

ドメインの管理についてはAzure DNSを使っている。

ログ管理

監視については、Azure Functions Proxyの処理状況が対象となるので、Functionsが標準とする診断ログとAzure Application Insightsを利用している。

マネージドサービスを多く使う場合のログは、何か起きた時のエビデンスとしての意味合いが強い。また、内部で起きていることを掴むための手段なので、きっちり設定してどんな内容が出力されるのかを見ながら学ぶのが良いと思う。

まとめ

以上が大まかな当サイトの裏側となっている。

当初、Azure CDN + Azure Storageも試していたのだが、Functions Proxy + Storageが 非常に使いやすく、かつランニングコストもかなり安いため採用することにした。

一つ、この方式が弱点として抱える点をあげるならば、リクエストが来てからの反応速度となる。Functionsはリクエストが来てからProxyを準備するという特徴がある。(これがServerlessの特徴的な部分)そのため、ランニングコストはとても低く管理範囲が極端に狭い。一方で、レスポンスについては起動したままで反応する従来の動的なサイトよりは幾分見劣りする。最終的には何を重きをおくのかという価値観によるので、この方式が万能では無いという点は覚えておく必要がある。一方で、変化した運用に関する作業を考えるとかなりメリットを感じる。

なんとなくサイト構築はCMS使うということをせず、一手間かかるが静的サイトジェネレーターを 使うことと、マネージドサービスをうまく使うことで非常に運用が楽になっていうのは特筆すべき点だと思う。