SQL Serverを使用して Django アプリを Azure App Service にデプロイする

この記事では、ODBC ドライバーの構成、環境ベースのシークレット、マネージド ID 認証など、mssql-django バックエンドを使用してAzure App Serviceする Django アプリケーションをデプロイする方法について説明します。

前提条件

  • Azure サブスクリプション
  • AzureからアクセスできるAzure SQL DatabaseまたはSQL Server インスタンス
  • mssql-django で設定された Django プロジェクト
  • Azure CLI インストール済み

Azure App Service上の ODBC ドライバー

Azure App Service Linux インスタンスには、Microsoft ODBC Driver for SQL Serverが含まれます。 次のコマンドを実行して、インストールされているドライバーのバージョンを確認できます。

az webapp ssh --resource-group <your-rg> --name <your-app>
odbcinst -j

Note

Azure App Serviceには、通常、Linux プランに ODBC Driver 17 または 18 がプレインストールされています。 Windows アプリ サービス プランには、ODBC ドライバーも含まれています。

シークレットに環境変数を使用する

settings.pyでデータベース資格情報をハードコーディングしないでください。 環境変数を使用し、App Service アプリケーション設定として構成します。

import os

DATABASES = {
    "default": {
        "ENGINE": "mssql",
        "NAME": os.environ.get("DB_NAME", "<your-database>"),
        "USER": os.environ.get("DB_USER", ""),
        "PASSWORD": os.environ.get("DB_PASSWORD", ""),
        "HOST": os.environ.get("DB_HOST", "<your-server>.database.windows.net"),
        "PORT": os.environ.get("DB_PORT", "1433"),
        "OPTIONS": {
            "driver": "ODBC Driver 18 for SQL Server",
        },
    },
}

Tip

DB_NAMEDB_HOSTなどの必要な値については、環境変数が不足している場合にアプリケーションが明確なos.environ["DB_NAME"]ですぐに失敗するように、KeyError (既定値なし) の使用を検討してください。

Azure App Serviceで環境変数を設定します。

az webapp config appsettings set \
    --resource-group <your-rg> \
    --name <your-app> \
    --settings DB_NAME=<your-database> DB_HOST=<your-server>.database.windows.net DB_USER=<your-username> DB_PASSWORD=<your-password>

マネージド ID 認証を使用する

運用環境のデプロイでは、資格情報の格納を回避するためにマネージド ID を使用します。 App Service でシステム割り当てマネージド ID を有効にします。

az webapp identity assign --resource-group <your-rg> --name <your-app>

マネージド ID に Azure SQL データベースへのアクセス権を付与します。

CREATE USER [<your-app-name>] FOR EXTERNAL PROVIDER;

ALTER ROLE db_datareader ADD MEMBER [<your-app-name>];
ALTER ROLE db_datawriter ADD MEMBER [<your-app-name>];
ALTER ROLE db_ddladmin ADD MEMBER [<your-app-name>];

Note

アプリケーションに必要なロールのみを付与します。 db_ddladmin固定データベース ロールは、アプリケーションが移行を実行する場合にのみ必要です。 読み取り専用ワークロードの場合は、 db_datareader で十分です。

サーバーがMicrosoft Entra専用認証用に構成されている場合、サーバーが ID 名を解決するためにMicrosoft Graphに到達できないため、FROM EXTERNAL PROVIDERMsg 33130で失敗します。 CREATE USER [<your-app-name>] WITH SID = 0x<sid-hex>, TYPE = Eを使用してユーザーを手動で作成します。<sid-hex>は、オブジェクト ID ではなく、マネージド ID のアプリケーション (クライアント) ID から派生します。 変換手順については、「Azure SQLで ID アクセスを許可する」を参照してください。

マネージド ID を使用するように settings.py を構成します。

import os

DATABASES = {
    "default": {
        "ENGINE": "mssql",
        "NAME": os.environ.get("DB_NAME", "<your-database>"),
        "HOST": os.environ.get("DB_HOST", "<your-server>.database.windows.net"),
        "PORT": "1433",
        "OPTIONS": {
            "driver": "ODBC Driver 18 for SQL Server",
            "extra_params": "Authentication=ActiveDirectoryMsi",
        },
    },
}

ManagedIdentityCredential でアクセス トークンを使用する

または、azure.identityTOKEN 設定を使用します:

注意事項

TOKEN値はプロセスの起動時に 1 回フェッチされ、60 分から 90 分後に期限切れになります。 実行時間の長い App Service デプロイの場合は、トークン更新ロジックまたは有効期間の短いワーカー リサイクルも実装する場合にのみ、この方法を使用します。 直接 ActiveDirectoryMsi パターンが環境内で動作する場合は、起動時のトークンの問題を回避します。

import os
from azure.identity import ManagedIdentityCredential

credential = ManagedIdentityCredential()
token = credential.get_token("https://database.windows.net/.default").token

DATABASES = {
    "default": {
        "ENGINE": "mssql",
        "NAME": os.environ.get("DB_NAME", "<your-database>"),
        "HOST": os.environ.get("DB_HOST", "<your-server>.database.windows.net"),
        "PORT": "1433",
        "TOKEN": token,
        "OPTIONS": {
            "driver": "ODBC Driver 18 for SQL Server",
        },
    },
}

Tip

DefaultAzureCredentialは、複数の資格情報の種類を自動的に試行するため、開発および共有コードベースに便利です。そのため、ノート PC、CI、および Azure で同じコードが動作します。 ただし、適用されない資格情報の種類ごとに数秒のタイムアウトが追加され、起動速度が低下します。 App Service は常にマネージド ID を使用できるため、 ManagedIdentityCredential はプローブ チェーンなしですぐに認証されます。 要件ファイル (azure-identity) にpip install azure-identityをインストールします。

デプロイ中に移行を実行する

デプロイ後のスクリプトまたはスタートアップ コマンドを追加して、移行を自動的に実行します。

az webapp config set \
    --resource-group <your-rg> \
    --name <your-app> \
    --startup-file "python manage.py migrate && gunicorn myproject.wsgi"

静的ファイルを収集する

運用環境の静的ファイル処理を構成します。

STATIC_URL = "/static/"
STATIC_ROOT = os.path.join(BASE_DIR, "staticfiles")

デプロイの一部として collectstatic を実行します。

python manage.py collectstatic --noinput

App Service にデプロイする

App Service では、次の 2 つの方法で Django アプリをホストできます。

  • 組み込みの Linux Python イメージ: App Service はソースからコードをビルドし、Pythonランタイムを提供します。
  • カスタム Docker イメージ: イメージを自分でビルドし、コンテナー レジストリから参照します。

どちらのパスでも、システム割り当てマネージド ID を使用してAzure SQLに対する認証を行うことができますが、レシピは異なります。 ご利用のデプロイに合ったタブを選択してください。

組み込みの Linux Python イメージを使用すると、App Service の Oryx ビルダーによってrequirements.txtがインストールされ、gunicornの下で Django アプリが自動的に起動されます。 ローカルのマネージド ID HTTP プロキシにより、Authentication=ActiveDirectoryMsi を ODBC 接続文字列から直接使用できるようになります。 settings.py」に示されているを使用します。

az webapp upを使用してコードをデプロイし、システム割り当てマネージド ID を有効にして、データベース環境変数を設定します。

az webapp up \
    --resource-group <your-rg> \
    --name <your-app> \
    --runtime "PYTHON:3.12" \
    --sku B1

az webapp identity assign --resource-group <your-rg> --name <your-app>

az webapp config appsettings set \
    --resource-group <your-rg> \
    --name <your-app> \
    --settings DB_NAME=<your-database> DB_HOST=<your-server>.database.windows.net

次に、「マネージド ID 認証を使用する」の説明に従って、SQL で マネージド ID アクセス権を付与します。

Docker Compose を使用したローカル開発

ローカルでの開発とテストの場合は、Docker Compose を使用して、SQL Server コンテナーと共に Django アプリを実行します。

# docker-compose.yml
services:
  db:
    image: mcr.microsoft.com/mssql/server:2022-latest
    environment:
      ACCEPT_EULA: "Y"
      MSSQL_SA_PASSWORD: "<password>"  # Must meet SQL Server complexity requirements
    ports:
      - "1433:1433"

  web:
    build: .
    ports:
      - "8000:8000"
    environment:
      DB_HOST: db
      DB_NAME: mydb
      DB_USER: sa
      DB_PASSWORD: "<password>"
    depends_on:
      - db

Tip

SQL Server コンテナーは、アプリケーション データベースを自動的に作成しません。 コンテナーを開始した後、データベースを作成し、移行を実行します。

docker compose exec db /opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P "<password>" -No -Q "CREATE DATABASE mydb"
docker compose exec web python manage.py migrate

SQL Server コンテナー イメージには、ACCEPT_EULA=Yと強力な SA パスワードが必要です。 運用環境では、SQL Server の資格情報ではなく、マネージド ID を使用して Azure SQL Database を使用します。 「マネージド ID 認証を使用する」を参照してください。