Esercitazione: Connettersi al database PostgreSQL da un'applicazione contenitore Java Quarkus senza segreti tramite un'identità gestita
App contenitore di Azure offre un'identità gestita per l'app, una soluzione chiavi in mano per proteggere l'accesso a Database di Azure per PostgreSQL e ad altri servizi di Azure. Le identità gestite nelle App contenitore rendono l'app più sicura eliminando i segreti dall'app, ad esempio le credenziali nelle variabili di ambiente.
Questa esercitazione illustra il processo di creazione, configurazione, distribuzione e ridimensionamento di app contenitore Java in Azure. Alla fine di questa esercitazione si avrà un'applicazione Quarkus che archivia i dati in un database PostgreSQL con un'identità gestita in esecuzione in App contenitore.
Contenuto dell'esercitazione:
- Configurare un'app Quarkus per l'autenticazione usando Microsoft Entra ID con un database PostgreSQL.
- Creare un registro Azure Container ed eseguire il push di un'immagine dell'app Java in esso.
- Creare un'app contenitore in Azure.
- Creare un database PostgreSQL in Azure.
- Connettersi al database PostgreSQL con identità gestita tramite la funzionalità Connettore servizio.
Se non si ha una sottoscrizione di Azure, creare un account Azure gratuito prima di iniziare.
1. Prerequisiti
- Interfaccia della riga di comando di Azure versione 2.45.0 o successiva.
- Git
- Java JDK
- Maven
- Docker
2. Creare un registro contenitori
Creare un gruppo di risorse con il comando az group create. Un gruppo di risorse di Azure è un contenitore logico in cui le risorse di Azure vengono distribuite e gestite.
L'esempio seguente crea un gruppo di risorse nell'area di Azure denominata myResourceGroup
nell'area di Azure Stati Uniti orientali.
RESOURCE_GROUP="myResourceGroup"
LOCATION="eastus"
az group create --name $RESOURCE_GROUP --location $LOCATION
Creare un'istanza del Registro Azure Container usando il comando az acr create e recuperarne il server di accesso usando il comando az acr show . Il nome del registro deve essere univoco in Azure e contenere da 5 a 50 caratteri alfanumerici. Tutte le lettere devono essere specificate in minuscolo. Il seguente esempio usa mycontainerregistry007
. Aggiornarlo a un valore univoco.
REGISTRY_NAME=mycontainerregistry007
az acr create \
--resource-group $RESOURCE_GROUP \
--name $REGISTRY_NAME \
--sku Basic
REGISTRY_SERVER=$(az acr show \
--name $REGISTRY_NAME \
--query 'loginServer' \
--output tsv | tr -d '\r')
3. Clonare l'app di esempio e preparare l'immagine del contenitore
In questa esercitazione viene usata un'app elenco Frutta di esempio con un'interfaccia utente Web che chiama un'API REST Quarkus supportata da Database di Azure per PostgreSQL. Il codice per l'app è disponibile in GitHub. Per altre informazioni sulla scrittura di app Java con Quarkus e PostgreSQL, vedere la Guida a Quarkus Hibernate ORM con Panache e la Guida a Quarkus Datasource.
Eseguire i comandi seguenti nel terminale per clonare il repository di esempio e configurare l'ambiente dell'app di esempio.
git clone https://github.com/quarkusio/quarkus-quickstarts
cd quarkus-quickstarts/hibernate-orm-panache-quickstart
Modificare il progetto
Aggiungere le dipendenze necessarie al file BOM del progetto.
<dependency> <groupId>com.azure</groupId> <artifactId>azure-identity-extensions</artifactId> <version>1.1.20</version> </dependency>
Configurare le proprietà dell'app Quarkus.
La configurazione di Quarkus si trova nel file src/main/resources/application.properties. Aprire questo file nell'editor e osservare diverse proprietà predefinite. Le proprietà precedute da
%prod
vengono usate solo quando l'applicazione viene compilata e distribuita, ad esempio quando viene distribuita nel servizio app di Azure. Quando l'applicazione viene eseguita in locale, le proprietà%prod
vengono ignorate. Analogamente, le proprietà%dev
vengono usate nella modalità live coding/sviluppo di Quarkus e le proprietà%test
vengono usate durante i test continui.Eliminare il contenuto esistente in application.properties e sostituire con quanto segue per configurare il database per le modalità di sviluppo, test e produzione:
quarkus.hibernate-orm.database.generation=drop-and-create quarkus.datasource.db-kind=postgresql quarkus.datasource.jdbc.max-size=8 quarkus.datasource.jdbc.min-size=2 quarkus.hibernate-orm.log.sql=true quarkus.hibernate-orm.sql-load-script=import.sql quarkus.datasource.jdbc.acquisition-timeout = 10 %dev.quarkus.datasource.username=${CURRENT_USERNAME} %dev.quarkus.datasource.jdbc.url=jdbc:postgresql://${AZURE_POSTGRESQL_HOST}:${AZURE_POSTGRESQL_PORT}/${AZURE_POSTGRESQL_DATABASE}?\ authenticationPluginClassName=com.azure.identity.extensions.jdbc.postgresql.AzurePostgresqlAuthenticationPlugin\ &sslmode=require %prod.quarkus.datasource.username=${AZURE_POSTGRESQL_USERNAME} %prod.quarkus.datasource.jdbc.url=jdbc:postgresql://${AZURE_POSTGRESQL_HOST}:${AZURE_POSTGRESQL_PORT}/${AZURE_POSTGRESQL_DATABASE}?\ authenticationPluginClassName=com.azure.identity.extensions.jdbc.postgresql.AzurePostgresqlAuthenticationPlugin\ &sslmode=require %dev.quarkus.class-loading.parent-first-artifacts=com.azure:azure-core::jar,\ com.azure:azure-core-http-netty::jar,\ io.projectreactor.netty:reactor-netty-core::jar,\ io.projectreactor.netty:reactor-netty-http::jar,\ io.netty:netty-resolver-dns::jar,\ io.netty:netty-codec::jar,\ io.netty:netty-codec-http::jar,\ io.netty:netty-codec-http2::jar,\ io.netty:netty-handler::jar,\ io.netty:netty-resolver::jar,\ io.netty:netty-common::jar,\ io.netty:netty-transport::jar,\ io.netty:netty-buffer::jar,\ com.azure:azure-identity::jar,\ com.azure:azure-identity-extensions::jar,\ com.fasterxml.jackson.core:jackson-core::jar,\ com.fasterxml.jackson.core:jackson-annotations::jar,\ com.fasterxml.jackson.core:jackson-databind::jar,\ com.fasterxml.jackson.dataformat:jackson-dataformat-xml::jar,\ com.fasterxml.jackson.datatype:jackson-datatype-jsr310::jar,\ org.reactivestreams:reactive-streams::jar,\ io.projectreactor:reactor-core::jar,\ com.microsoft.azure:msal4j::jar,\ com.microsoft.azure:msal4j-persistence-extension::jar,\ org.codehaus.woodstox:stax2-api::jar,\ com.fasterxml.woodstox:woodstox-core::jar,\ com.nimbusds:oauth2-oidc-sdk::jar,\ com.nimbusds:content-type::jar,\ com.nimbusds:nimbus-jose-jwt::jar,\ net.minidev:json-smart::jar,\ net.minidev:accessors-smart::jar,\ io.netty:netty-transport-native-unix-common::jar,\ net.java.dev.jna:jna::jar
Compilare ed eseguire il push di un'immagine Docker nel registro contenitori
Compilare l'immagine del contenitore.
Eseguire il comando seguente per compilare l'immagine dell'app Quarkus. È necessario contrassegnarlo con il nome completo del server di accesso del Registro di sistema.
CONTAINER_IMAGE=${REGISTRY_SERVER}/quarkus-postgres-passwordless-app:v1 mvn quarkus:add-extension -Dextensions="container-image-jib" mvn clean package -Dquarkus.container-image.build=true -Dquarkus.container-image.image=${CONTAINER_IMAGE}
Accedere al Registro di sistema.
Prima di eseguire il push delle immagini del contenitore, è necessario accedere al registro. A tale scopo, usare il comando [az acr login][az-acr-login].
az acr login --name $REGISTRY_NAME
Il comando restituisce un messaggio
Login Succeeded
al termine dell'esecuzione.Eseguire il push dell'immagine nel registro.
Usare [docker push][docker-push] per eseguire il push dell'immagine nell'istanza del Registro di sistema. Questo esempio crea il repository
quarkus-postgres-passwordless-app
che contiene l'immaginequarkus-postgres-passwordless-app:v1
.docker push $CONTAINER_IMAGE
4. Creare un'app contenitore in Azure
Creare un'istanza di App contenitore eseguendo il comando seguente. Assicurarsi di sostituire il valore delle variabili di ambiente con il nome e la posizione effettivi da usare.
CONTAINERAPPS_ENVIRONMENT="my-environment" az containerapp env create \ --resource-group $RESOURCE_GROUP \ --name $CONTAINERAPPS_ENVIRONMENT \ --location $LOCATION
Creare un'app contenitore con l'immagine dell'app eseguendo il comando seguente:
APP_NAME=my-container-app az containerapp create \ --resource-group $RESOURCE_GROUP \ --name $APP_NAME \ --image $CONTAINER_IMAGE \ --environment $CONTAINERAPPS_ENVIRONMENT \ --registry-server $REGISTRY_SERVER \ --registry-identity system \ --ingress 'external' \ --target-port 8080 \ --min-replicas 1
Nota
Le opzioni
--registry-username
e--registry-password
sono ancora supportate, ma non sono consigliate perché l'uso del sistema di identità è più sicuro.
5. Creare e connettere un database PostgreSQL con connettività di identità
Creare quindi un database PostgreSQL e configurare l'app contenitore per connettersi a un database PostgreSQL con un'identità gestita assegnata dal sistema. L'app Quarkus si connetterà a questo database e archivierà i propri dati durante l'esecuzione, rendendo persistente lo stato dell'applicazione indipendentemente dalla posizione in cui viene eseguita.
Creare il servizio del database.
DB_SERVER_NAME='msdocs-quarkus-postgres-webapp-db' az postgres flexible-server create \ --resource-group $RESOURCE_GROUP \ --name $DB_SERVER_NAME \ --location $LOCATION \ --public-access None \ --sku-name Standard_B1ms \ --tier Burstable \ --active-directory-auth Enabled
Nota
Le opzioni
--admin-user
e--admin-password
sono ancora supportate, ma non sono consigliate perché l'uso del sistema di identità è più sicuro.I parametri seguenti vengono usati nel comando dell'interfaccia della riga di comando di Azure precedente:
- gruppo di risorse → Usare lo stesso nome del gruppo di risorse in cui è stata creata l'app Web,
msdocs-quarkus-postgres-webapp-rg
ad esempio . - nome → il nome del server di database PostgreSQL. Questo nome deve essere univoco in tutti gli ambienti di Azure (l'endpoint server diventa
https://<name>.postgres.database.azure.com
). I caratteri consentiti sonoA
-Z
,0
-9
e-
. Un criterio valido consiste nell'usare una combinazione del nome della società e di un identificatore del server. (msdocs-quarkus-postgres-webapp-db
) - posizione → Usare la stessa posizione usata per l'app Web. Se non funziona, passare a una posizione diversa.
- public-access →
None
che imposta il server in modalità di accesso pubblico senza regole del firewall. Le regole verranno create in un passaggio successivo. - sku-name → Il nome del piano tariffario e della configurazione di calcolo,
Standard_B1ms
ad esempio . Per altre informazioni, vedere Piano tariffario di Database di Azure per PostgreSQL. - livello → il livello di calcolo del server. Per altre informazioni, vedere Piano tariffario di Database di Azure per PostgreSQL.
- active-directory-auth →
Enabled
per abilitare l'autenticazione di Microsoft Entra.
- gruppo di risorse → Usare lo stesso nome del gruppo di risorse in cui è stata creata l'app Web,
Creare un database denominato
fruits
all'interno del servizio PostgreSQL con questo comando:DB_NAME=fruits az postgres flexible-server db create \ --resource-group $RESOURCE_GROUP \ --server-name $DB_SERVER_NAME \ --database-name $DB_NAME
Installare l'estensione senza password Connettore di servizi per l'interfaccia della riga di comando di Azure:
az extension add --name serviceconnector-passwordless --upgrade --allow-preview true
Connettere il database all'app contenitore con un'identità gestita assegnata dal sistema usando il comando di connessione.
az containerapp connection create postgres-flexible \ --resource-group $RESOURCE_GROUP \ --name $APP_NAME \ --target-resource-group $RESOURCE_GROUP \ --server $DB_SERVER_NAME \ --database $DB_NAME \ --system-identity \ --container $APP_NAME
6. Esaminare le modifiche
È possibile trovare l'URL dell'applicazione (FQDN) usando il comando seguente:
echo https://$(az containerapp show \
--name $APP_NAME \
--resource-group $RESOURCE_GROUP \
--query properties.configuration.ingress.fqdn \
--output tsv)
Quando nella nuova pagina Web viene visualizzato l'elenco di frutti, l'app si connette al database con l'identità gestita. Dovrebbe ora essere possibile modificare l'elenco di frutta come in precedenza.
Pulire le risorse
Nei passaggi precedenti sono state create risorse di Azure in un gruppo di risorse. Se si ritiene che queste risorse non saranno necessarie in futuro, eliminare il gruppo di risorse eseguendo questo comando in Cloud Shell:
az group delete --name myResourceGroup
L'esecuzione del comando può richiedere un minuto.
Passaggi successivi
Altre informazioni sull'esecuzione di app Java in Azure sono disponibili nella guida per sviluppatori.