ツナ缶雑記

ぐうたらSEのブログです。主にマイクロソフト系技術を中心に扱います。

Azure Pipelines で Markdown から静的 Web サイトを生成してStorage Accountに公開する(mkdocs)

f:id:masatsuna:20210624080015p:plain

前回は mkdocs を使って静的な Web サイトを Markdown を用いて生成しました。

tsuna-can.hateblo.jp

今回はこれを Azure DevOps を使って、 Azure Storage Account の静的 Web サイトに発行する手順を解説します。

環境

  • Azure DevOps
  • Storage Account(静的 Web サイト)

Storage Account の 静的 Web サイトとは

Storage Account にアップロードしたファイルを、 Web に公開してくれる機能です。 サーバー側は、ただ静的ファイルを公開する機能しか持たないため、サーバー再度で何らかの処理を行うことはできません。 JavaScript のように、クライアント側で実行するものは使えますが、あくまで静的なファイルを配信する目的にしか使えません。

またファイルの配置先は Storage Account となるため、 Web アプリケーション自体の認証機能が弱いです。 Azure AD と接続して認証させたいとか、細かな制御ができません。 同じような機能を提供してくれる Static Web Apps というものもありますので、要件に合わせてよい方法を選択してもらえればと思います。

ディレクトリ構造

今回作るディレクトリの構造は以下のようなものになります。

ルートディレクトリ
├ mkdocs.yml
├ docs
│  └ index.md
└ pipelines
   └ markdown-build.yaml

Markdown を作る

今回は Azure Pipelines で静的 Web サイトを発行することが目的なので、作成する Markdown は初期のものをそのまま使います。 mkdocs.yml と index.md が mkdocs で生成したファイルです。 詳細は前回の記事を参照してください。

Azure Pipelines 用の YAML を作る

markdown-build.yaml ファイルに、 mkdocs のビルドを行うための設定を記述していきます。 今回は mkdocs による静的 Web サイトの生成と、 Storage Account の静的 Web サイトへの発行の 2 ステップを行います。 説明を簡略化するため、 Multi Stage Pipeline は利用していないことに注意してください。

構築する YAML の全体像は以下のようになります。

trigger: none

pool:
  vmImage: ubuntu-latest

steps:
  - task: PowerShell@2
    displayName: "MkDocs のインストールと実行"
    inputs:
      targetType: 'inline'
      script: |
        python -m pip install wheel
        python -m pip install mkdocs
        python -m pip install mkdocs-material
        python -m pip install mkdocs-minify-plugin
        python -m mkdocs build
  - task: AzureCLI@2
    displayName: '静的Webサイトの更新'
    inputs:
      azureSubscription: '<サービスコネクションの接続名>'
      scriptType: 'pscore'
      scriptLocation: 'inlineScript'
      inlineScript: |
        Param($StorageAccountName, $ContainerName, $UploadDirectory)
        az storage blob delete-batch --source $ContainerName --account-name $StorageAccountName
        az storage blob upload-batch --destination $ContainerName --source $UploadDirectory --account-name $StorageAccountName
      arguments: 
        -StorageAccountName '<ストレージアカウントの名前>'
        -ContainerName '$web'
        -UploadDirectory '$(Build.SourcesDirectory)/site'

以下、部分ごとに解説していきます。

Python のインストール要否

今回は ubuntu-latestVM を利用するため、 PythonVM イメージにインストール済みです。 この記事を書いている時点では、 Python 3.8.5 がインストールされていました。 また pip についてもインストール済みです。

VM イメージにインストールされているソフトウェアは、以下のページから参照することができます。

docs.microsoft.com

もっと新しいバージョンの Python を使いたい場合は、自分で Python をインストールするようにしましょう。

mkdocs のインストール

Python 同様、 pip も ubuntu-latest のマシンにはプリインストールされています。 また PowerShell もインストールされています。 ということで、 PowerShell のタスクを使って、必要となるパッケージをインストールしています。

  - task: PowerShell@2
    displayName: "MkDocs のインストールと実行"
    inputs:
      targetType: 'inline'
      script: |
        python -m pip install wheel
        python -m pip install mkdocs
        python -m pip install mkdocs-material
        python -m pip install mkdocs-minify-plugin

mkdocs の実行

前述のタスクの最後に、 mkdocs を使って静的 Web ページを生成しています。 以下の個所がそれです。

python -m mkdocs build

このコマンドを実行することで、 mkdocs.yml ファイルのあるディレクトリに、 site という名前のディレクトリが生成され、その中に静的 Web サイトの HTML や CSS などのコンテンツが出力されます。

Azure Blob Storage の作成

ここまでで静的 Web サイトとして発行するための資材は完成しました。 続いて静的 Web サイトを発行する先の Azure のリソースである Blob Storage を作成します。

普通に Azure Portal から Blob Storage のリソースを 1 つ作成します。 作成が完了したら、 Blob Storage に対して静的 Web サイトの機能を有効にします。

まず Storage Account の画面に入って、左側のメニューから [データ] > [静的な Web サイト] を選択します。

f:id:masatsuna:20210621234142p:plain

続いて右側のブレードで [静的な Web サイト] を [有効] に設定し、以下のように設定します。

項目 設定値
インデックス ドキュメント名 index.html
エラー ドキュメントのパス 404.html

f:id:masatsuna:20210621234433p:plain

この状態で左上にある [保存] ボタンを押下します。 すると画面が以下のようになり、 Web サイトを公開している URL が表示されます。

f:id:masatsuna:20210621234834p:plain

この状態で、すでに Web サイトが立ち上がっています。 URL に対してブラウザーからアクセスすると、 404 が返ってくることがわかると思います。

静的な Web サイトの機能を有効にすると、 Storage Account に 「$web」という名前のコンテナーが自動的に作成されます。

f:id:masatsuna:20210622001351p:plain

このコンテナーに Web サイトの資材を配置すると、 Web ブラウザーから閲覧できるようになります。 これで Azure のリソース準備は完了です。

サービスコネクションの作成

続いて Azure DevOps から Azure Blob Storage に接続できるように設定していきます。 Azure DevOps の組織の管理者であり、 Azure サブスクリプションの所有者でもあるアカウントであれば、すごく簡単にサービスコネクションの設定が可能です。 以下の記事で設定手順を解説しています

tsuna-can.hateblo.jp

本家サイトでは、以下に解説があります。

docs.microsoft.com

docs.microsoft.com

サービスコネクションを作成したら、その接続名を控えておきましょう。 あとで使用します。

Azure Blob Storage の更新

再度 Azure Pipelines の YAML に戻り、作成したサービスコネクションを経由して、 Azure Blob Storage に静的 Web サイトを配置できるようにしていきます。 ubuntu のマシンから Azure のリソースに接続する場合は Azure CLI のタスクを利用します。 今回は PowerShell Core を使ってアクセスするように設定しています。 また azureSubscription には、先ほど作成したサービスコネクションの接続名を設定します。

  - task: AzureCLI@2
    displayName: '静的Webサイトの更新'
    inputs:
      azureSubscription: '<サービスコネクションの接続名>'
      scriptType: 'pscore'
      scriptLocation: 'inlineScript'
      inlineScript: |
        Param($StorageAccountName, $ContainerName, $UploadDirectory)
        az storage blob delete-batch --source $ContainerName --account-name $StorageAccountName
        az storage blob upload-batch --destination $ContainerName --source $UploadDirectory --account-name $StorageAccountName
      arguments: 
        -StorageAccountName '<ストレージアカウントの名前>'
        -ContainerName '$web'
        -UploadDirectory '$(Build.SourcesDirectory)/site'

今回は Blob Storage の「$web」というコンテナーに対して、静的 Web サイトを配置する前に全削除を行い、ビルドした資材を再度アップロードする、という方法で更新していきます。 Blob Storage のデータを削除したり更新したりする場合、 az storage blob というコマンドを使ってアクセスします。 Azure CLI のタスクを使用すると、 Azure へのログインは自前で行わなくても、タスク側で自動的に実行してくれます。 ですので、やりたい処理をそのまま書くだけで問題ありません。 特定のコンテナーからファイルを全件削除する場合、 az storage blob delete-batch コマンドを、ローカルディレクトリ内の全ファイルをアップロードする場合 az storage blob upload-batch コマンドを使うと便利です。

またアップロードする静的 Web サイトは、 mkdocs によってビルドした site ディレクトリ配下のものを指定しています。 今回はルートディレクトリ内に mkdocs.yml を配置しているため、ルートディレクトリ( $(Build.SourcesDirectory) の変数に設定されているパス)直下に生成される site ディレクトリをアップロード対象のディレクトリとして指定しています。

実行してみる

うまく設定ができていれば、ビルドパイプラインを実行すると、 Blob Storage の静的 Web サイトが更新されます。

f:id:masatsuna:20210622003518p:plain

存在しない URL をたたいた場合も、ちゃんと 404 ページが表示されていい感じです。

f:id:masatsuna:20210622003625p:plain

まとめ

今回は mkdocs を Azure Pipelines から実行して、 Blob Storage の静的な Web サイトに発行する手順を書きました。 CI トリガーを設定しておけば、 Git リポジトリを更新したら Web サイトを即時反映することもできちゃいますね。 Blob Storage の制約が気にならないのであれば、格安で情報共有サイトが作れます。 もしその辺の制約が気になるのであれば、 Static Web Apps とかも検討してみるとよいと思います。

本稿で解説した YAML について

原本は以下の GitHub リポジトリに公開してあります。

AzurePipelinesYAMLSample/MkdocsAndPublishToBlobStorage at master · tsuna-can-se/AzurePipelinesYAMLSample · GitHub