Azure Static Web Apps でプレビューサイトのみアクセスを制限する
Web アプリの開発中に実際にデプロイして動作確認する際、何らかのアクセス制限をかけたいというニーズはよくあると思います。Basic 認証を使う例をよく見ますが、パブリッククラウド系のホスティングではその仕組み上使えないことが多いです。
Azure Static Web Apps でも Basic 認証は使えず、GitHub や Twitter などの認証プロバイダーを使ったアクセス制御を利用する形になります。ただし、ある特定の環境のみ認証を有効にする方法が標準では用意されていないので、config ファイルと CI/CD ワークフローをカスタマイズして実現する方法を紹介します。
開発環境用の config ファイルを作成する
Azure Static Web Apps(以下 SWA と記載する場合あり) ではアプリケーションの構成は基本的に staticwebapp.config.json
で設定します。ここでは、まず開発環境で有効にしたい設定を追加していくことにします。
上記公式ドキュメントの通り、設定ファイルでできることはたくさんありますが、アクセス制御に使うのは以下の設定項目になると思います。
ロールによるルートのセキュリティ保護
あるルート以下を特定のロールに紐づけられた認証が必須となるようにしたい場合に設定します。今回は開発環境の場合にサイト全体にアクセス制限をかけたいので、以下のように制限対象のルートを /*
で設定します。ロール名は後でポータルで紐づけるので適当な文字列を入れておきます。
{ |
ログインのルート設定
SWA では認証プロバイダーごとに .auth/login/<プロバイダー名>
といったログイン用のルートがあらかじめ定義されています。今回は開発時のみの認証を想定しているので GitHub 認証を使うことにします。その際、必須ではないのですが以下のように /login
などのルートに特定の認証用ルートをマッピングする定義を入れておくと便利です。
{ |
なお、他の認証プロバイダーを使わせたくない場合は以下のように設定すると無効になります(Twitter 認証を無効にする例)。
{ |
組み込みの認証を使う場合は、Azure Portal でアクセスを許可するアカウントを招待しておき、ロールを割り当てておく必要があります。
IP アドレス制限
最近、ネットーワーク設定の項目が新たに追加になり、 IP アドレスの制限を設定することができるようになりました(Standard プランのみ)。開発者が特定の IP 以下に特定できる場合はこの設定を入れるだけで、認証設定は使わなくても良いというケースもあると思います。認証と併用することも可能です。
{ |
CI/CD ワークフローで config ファイルを選択する
これらの設定を staticwebapp.config.json
に追加した状態で、SWA 標準の CI/CD ワークフローでデプロイすると、本番環境も含めてアクセス制限が効いてしまいます。そこで、GitHub Actions のワークフローで、開発時のみにこの設定ファイルが適用されるようにしていきます。
ワークフローを以下のようにカスタマイズして実現しています。
- 開発環境専用の設定を組み込んだ config ファイルを作成する(ここまでの作業で実施済み)
- ビルドとデプロイの Job を分割する(
Azure/static-web-apps-deploy
ではビルドしない) main
ブランチへのプッシュは PR 時以外はされないように branch protection を設定しておく- PR 時のビルドでは開発環境の config が選択されるようにする
main
へのプッシュ時(PR マージ時)は本番用の config が使われるようにする
これらを実現すると以下のような yaml になります(一部抜粋、アプリケーションは Nuxt.js で開発)。
name: Azure Static Web Apps CI/CD |
この設定にした場合、Pull Request を発行すると以下のようなワークフローが実現します。
- PR を発行する
- 開発環境用の config が使われてアプリがビルドされる
- プレビューサイト (pre-production environments) にアプリがデプロイされる
- アクセス制限が必要なプレビューサイトが公開される
なお、本番環境でも何らかの設定を入れたい場合は、 staticwebapp.config.prod.json
のように別名で config ファイルを設定しておき、CI/CD 時にファイル名を変更するようにしています。この点は、Node.js の env
ファイルのようにファイル名から自動で環境に紐づくような仕組みが欲しいところです。Issue をあげておいたので、いつか改善されることを期待したいです。