チュートリアル: Java JBoss EAP on Azure App Service から MySQL データベースに接続する

このチュートリアルでは、マネージド ID を使用して、Azure App Service Java JBoss EAP アプリをAzure Database for MySQL データベースに接続する方法について説明します。 App Service では、管理 ID を使用して、Azure Database for MySQL およびその他のAzure サービスへの安全なアクセスを提供できます。 マネージド ID を使用すると、環境変数の資格情報など、アプリでシークレットを使用する必要がなくなります。

このチュートリアルでは、Azure CLI コマンドを使用して、次のタスクを実行します。

  • Azure Database for MySQL サーバーとデータベースを作成します。
  • WAR パッケージを使用してサンプル JBoss EAP アプリを App Service にデプロイします。
  • MySQL データベースでMicrosoft Entra認証を使用するように Spring Boot Web アプリケーションを構成します。
  • マネージド ID 認証で Service Connector を使用して、Web アプリを MySQL データベースに接続します。

前提条件

  • サービス コネクタをサポートし、このチュートリアルに必要な十分な App Service のサポートとクォータを備えている Azure リージョンにおいて、Microsoft Entra のロール割り当てアクセス許可と Azure リソースの書き込みアクセス許可を持つ Azure サブスクリプション。

  • Azure サブスクリプションに登録されている Microsoft.ServiceLinker および Microsoft.DBforMySQL リソース プロバイダー。 az provider register -n Microsoft.[service] を実行してプロバイダーを登録できます。

  • Git を使用してサンプル リポジトリにアクセスし、複製します。

  • Azure Cloud Shell にアクセスしてチュートリアルの手順を実行するか、ローカルで実行する場合は、次の前提条件と手順を実行します。

    • Java JDK インストールされました

    • Maven がインストールされている

    • jq インストールされました

    • MySQL クライアント がインストールされている

    • Azure CLI 2.46.0 以降がインストールされています。 バージョンを確認するには、 az --versionを実行します。 アップグレードするには、 az upgradeを実行します。

      ローカルで実行している場合:

      1. az login を使用して、プロンプトに従ってAzureにサインインします。
      2. サインイン資格情報に複数のAzure サブスクリプションが接続されている場合は、az account set --subscription <subscription-ID> を実行して適切なサブスクリプションを選択します。

環境を設定する

  1. 次の Azure CLI 拡張機能をインストールします。

    az extension add --name serviceconnector-passwordless --upgrade
    az extension add --name rdbms-connect
    
  2. 次のコマンドを実行して、サンプル リポジトリを複製し、サンプル アプリ プロジェクト フォルダーにディレクトリを変更します。 このフォルダーから残りのすべてのコマンドを実行します。

    git clone https://github.com/Azure-Samples/Passwordless-Connections-for-Java-Apps
    cd Passwordless-Connections-for-Java-Apps/JakartaEE/jboss-eap/
    
  3. チュートリアルの次の環境変数を定義し、 <region> プレースホルダーを有効な値に置き換えます。 LOCATION は、サブスクリプションがAzure リソースを作成するのに十分なクォータを持ち、どのサービスにも制限がないAzureリージョンである必要があります。

    LOCATION="<region>"
    RESOURCE_GROUP="mysql-mi-webapp"
    
  4. Azure リソース グループを作成して、すべてのプロジェクト リソースを格納します。 リソース グループ名はキャッシュされ、後続のコマンドに自動的に適用されます。

    az group create --name $RESOURCE_GROUP --location $LOCATION
    

Azure Database for MySQL の作成

サブスクリプションにAzure Database for MySQL サーバーとデータベースを作成します。 Spring Boot アプリは、このデータベースに接続し、実行時にそのデータを格納し、アプリケーションの実行場所に関係なくアプリケーションの状態を保持します。

  1. 次のコマンドを実行して、Azure Database for MySQL サーバーを作成します。 MYSQL_HOST名は、すべてのAzureで一意である必要があります。

    このコマンドは管理者アカウントを定義しますが、Microsoft Entra管理者アカウントがすべての管理タスクを実行するため、アカウントは使用されません。

    export MYSQL_ADMIN_USER=azureuser
    export MYSQL_ADMIN_PASSWORD="AdminPassword1"
    export RAND_ID=$RANDOM
    export MYSQL_HOST="mysql-mi-$RAND_ID"
    az mysql flexible-server create \
        --name $MYSQL_HOST \
        --resource-group $RESOURCE_GROUP \
        --location $LOCATION \
        --admin-user $MYSQL_ADMIN_USER \
        --admin-password $MYSQL_ADMIN_PASSWORD \
        --public-access 0.0.0.0 \
        --tier Burstable \
        --sku-name Standard_B1ms \
        --storage-size 32
    
  2. アプリケーションで使用する checklist という名前のデータベースを作成します。

    export DATABASE_NAME="checklist"
    az mysql flexible-server db create \
        --resource-group $RESOURCE_GROUP \
        --server-name $MYSQL_HOST \
        --database-name $DATABASE_NAME
    
  3. ファイアウォールを開いて、現在の IP アドレスからデータベースへの接続を許可します。

    # Create a temporary firewall rule to allow connections from your current machine to the MySQL server
    export MY_IP=$(curl http://whatismyip.akamai.com)
    az mysql flexible-server firewall-rule create \
        --resource-group $RESOURCE_GROUP \
        --name $MYSQL_HOST \
        --rule-name AllowCurrentMachineToConnect \
        --start-ip-address ${MY_IP} \
        --end-ip-address ${MY_IP}
    
  4. データベースに接続し、 /azure/init-db.sql サンプル プロジェクト ファイルで指定されているテーブルを作成します。

    export DATABASE_FQDN=${MYSQL_HOST}.mysql.database.azure.com
    export CURRENT_USER=$(az account show --query user.name --output tsv)
    export RDBMS_ACCESS_TOKEN=$(az account get-access-token \
        --resource-type oss-rdbms \
        --output tsv \
        --query accessToken)
    mysql -h "${DATABASE_FQDN}" --user "${CURRENT_USER}" --password="$RDBMS_ACCESS_TOKEN" < azure/init-db.sql
    
  5. 一時的なファイアウォール規則を削除します。

    az mysql flexible-server firewall-rule delete \
        --resource-group $RESOURCE_GROUP \
        --name $MYSQL_HOST \
        --rule-name AllowCurrentMachineToConnect
    

App Service リソースを作成する

Linux 上に App Service JBoss EAP リソースを作成します。 JBoss EAP には Premium sku レベルが必要です。

# Create an App Service plan
export APPSERVICE_PLAN="mysql-mi-plan"
export APPSERVICE_NAME="mysql-mi-app"
az appservice plan create \
    --resource-group $RESOURCE_GROUP \
    --name $APPSERVICE_PLAN \
    --location $LOCATION \
    --sku P1V3 \
    --is-linux

# Create an App Service web app
az webapp create \
    --resource-group $RESOURCE_GROUP \
    --name $APPSERVICE_NAME \
    --plan $APPSERVICE_PLAN \
    --runtime "JBOSSEAP:7-java8"

ユーザー割り当てマネージド ID を作成して構成する

次のコマンドを使用して、Microsoft Entra認証に使用するAzureユーザー割り当てマネージド ID を作成します。 詳細については、「Azure Database for MySQL - フレキシブル サーバーの Microsoft Entra 認証を設定する」を参照してください。

export USER_IDENTITY_NAME="my-user-assigned-identity"
export IDENTITY_RESOURCE_ID=$(az identity create \
    --name $USER_IDENTITY_NAME \
    --resource-group $RESOURCE_GROUP \
    --query id \
    --output tsv)

新しいユーザー割り当てアイデンティティUser.Read.AllGroupMember.Read.All、およびApplication.Read.Allにアクセス許可を付与します。 または、ID に Directory Readers Microsoft Entra 組み込みロールを指定します。

Azure CLIは、Microsoft Entraのアクセス許可またはロールの割り当てにはサポートされていません。 Microsoft Entra 管理センター、PowerShell Microsoft Graph、または Microsoft Graph API を使用して、割り当てを作成できます。 詳細については、「Microsoft Entra ロール割り当てる」を参照してください。

これらの割り当てを追加するには、Microsoft Entra テナントに少なくとも 特権ロール管理者 ロールまたはアクセス許可が必要です。 このロールがない場合は、 グローバル管理者 または 特権ロール管理者 にアクセス許可を付与するよう依頼してください。

マネージド ID を使用してサービスを接続する

Service Connector を使用して、App Service JBoss EAP Web アプリをマネージド ID を使用して MySQL データベースに接続します。 Service Connector はバックグラウンドで次のタスクを実行します。

  • 現在サインインしているユーザーを Microsoft Entra データベース管理者として設定します。
  • アプリのシステム割り当てマネージド ID を有効にします。
  • システム割り当てマネージド ID のデータベース ユーザーを追加し、このユーザーにすべてのデータベース特権を付与します。
  • AZURE_MYSQL_CONNECTIONSTRING という名前の接続文字列をアプリの App Settings に追加します。

次の az webapp connection create コマンドを使用して、マネージド ID を使用してアプリを MySQL データベースに接続します。

az webapp connection create mysql-flexible \
    --resource-group $RESOURCE_GROUP \
    --name $APPSERVICE_NAME \
    --target-resource-group $RESOURCE_GROUP \
    --server $MYSQL_HOST \
    --database $DATABASE_NAME \
    --system-identity mysql-identity-id=$IDENTITY_RESOURCE_ID \
    --client-type java

アプリをビルドしてデプロイする

  1. 次のコードを実行して、生成された 接続文字列 Service Connector にパスワードレス認証プラグインを追加します。 アプリのスタートアップ スクリプトは、この接続文字列を参照します。

    export PASSWORDLESS_URL=$(\
        az webapp config appsettings list \
            --resource-group $RESOURCE_GROUP \
            --name $APPSERVICE_NAME \
        | jq -c '.[] \
        | select ( .name == "AZURE_MYSQL_CONNECTIONSTRING" ) \
        | .value' \
        | sed 's/"//g')
    # Create a new environment variable with the connection string including the passwordless authentication plugin
    export PASSWORDLESS_URL=${PASSWORDLESS_URL}'&defaultAuthenticationPlugin=com.azure.identity.extensions.jdbc.mysql.AzureMysqlAuthenticationPlugin&authenticationPlugins=com.azure.identity.extensions.jdbc.mysql.AzureMysqlAuthenticationPlugin'
    az webapp config appsettings set \
        --resource-group $RESOURCE_GROUP \
        --name $APPSERVICE_NAME \
        --settings "AZURE_MYSQL_CONNECTIONSTRING_PASSWORDLESS=${PASSWORDLESS_URL}"
    
  2. サンプル アプリの pom.xml ファイルを使用してアプリをビルドし、WAR ファイルを生成します。

    mvn clean package -DskipTests
    
  3. WAR ファイルとスタートアップ スクリプトを App Service にデプロイします。

    az webapp deploy \
        --resource-group $RESOURCE_GROUP \
        --name $APPSERVICE_NAME \
        --src-path target/ROOT.war \
        --type war
    az webapp deploy \
        --resource-group $RESOURCE_GROUP \
        --name $APPSERVICE_NAME \
        --src-path src/main/webapp/WEB-INF/createMySQLDataSource.sh \
        --type startup
    

アプリをテストする

  1. 次のコードを実行して、一部のリスト アイテムを含むリストを作成します。

    export WEBAPP_URL=$(az webapp show \
        --resource-group $RESOURCE_GROUP \
        --name $APPSERVICE_NAME \
        --query defaultHostName \
        --output tsv)/$DATABASE_NAME
    
    # Create a list
    curl -X POST -H "Content-Type: application/json" -d '{"name": "list1","date": "2022-03-21T00:00:00","description": "Sample checklist"}' https://${WEBAPP_URL}
    
    # Create few items on the list 1
    curl -X POST -H "Content-Type: application/json" -d '{"description": "item 1"}' https://${WEBAPP_URL}/1/item
    curl -X POST -H "Content-Type: application/json" -d '{"description": "item 2"}' https://${WEBAPP_URL}/1/item
    curl -X POST -H "Content-Type: application/json" -d '{"description": "item 3"}' https://${WEBAPP_URL}/1/item
    
  2. ローカルで作業している場合は、次のコードを実行してアプリを表示します。

    # Get all list items
    curl https://${WEBAPP_URL}
    
    # Get list item 1
    curl https://${WEBAPP_URL}/1
    

    Cloud Shellローカル ブラウザーを開くことができないので、Cloud Shellで作業している場合、Web アプリを表示する最も簡単な方法は、アプリのAzure ポータル ページの上部にある Browse または Default domain リンクを選択することです。 次に、ブラウザーの URL の末尾に /checklist または /checklist/1 を追加します (例: https://mysql-mi-app.azurewebsites.net/checklist)。

リソースをクリーンアップする

このチュートリアルが完了したら、作成したリソースを削除することで、追加の課金を回避できます。 リソース グループを削除して、含まれるすべてのリソースを削除します。 コマンドを実行する前に、リソースが不要になっていることを確認してください。

az group delete --name $RESOURCE_GROUP --no-wait

すべてのリソースが削除されるまでには多少時間がかかります。 --no-wait引数を指定すると、コマンドはすぐに戻ることができます。