koudenpaのブログ

趣味のブログです。株式会社はてなでWebアプリケーションエンジニアをやっています。職業柄IT関連の記事が多いと思います。

Bitbucket Pipelines の Pipes で Azure Blob Storage の静的Webサイトにファイルをコピーする

昨今、静的なWebサイトのホスティングは簡便化が著しく、GitHub PagesのようにGitリポジトリがその機能を提供していたり、クラウドサービスならオブジェクトストレージ+CDNで構成すると安価かつ高速なファイル配信を行えたりする。

Microsoft Azureでこのオブジェクトストレージ+CDNでの静的サイトの構成は、2018年頃まではよい形で行えなかったのだが、2019年6月現在ではなかなか便利に行えるようになっている。

辛さは以下の記事がよくまとまっていて分かりやすい。

qiita.com

自分自身去年同様の不便さに直面した。

koudenpa.hatenablog.com

これらの辛さはどれも解消している。

また、自分がよく使っているGitリポジトリサービスであるBitbucketが Pipes という便利なCI機能をリリース、Azureも各種 Pipe を提供していたので『Bitbucket Pipes + Azure Blob Storage + Azure CDN』の形での静的WebサイトのCDを構成をしてみた。

bitbucket-pipelines.yml

master ブランチへの変更でBlobストレージへファイルコピーする bitbucket-pipelines.yml は以下のような形になった。

pipelines:
  branches:
    master:
      - step:
          name: Deploy to Azure Blob Storage.
          deployment: test
          script:
            - pipe: microsoft/azure-storage-deploy:1.1.1
              variables:
                SOURCE: 'public'
                # コンテナ名の $ を二重にエスケープ
                # 参照: https://community.atlassian.com/t5/Bitbucket-Pipelines-questions/How-do-I-properly-quote-Pipelines-pipe-variables-and-escape/qaq-p/1021713
                DESTINATION: 'https://hoge.blob.core.windows.net/\\\$web'
                DESTINATION_SAS_TOKEN: $AZURE_STORAGE_SAS_TOKEN
                # 参照: https://docs.microsoft.com/en-us/azure/storage/common/storage-use-azcopy-linux
                # ただし、azure-storage-deploy:1.1.1はAzCopy7.3
                EXTRA_ARGS: '--set-content-type'
                DEBUG: 'true'

2つの留意点があった。また、Azure CDNへの指定にも多少癖があったので併記する。

コンテナ名の $ を二重にエスケープ

Azure Blob Storage の静的Webサイトは $web という特別な名前のコンテナにオブジェクトを配置することで利用できる。

これによって / へのアクセスに対して /index.html を返却するようなWebサイトに必要となる機能が提供されるのだ。

docs.microsoft.com

しかし、Bitbucket Pipelinesでは $ から始まる単語は変数として扱われるためエスケープが必要となる。 また、このスクリプトの実行時にはシェルへのコマンド引数となるため、その際にも変数展開が行われる。

これを回避するには $ を二重にエスケープしなくてはならない。

以下のQAが分かりやすかった。

community.atlassian.com

AzCopyのバージョンが7.3

microsoft/azure-storage-deploy:1.1.1 では実際のファイルコピーに AzCopy というユーティリティを使用しているが、このバージョンが少し古い。

既定のオプション設定や指定などが最新版とは異なっている。

特に EXTRA_ARGS: '--set-content-type' は指定しておかないとファイルのContent-Typeが指定されず、HTMLファイルがダウンロードされるまさかの動作となる。

新しいバージョンの AzCopy ではこのオプション指定は逆転し、Content-Typeを設定しないことがオプションとなっているようだ(オプションの存在確認のみで試してはいない)。

Azure CDN に指定する配信元

Azure Blob Storage の静的Webサイトは通常のオブジェクト配信のURLとは別に、静的Webサイト向けのURLが用意される。 静的Webサイトに関する機能はそちらでの提供になるため、CDNの配信元に指定するホストもそちらとする。

CDN および SSL のサポート

静的な Web サイトのファイルをカスタム ドメインおよび HTTPS 経由で使用できるようにするには、「Azure CDN を使用して HTTPS 経由でカスタム ドメイン付きの BLOB にアクセスする」を参照してください。 このプロセスの一環として、CDN が BLOB エンドポイントではなく "Web エンドポイントを指す" ようにする必要があります。 CDN 構成がすぐに実行されないため、コンテンツが表示されるまで数分待たなければならない場合があります。

2019年6月現在、Azure Portal上での操作ではAzure CDNはAzure内の配信元候補をドロップダウンリストで提示してくれるが、そこにこの静的Webサイトのホストは存在しないので、カスタム配信元を選択する必要がある。

f:id:koudenpa:20190531083855p:plain
配信元種類はカスタムにする

感想

Azure CDNはDV証明書を無償で配置してくれるし、やっとAWSのS3 + CloudFrontに追いつきつつある。 CDN側がCloudFrontに比べると機能不足だが、静的サイトを構成する分には問題ない。

今後の機能充実にも期待したい。