記事内に広告が含まれています

GitHub ActionsでC#アプリをAzure App Serviceに自動デプロイする方法

GitHub ActionsでC#アプリをAzure App Serviceに自動デプロイする方法 開発環境

Azure App Serviceは、C#やASP.NET Coreアプリを簡単に公開できるPaaSです。

Visual Studioを使えば手動で発行することもできますが、実務ではGitHubにソースコードをプッシュした時点で自動的にデプロイされる仕組みを整えておくのが理想です。

この記事では、Visual StudioからGitHubにリポジトリを作成 → Azure App Serviceに接続 → GitHub Actionsで自動デプロイ という流れを解説します。

※手動デプロイを試したい方はこちらの記事をご覧ください:
Visual StudioでC#アプリをAzure App Serviceに手動デプロイする

前提

C# Webアプリを作成する

Visual Studioを開き、テンプレートから「ASP.NET Core Webアプリ」を選んで新しいプロジェクトを作成します。

※「ASP.NET Core Webアプリ (Model-View-Controller)」「ASP.NET Core Web API」「Blazor Webアプリ」などでも問題ありません。

任意のプロジェクト名を入力後(今回はMyWebAppとしています)、.NETのバージョンを確認して作成をクリックします。

GitHubにリポジトリを作成する

作成したプロジェクトをGitHubにプッシュします。

Visual Studioの右下の [Git変更]タブ(または上部メニューの [表示] → [Git変更])を開き、[Gitリポジトリの作成] を選択します。

表示範囲を「public」にして、「作成とプッシュ」をクリックします。
(今回の内容であればprivateでも問題ないですが、publicの場合はGitHub Actionsが完全無料なので、学習用であれば public を選んでおくのがおすすめです)

自動的にGitHubリポジトリが作成され、ソースコードがプッシュされます。

Azure App Serviceを作成する

次に、Azure ポータルから Web アプリ(App Service)を新規作成します。

Azure ポータルにサインインし、左メニューから「App Services」をクリックします。

左上の「作成」から「Webアプリ」を選択します。

「基本」タブで以下の情報を入力します。

  • サブスクリプション:対象のサブスクリプションを選択
  • リソース グループ:関連リソースをまとめるフォルダのようなもの。既存がなければ新規作成をクリックして作成してください
  • 名前:アプリの識別子。世界で一意である必要があります。後から変更することはできません(例:myapp-<任意文字列>
    • 「安全な一意の既定のホスト名」のトグルはONのままで大丈夫です(サブドメイン乗っ取り対策を強化する設定)
  • 公開:コード を選択
  • ランタイム スタック:.NET 8 (LTS) を選択
  • オペレーティング システム:Linux を選択(ASP.NET Core なら推奨。Windows でも可)
  • リージョン:Japan East または Japan West を選択

App Service プランを設定します。

  • Linuxプラン:「新規作成」から、わかりやすい名前(例:asp-myapp-dev)を付けます。
    • プラン名も後から変更できないため、命名規則を決めておくと管理が楽です。
  • 価格レベル:今回は学習用なので Free(F1) を選択します。
    • Freeプラン(F1) は、1つのリージョンに1つしか作れません。
    • Freeプランは 共有コンピューター上で動作するため、アプリの起動が遅くなったり、同時アクセス数や処理速度に制限があります。(学習用なら問題なし)

入力できたら、「確認および作成」をクリックします。

「作成」 をクリックするとApp Serviceのデプロイが開始します。

デプロイが完了したら [リソースに移動] をクリックします。

デプロイ センターで GitHub Actions を接続する

作成したApp Serviceのデプロイセンターを開きます。

「ソース」で「GitHub」を選択後、GitHubの「認可」をクリックします。

別ウィンドウでApp ServiceにGitHubを許可するかが聞かれるので、「Authorize AzureAppService」をクリックします。

その後ログイン画面が表示された場合は、GitHubのパスワードでログインしてください。

認可に成功すると、GitHubの組織やリポジトリが選べるようになるので、以下を設定してください。

  • 組織:個人ならGitHubアカウント名
  • リポジトリ:先ほど作成したリポジトリを選択
  • ブランチ:自動デプロイしたいブランチを選択(例:master / main)
  • ワークフローオプション:ワークフローの追加 を選択(選択したリポジトリにyamlファイルが自動生成されます)

また、認証の設定では「ユーザー割り当てID」を選択します。
このIDはAzureが自動で作成してくれるので、デフォルトのままで問題ありません。

このユーザー割り当てID は、GitHub Actions と Azure を安全につなぐためのカギのような役割を持っています。
内部では OpenID Connect(OIDC)という仕組みが使われており、どのリポジトリからの実行なのかをAzureが確認できるようになります。

仕組みそのものについては、最後のセクションで詳しく説明します。

設定が終わったら、上部の「保存」をクリックしてください。

選択したGitHubリポジトリにワークフローファイル(.yml)が自動で生成され、初回のワークフローが起動します。

自動生成されたワークフローを確認する

まず、GitHub リポジトリの[Actions]タブを開いてみましょう。
App Service と連携設定すると、自動的にワークフローが生成され、すぐに実行が始まります。

build → deploy の順に進み、緑のチェックマークが付けばデプロイ成功です。

ワークフローが成功したら、実際にアプリが公開されているかを確認してみましょう。
App Serviceの概要画面で「既定のドメイン」のリンクをクリックします。

以下のような画面が表示されればデプロイは成功しています。(初回は表示に時間がかかります)

自動生成されたワークフローファイルも確認します。
.github/workflows/<名前>.yml に保存されています。

以下は、自動生成されたファイルに初心者向けのコメントを追記した例です。
何をしているかを理解しておくと、後で自分のプロジェクトに合わせて修正しやすくなります。

# ワークフローの表示名(Actions画面に表示される)
name: Build and deploy ASP.Net Core app to Azure Web App - your-webapp-name

# いつ動かすか(トリガー)
on:
  push: # ブランチにプッシュされたとき
    branches:
      - master
  workflow_dispatch: # 手動実行時

# 実行する処理のまとまり(ジョブ)。ここでは build → deploy の2段階
jobs:
  # ① ビルド:アプリをコンパイルして成果物を作る
  build:
    # 実行マシン(Ubuntu最新版)
    runs-on: ubuntu-latest
    # リポジトリ読み取りなどの最低限の権限を付与
    permissions:
      contents: read # actions/checkout がリポジトリを読むために必要

    steps:
      # リポジトリのソースコードをワークフロー用の仮想マシンにチェックアウト
      - uses: actions/checkout@v4

      # .NET SDK をセットアップ
      - name: Set up .NET Core
        uses: actions/setup-dotnet@v4
        with:
          dotnet-version: '8.x'
      
      # Release 構成でビルド
      - name: Build with dotnet
        run: dotnet build --configuration Release
     
      # 実行に必要なファイルを1つのフォルダに出力
      - name: dotnet publish
        run: dotnet publish -c Release -o ${{env.DOTNET_ROOT}}/myapp

      # 後続の deploy ジョブに受け渡すため、発行フォルダを「アーティファクト」として一時保存
      - name: Upload artifact for deployment job
        uses: actions/upload-artifact@v4
        with:
          name: .net-app
          path: ${{env.DOTNET_ROOT}}/myapp

# ② デプロイ:build ジョブの成果物を取得してAzure App Service に配置
  deploy:
    # 実行マシン(Ubuntu最新版)
    runs-on: ubuntu-latest
    needs: build # build ジョブが成功したら実行
    permissions:
      id-token: write # Azure に OIDC でログインするために必要
      contents: read # actions/checkout がリポジトリを読むために必要

    steps:
      # build ジョブでアップロードした「アーティファクト」をダウンロード
      - name: Download artifact from build job
        uses: actions/download-artifact@v4
        with:
          name: .net-app
      
      # Azure にサインイン(OIDC)
      - name: Login to Azure
        uses: azure/login@v2
        with:
          # GitHub 側に自動登録された変数(Secrets)を参照
          # client-id / tenant-id / subscription-id は OIDC 用の識別子
          client-id: ${{ secrets.AZUREAPPSERVICE_CLIENTID_xxx }}
          tenant-id: ${{ secrets.AZUREAPPSERVICE_TENANTID_xxx }}
          subscription-id: ${{ secrets.AZUREAPPSERVICE_SUBSCRIPTIONID_xxx }}

      # App Service に成果物をデプロイ
      - name: Deploy to Azure Web App
        id: deploy-to-webapp
        uses: azure/webapps-deploy@v3
        with:
          app-name: 'your-webapp-name'
          slot-name: 'Production' # スロット(既定は Production)
          package: .              # 直前に展開したアーティファクトの中身を配置

押さえておきたいポイントは以下です。

  • on: push / workflow_dispatch
    • push → 指定ブランチ(今回はmaster)にコードをプッシュするとワークフローが動く
    • workflow_dispatch → GitHub Actions 画面からの手動実行も可能
  • build ジョブ
    • actions/checkout → リポジトリのソースコードを取得
    • actions/setup-dotnet → .NET SDK をセットアップ(今回は 8.x)
    • dotnet build → コードをビルド
    • dotnet publish → 実行に必要なファイルを1つのフォルダにまとめる
    • actions/upload-artifact → publish で作ったフォルダをアーティファクトとして一時保管
      • アーティファクトとは、ワークフロー内で生成したファイルを GitHub のストレージに一時保存できる仕組み
      • ジョブごとに新しい仮想マシンが起動するので、ジョブ内で生成したファイルを後続ジョブに渡す際は、アーティファクトを介して受け渡す必要がある
  • deploy ジョブ
    • actions/download-artifact → build ジョブで保存したアーティファクトをダウンロード
    • azure/login → GitHub Actions からAzure にサインイン ※詳細は次のセクションで解説
    • azure/webapps-deploy → App Service に成果物を配置

ここまでで、C#アプリをApp Serviceに自動デプロイする方法の説明は終わりですが、GitHub ActionsとAzureにどのようにサインインしているのかを仕組みが気になる方は、ぜひ次のセクションを参照してください。

(補足)GitHub Actions と Azure が OIDC で連携する仕組み

ここからは、GitHub Actions と Azure が OpenID Connect (OIDC) を使って連携する仕組みを説明します。

OIDC とは、広く使われている 認証の仕組みで、以下のような特徴があります。

  • 誰がアクセスしているのかを IDトークン という証明書で確認できる
  • パスワードを渡さなくても、安全に認証情報をやり取りできる

GitHub が発行した身分証明書(IDトークン)を Azure が確認して、「確かに正しいGitHubリポジトリから来た実行だ」と信頼する仕組みです。

登場人物の整理

まず、OIDC を使った GitHub Actions と Azure の連携で登場する人物を整理します。

  • エンドユーザー GitHub Actions ワークフロー
    通常のWebログインであれば「人間のユーザー」ですが、GitHub Actions の場合は 特定のリポジトリやブランチで実行されるワークフローがエンドユーザーの役割を担う
  • OpenIDプロバイダ (OP)GitHub
    GitHub Actions のワークフローが本物であることを証明するための IDトークン を発行する
  • リライング・パーティ (RP)Azure (Entra ID)
    GitHub が発行した ID トークンを受け取り、その内容が正しいかを検証する。
    信頼できると判断した場合に、Azure リソースにアクセスするための アクセストークン を発行する
  • リソースサーバーAzure の各種リソース(App Serviceなど)
    Azure が発行したアクセストークンを持つ GitHub Actions のジョブだけが、これらのリソースにアクセスできる

OIDC認証の流れ

GitHub ActionsとAzure間でのOIDC認証の流れを説明します。

1. 連携の準備(GitHub Actions)

デプロイ センターのセットアップ後、対象のGitHub リポジトリには以下のキー(シークレットではなく識別子)が自動登録されます。

  • AZUREAPPSERVICE_CLIENTID(Azure 側 ID の Client ID)
  • AZUREAPPSERVICE_SUBSCRIPTIONID(サブスクリプション ID)
  • AZUREAPPSERVICE_TENANTID(テナント ID)

これらのキーは、GitHub ActionsワークフローがAzureにログインする際に使用されます。

対象のリポジトリの Settings を開き、 Secrets and variables → Actionsから確認することができます。

2. ID トークンの発行(GitHub 側)

まずGitHub Actionsワークフローは、GitHubから「ジョブが本物である」ことを証明した身分証(=IDトークン)を受け取り、Azureに渡します。

azure/login@v2 ステップが実行されると、ここで初めて OIDC のリクエストが発生します。内部的には次の処理が行われます。

  1. ワークフローのazure/login@v2 ステップに到達すると、GitHub Actions のランナーが一時変数を使って GitHub OIDC Provider (https://token.actions.githubusercontent.com) にリクエストを送り、IDトークン (JWT) を取得する
    permissions: id-token: write によって、ワークフローはIDトークンを発行リクエストできる権限を持っている
  2. 取得したIDトークンとGitHubリポジトリに自動登録された変数を Azure のトークンエンドポイント に送信する
  # Azure にサインイン(OIDC)
  - name: Login to Azure
    uses: azure/login@v2
    with:
      # GitHub 側に自動登録された変数(Secrets)を参照
      # client-id / tenant-id / subscription-id は OIDC 用の識別子
      client-id: ${{ secrets.AZUREAPPSERVICE_CLIENTID_xxx }}
      tenant-id: ${{ secrets.AZUREAPPSERVICE_TENANTID_xxx }}
      subscription-id: ${{ secrets.AZUREAPPSERVICE_SUBSCRIPTIONID_xxx }}

3. Azure 側での検証

Azure側では、連携時に自動作成された「ユーザー割り当てマネージドID」に、「フェデレーション資格情報」が設定されています。

ここでは、発行者(=外部IDプロバイダーを特定する情報)やサブジェクト識別子(どの GitHub リポジトリ/ブランチからのリクエストを受け入れるか)などが定義されています。

Azureは、GitHub Actionsワークフローから渡されたIDトークンに対して、以下の検証を行います。

  • 発行者 (iss) が GitHub であるか
  • リポジトリ/ブランチ (sub) が許可されたものであるか
  • 宛先 (aud) が Azure 用になっているか

さらに、GitHub の公開鍵を使って署名が正しいことを確認します。

4. アクセストークンの発行(Azure 側)

検証に成功し証明書の真正性が確認できたら、Azure Entra ID が一時的なアクセストークンを発行します。

このアクセストークンには、App Service にデプロイできる権限(Web サイト共同作成者)が含まれています。

アクセストークンにどのような権限(ロール)が割り当てられるかは、App ServiceのIAMで確認できます。ユーザー割り当てマネージドID(サービスプリンシパル)に事前に割り当てられています。

5. Azure リソースへのアクセス(App Service)

最後に、GitHub Actions のジョブがそのアクセストークンを使って App Service にアクセスし、デプロイを実行します。

この仕組みにより、Secrets に長期的なパスワードを保存せずに安全にデプロイできます。

まとめ

今回は、GitHub Actions を使って、C# アプリを Azure App Service に自動デプロイする方法 を解説しました。

押さえておきたいポイントは次のとおりです。

  • Azureポータル上 から直接GitHubと連携してワークフローを作成できる
  • 学習用であれば public リポジトリを選べば GitHub Actions が無料 で利用できる
  • GitHub ActionsとAzureはOpen ID Connectの仕組みを使ってセキュアに連携できる

自動デプロイを整えることで、手動発行の手間やミスをなくし、継続的デリバリー(CD)の第一歩 を踏み出せます。

コメント

タイトルとURLをコピーしました