GitHub Actionsで発行プロファイルを使わずにAzure App Serviceへデプロイする

2021.11.03

いわさです。

流行りのGitHub Actions+OIDCのAzure版をやってみました。

AWS版は以下の記事で紹介されております。

現在、ドキュメント上にはAWSもAzureもGoogleも全て方法が掲載されていますが、記載の無い部分で思ったより手こずりました。

同じように詰まる方がいるかもしれないので手順を残しておこうかなと思います。

App Service + GitHub Actionsの用意

今回は、App Service構築時にGitHub連携を有効化しリポジトリと連携させました。
アプリケーションは、dotnet new webで作成した直後のスケルトン状態です。
Hello World!と返事をしてくれます。

その状態からOIDCを使う形に変更したいと思います。
変更前のデフォルトのYAMLはこちらになります。

# Docs for the Azure Web Apps Deploy action: https://github.com/Azure/webapps-deploy
# More GitHub Actions for Azure: https://github.com/Azure/actions

name: Build and deploy ASP.Net Core app to Azure Web App - iwasa20211103aspcore

on:
  push:
    branches:
      - main
  workflow_dispatch:

jobs:
  build:
    runs-on: windows-latest

    steps:
      - uses: actions/checkout@v2

      - name: Set up .NET Core
        uses: actions/setup-dotnet@v1
        with:
          dotnet-version: '5.0.x'
          include-prerelease: true

      - name: Build with dotnet
        run: dotnet build --configuration Release

      - name: dotnet publish
        run: dotnet publish -c Release -o ${{env.DOTNET_ROOT}}/myapp

      - name: Upload artifact for deployment job
        uses: actions/upload-artifact@v2
        with:
          name: .net-app
          path: ${{env.DOTNET_ROOT}}/myapp

  deploy:
    runs-on: windows-latest
    needs: build
    environment:
      name: 'Production'
      url: ${{ steps.deploy-to-webapp.outputs.webapp-url }}

    steps:
      - name: Download artifact from build job
        uses: actions/download-artifact@v2
        with:
          name: .net-app

      - name: Deploy to Azure Web App
        id: deploy-to-webapp
        uses: azure/webapps-deploy@v2
        with:
          app-name: 'iwasa20211103aspcore'
          slot-name: 'Production'
          publish-profile: ${{ secrets.AZUREAPPSERVICE_PUBLISHPROFILE_B0984B498A96463183F0D36D46AFF106 }}
          package: .

secrets.AZUREAPPSERVICE_PUBLISHPROFILE_B0984B498A96463183F0D36D46AFF106が発行プロファイルですね。
App Serviceから取得すると以下のような形でユーザー名やパスワードが埋め込まれている秘匿情報です。

<publishData>
    <publishProfile profileName="iwasa20211103aspcore - Web Deploy" publishMethod="MSDeploy" publishUrl="iwasa20211103aspcore.scm.azurewebsites.net:443" msdeploySite="iwasa20211103aspcore" userName="$iwasa20211103aspcore" userPWD="hogehogehogehogehogehogehogehogehogehogehogehogehogehogehoge" destinationAppUrl="http://iwasa20211103aspcore.azurewebsites.net" SQLServerDBConnectionString="" mySQLDBConnectionString="" hostingProviderForumLink="" controlPanelLink="http://windows.azure.com" webSystem="WebSites">
        <databases />
    </publishProfile>
    <publishProfile profileName="iwasa20211103aspcore - FTP" publishMethod="FTP" publishUrl="ftp://waws-prod-ty1-051.ftp.azurewebsites.windows.net/site/wwwroot" ftpPassiveMode="True" userName="iwasa20211103aspcore\$iwasa20211103aspcore" userPWD="hogehogehogehogehogehogehogehogehogehogehogehogehogehogehoge" destinationAppUrl="http://iwasa20211103aspcore.azurewebsites.net" SQLServerDBConnectionString="" mySQLDBConnectionString="" hostingProviderForumLink="" controlPanelLink="http://windows.azure.com" webSystem="WebSites">
        <databases />
    </publishProfile>
    <publishProfile profileName="iwasa20211103aspcore - Zip Deploy" publishMethod="ZipDeploy" publishUrl="iwasa20211103aspcore.scm.azurewebsites.net:443" userName="$iwasa20211103aspcore" userPWD="hogehogehogehogehogehogehogehogehogehogehogehogehogehogehoge" destinationAppUrl="http://iwasa20211103aspcore.azurewebsites.net" SQLServerDBConnectionString="" mySQLDBConnectionString="" hostingProviderForumLink="" controlPanelLink="http://windows.azure.com" webSystem="WebSites">
        <databases />
    </publishProfile>
</publishData>

それでは、OIDCへ移行して秘匿情報をGitHubシークレットから削除するようにしてみましょう。

Azureの設定

Azure側で必要なのは、おおまかに以下の3つの手順が必要です。

  • テナント(ディレクトリ)へアプリを登録する。
  • 登録したアプリにフェデレーション資格情報を追加し、GitHub Actionsからデプロイできるようにする。
  • サブスクリプションから上記アプリへロールを割り当てる。

エンティティ型に注意してください。
ブランチの指定でも良さそうに見えますが、ここで選択した内容がサブジェクト識別子に設定されます。

先程のワークフローの設定からすると、環境Productionを選択する必要があります。
私はここで1時間ハマりました。

アプリ登録しただけではダメで、ロールの割り当てまで行う必要がありますのでご注意ください。
私はここで1時間ハマりました。

※ここでは所有者権限を付与してしまっていますが、実際はデプロイに必要な最小権限を設定するようにしてください。面倒くさくてサボってしまいました。

設定変更とデプロイ・確認

GitHubシークレットに作成したアプリのクライアントID、テナントIDとロール割り当て元のサブスクリプションIDを登録しておきます。

ワークフローを修正します。
ハイライト部分が追加、またはコメントアウトした部分です。

# Docs for the Azure Web Apps Deploy action: https://github.com/Azure/webapps-deploy
# More GitHub Actions for Azure: https://github.com/Azure/actions

name: Build and deploy ASP.Net Core app to Azure Web App - iwasa20211103aspcore

on:
  push:
    branches:
      - main
  workflow_dispatch:

permissions:
  id-token: write

jobs:
  build:
    runs-on: windows-latest

    steps:
      - uses: actions/checkout@v2

      - name: Set up .NET Core
        uses: actions/setup-dotnet@v1
        with:
          dotnet-version: '5.0.x'
          include-prerelease: true

      - name: Build with dotnet
        run: dotnet build --configuration Release

      - name: dotnet publish
        run: dotnet publish -c Release -o ${{env.DOTNET_ROOT}}/myapp

      - name: Upload artifact for deployment job
        uses: actions/upload-artifact@v2
        with:
          name: .net-app
          path: ${{env.DOTNET_ROOT}}/myapp

  deploy:
    runs-on: windows-latest
    needs: build
    environment:
      name: 'Production'
      url: ${{ steps.deploy-to-webapp.outputs.webapp-url }}

    steps:
      - name: Download artifact from build job
        uses: actions/download-artifact@v2
        with:
          name: .net-app

      - name: Install CLI-beta
        run: |
            cd ../..
            $CWD = Convert-Path .
            echo $CWD
            python --version
            python -m venv oidc-venv
            . .\oidc-venv\Scripts\Activate.ps1
            python -m pip install -q --upgrade pip
            echo "started installing cli beta" 
            pip install -q --extra-index-url https://azcliprod.blob.core.windows.net/beta/simple/ azure-cli
            echo "installed cli beta" 
            echo "$CWD\oidc-venv\Scripts" >> $env:GITHUB_PATH
      - name: Installing Az.accounts for powershell
        shell: pwsh
        run: |
             Install-Module -Name Az.Accounts -Force -AllowClobber -Repository PSGallery
      - name: OIDC Login to Azure Public Cloud with AzPowershell (enableAzPSSession true)
        uses: azure/login@v1.4.0
        with:
          client-id: ${{ secrets.AZURE_CLIENTID }}
          tenant-id: ${{ secrets.AZURE_TENANTID }}
          subscription-id: ${{ secrets.AZURE_SUBSCRIPTIONID }} 
          enable-AzPSSession: true

      - name: Deploy to Azure Web App
        id: deploy-to-webapp
        uses: azure/webapps-deploy@v2
        with:
          app-name: 'iwasa20211103aspcore'
          slot-name: 'Production'
          # publish-profile: ${{ secrets.AZUREAPPSERVICE_PUBLISHPROFILE_B0984B498A96463183F0D36D46AFF106 }}
          package: .

AzureでのOIDCサポートは現在パブリックプレビューのため、サンプルではベータ版のAzure CLIをセットアップしているようです。
また、GovリージョンやAzureStackでは現時点ではまだサポートされていないようですので対応をお待ちください。

また、セットアップコマンドは以下のドキュメントに記載がありますが、ホストマシンがWindowsかLinuxかで内容が異なっているのでその点もご注意ください。

設定が出来たので、 不要な発行プロファイルをGitHubシークレットから削除し、StartUp.csを少し変更してリポジトリを更新してみましょう。

デプロイ成功しました。
Webサイトにアクセスしてみましょう。

やった、更新内容が反映されていますね。
発行プロファイルを使わずにパイプラインを実行することに成功しました。

さいごに

ちなみに、実は最初は Azure Static Web Appsで試していました。
しかし、デプロイにAzure/static-web-apps-deploy@v1を使っており、そこでは入力トークンが必須になっていたので、現時点では利用出来ないか少し違う方法を取る必要がありそうだということがわかりました。
そのうちモジュールが対応されそうな気もします。

azure/webapps-deploy@v2ではうまくいきましたが、もしモジュールが対応していない場合はCLIでどうにか出来るか調べる感じになりそうです。