しばやん雑記

Azure とメイドさんが大好きなフリーランスのプログラマーのブログ

Azure Static Web Apps のデプロイに SWA CLI と Service Principal (Federated Credentials) を利用する

Static Web Apps へのデプロイを行う方法としては、公式で提供されている GitHub Action や Azure Pipelines Task を使う方法の他に Static Web Apps CLI を使う方法があります。最近ではビルドをカスタマイズしたいので、あえて Static Web Apps CLI を使ったデプロイを GitHub Actions でも行うようにしています。

SWA CLI を使ったデプロイ方法については以前書いたので、以下のエントリを参照してください。

この時の例では SWA CLI のデプロイに Deployment Token をシークレットに追加しましたが、App Service や Azure Functions のデプロイには RBAC と Federated Credentials を利用した安全な認証情報を使うのが最早当たり前になっているので、SWA だけ専用の認証情報を使う必要があるのは不満な点でした。

GitHub Actions で OIDC / Federated Credentials を使ったデプロイを行う方法も既に書いているので、詳細は以下のエントリを参照してください。App Service の公式ドキュメントも OIDC 対応になっています。

話を SWA CLI に戻しますが、元から SWA CLI は Service Principal を使ったデプロイには対応していたのですが、Azure CLI の認証情報を使ったデプロイには何故か非対応でした。

GitHub Actions 上での OIDC / Federated Credentials は実質的に Azure CLI へのログインとして扱われるため、SWA CLI に対して Azure CLI の認証情報を使うように Pull Request を作成したところ、かなり時間はかかりましたが先日リリースされたバージョン 2.0.0 で取り込まれました。

SWA CLI のバージョン 2.0.0 以降では、ローカルから SWA へのデプロイは Azure CLI にログインさえしていれば、以下のような非常にシンプルなコマンドで実現出来ます。

SWA 名を指定するだけなので非常に簡単ですし、Deployment Token のように明示的な指定や切り替えが必要ないため、自動化も圧倒的に行いやすくなります。

swa deploy ./dist/ --env production --app-name <app-name> --no-use-keychain

実際にローカルに SWA CLI の 2.0.0 以降をインストールしてコマンドを実行すると、以下のように認証情報を自動的に解決して、SWA へのデプロイが行われていることが確認出来ます。

正直これだけでもかなり便利なのでアップデートして使う価値があるのですが、本命は GitHub Actions / Azure Pipelines でのデプロイ時に Federated Credentials を使って、Deployment Token を不要にする構成です。

前述したとおり SWA CLI が Azure CLI の認証情報を利用できるようになったので、GitHub Actions などで OIDC / Federated Credentials を使ったログインを行えば、その認証情報を使ってデプロイが行われます。Federated Credentials を使ったログインについては以下のドキュメントを参照してください。

実際に GitHub Actions で Static Web Apps CLI と Federated Credentials を使って、SWA の Deployment Token を使わないワークフローの例を紹介しておきます。これは本番向けで利用しているものと同じです。

実行しているコマンドはローカルで叩いたものと同じですが、事前に azure/login@v2 で OIDC / Federated Credentials を使ったログインを実行しているのが大きな違いです。

  deploy:
    runs-on: ubuntu-latest
    needs: publish
    environment: production
    permissions:
      id-token: write
      contents: read
    steps:
    - name: Azure Login
      uses: azure/login@v2
      with:
        client-id: ${{ secrets.AZURE_CLIENT_ID }}
        tenant-id: ${{ secrets.AZURE_TENANT_ID }}
        subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}

    - name: Download artifact
      uses: actions/download-artifact@v4
      with:
        name: frontend
        path: dist

    - name: Deploy to Static Web App
      run: |
        npm i -g @azure/static-web-apps-cli
        swa deploy ./dist/ --env production --app-name <app-name> --no-use-keychain

既に App Service / Azure Functions へのデプロイを行っている場合には、SWA CLI を使ったデプロイに書き換えるだけで同じ Service Principal を使ってデプロイが行われるので、管理が必要な認証情報が減るためよりセキュアに運用できます。

個人的に運用している App Service Info というアプリのデプロイを SWA CLI と Federated Credentials に書き換えましたが、問題なく App Service にデプロイするための認証情報で SWA へのデプロイが行えています。

これで GitHub Actions に登録しているシークレットは Service Principal の利用に必要な 3 つだけになり、期限のある Client Secret や個別の Deployment Token が含まれなくなったので格段に管理がしやすくなりました。デプロイ先のリソースが増えたとしても、Service Principal の RBAC で対応できるので簡単です。

SWA CLI で Federated Credentials を使ったデプロイができるようになったので、殆ど全てのケースで Client Secret や Deployment Token といったシークレットが必要なくなりました。特に複数の SWA へのデプロイが必要な環境の場合は Deployment Token をそれぞれ管理する必要がありましたが、今後は不要です。

公式のデプロイ Action ではサポートされる気配がないので、SWA CLI を使って楽をしましょう。