Tutorial: Conexión a la base de datos PostgreSQL desde una aplicación contenedora de Java Quarkus sin secretos mediante una identidad administrada
Azure Container Apps proporciona una identidad administrada para la aplicación, la cual constituye una solución inmediata para proteger el acceso a Azure Database for PostgreSQL y a otros servicios de Azure. Las identidades administradas de Container Apps hacen que su aplicación sea más segura mediante la eliminación de los secretos de aplicación como, por ejemplo, las credenciales de las variables de entorno.
Este tutorial lo guiará en el proceso de compilación, configuración, implementación y escalado de aplicaciones de contenedor de Java en Azure. Al final de este tutorial, tendrá una aplicación de Quarkus que almacena datos en una base de datos PostgreSQL con una identidad administrada que se ejecuta en Container Apps.
Lo qué aprenderá:
- Configure una aplicación de Quarkus para autenticarse mediante Microsoft Entra ID con una base de datos PostgreSQL.
- Creación de un registro de contenedor de Azure e inserción de una imagen de aplicación de Java.
- Creación de una aplicación de contenedor en Azure.
- Creación de una base de datos PostgreSQL en Azure.
- Conexión a una base de datos PostgreSQL con una identidad administrada mediante el conector de servicio.
Si no tiene una suscripción a Azure, cree una cuenta gratuita de Azure antes de empezar.
1. Prerrequisitos
2. Creación de un registro de contenedor
Para crear un grupo de recursos, use el comando az group create. Un grupo de recursos de Azure es un contenedor lógico en el que se implementan y se administran los recursos de Azure.
En el siguiente ejemplo se crea un grupo de recursos llamado myResourceGroup
en la región de Azure Este de EE. UU.
az group create --name myResourceGroup --location eastus
Cree una instancia de registro de contenedor de Azure con el comando az acr create. El nombre del registro debe ser único en Azure y contener entre 5 y 50 caracteres alfanuméricos. Todas las letras deben especificarse en minúsculas. En el ejemplo siguiente se usa mycontainerregistry007
. Actualice este valor a uno único.
az acr create \
--resource-group myResourceGroup \
--name mycontainerregistry007 \
--sku Basic
3. Clonación de la aplicación de ejemplo y preparación de la imagen de contenedor
En este tutorial se usa una aplicación de lista de Fruits de ejemplo con una interfaz de usuario web que llama a una API REST de Quarkus con el respaldo de Azure Database for PostgreSQL. El código de la aplicación está disponible en GitHub. Para obtener más información sobre cómo escribir aplicaciones Java con Quarkus y PostgreSQL, consulte la Guía ORM de hibernación de Quarkus con Panache y la guía de orígenes de datos de Quarkus.
Ejecute los comandos siguientes en su terminal para clonar el repositorio de ejemplo y configurar el entorno de aplicación de ejemplo.
git clone https://github.com/quarkusio/quarkus-quickstarts
cd quarkus-quickstarts/hibernate-orm-panache-quickstart
Modificación del proyecto
Agregue las dependencias necesarias al archivo BOM del proyecto.
<dependency> <groupId>com.azure</groupId> <artifactId>azure-identity-providers-jdbc-postgresql</artifactId> <version>1.0.0-beta.1</version> </dependency>
Configuración de las propiedades de la aplicación Quarkus.
La configuración de Quarkus se encuentra en el archivo src/main/resources/application.properties. Abra este archivo en el editor y observe varias propiedades predeterminadas. Las propiedades que tienen
%prod
como prefijo solo se usan cuando la aplicación se compila e implementa, por ejemplo, cuando se implementa en Azure App Service. Cuando la aplicación se ejecuta localmente, se omiten las propiedades%prod
. De forma similar, las propiedades%dev
se usan en el modo de codificación y desarrollo en directo de Quarkus, y las propiedades%test
se usan durante las pruebas continuas.Elimine el contenido existente en application.properties y reemplácelo por lo siguiente para configurar la base de datos para los modos de desarrollo, prueba y producción:
quarkus.package.type=uber-jar 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=${AZURE_CLIENT_NAME} %dev.quarkus.datasource.jdbc.url=jdbc:postgresql://${DBHOST}.postgres.database.azure.com:5432/${DBNAME}?\ authenticationPluginClassName=com.azure.identity.providers.postgresql.AzureIdentityPostgresqlAuthenticationPlugin\ &sslmode=require\ &azure.clientId=${AZURE_CLIENT_ID}\ &azure.clientSecret=${AZURE_CLIENT_SECRET}\ &azure.tenantId=${AZURE_TENANT_ID} %prod.quarkus.datasource.username=${AZURE_MI_NAME} %prod.quarkus.datasource.jdbc.url=jdbc:postgresql://${DBHOST}.postgres.database.azure.com:5432/${DBNAME}?\ authenticationPluginClassName=com.azure.identity.providers.postgresql.AzureIdentityPostgresqlAuthenticationPlugin\ &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-providers-core::jar,\ com.azure:azure-identity-providers-jdbc-postgresql::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
Compilación e inserción de la imagen de Docker en el registro de contenedor
Compile la imagen de contenedor.
Ejecute el siguiente comando para compilar la imagen de aplicación Quarkus. Debe etiquetarla con el nombre completo del servidor de inicio de sesión del registro. El nombre del servidor de inicio de sesión tiene el formato <nombre-de-registro>.azurecr.io (debe estar todo en minúscula); por ejemplo, mycontainerregistry007.azurecr.io. Reemplace el nombre por su propio nombre del registro.
mvnw quarkus:add-extension -Dextensions="container-image-jib" mvnw clean package -Pnative -Dquarkus.native.container-build=true -Dquarkus.container-image.build=true -Dquarkus.container-image.registry=mycontainerregistry007 -Dquarkus.container-image.name=quarkus-postgres-passwordless-app -Dquarkus.container-image.tag=v1
Inicie sesión en el registro.
Antes de insertar imágenes de contenedor, debe iniciar sesión en el registro. Para ello, utilice el comando [az acr login][az-acr-login]. Especifique solo el nombre del recurso de registro al iniciar sesión con la CLI de Azure. No use el nombre completo del servidor de inicio de sesión.
az acr login --name <registry-name>
El comando devolverá un mensaje
Login Succeeded
una vez completado.Inserte la imagen en el registro.
Use el comando [docker push][docker-push] para insertar la imagen en la instancia del registro. Reemplace
mycontainerregistry007
por el nombre del servidor de inicio de sesión de la instancia del registro. Este ejemplo crea el repositorioquarkus-postgres-passwordless-app
, que contiene la imagenquarkus-postgres-passwordless-app:v1
.docker push mycontainerregistry007/quarkus-postgres-passwordless-app:v1
4. Creación de una aplicación de contenedor en Azure
Cree una instancia de Container Apps mediante la ejecución del comando siguiente. Asegúrese de reemplazar el valor de las variables de entorno por el nombre real y la ubicación que desea usar.
RESOURCE_GROUP="myResourceGroup" LOCATION="eastus" CONTAINERAPPS_ENVIRONMENT="my-environment" az containerapp env create \ --resource-group $RESOURCE_GROUP \ --name $CONTAINERAPPS_ENVIRONMENT \ --location $LOCATION
Para crear una aplicación contenedora con la imagen de la aplicación, ejecute el siguiente comando. Reemplace los marcadores de posición por sus valores. Para buscar los detalles de la cuenta de administrador del registro de contenedor, consulte Autenticación con un registro de contenedor de Azure.
CONTAINER_IMAGE_NAME=quarkus-postgres-passwordless-app:v1 REGISTRY_SERVER=mycontainerregistry007 REGISTRY_USERNAME=<REGISTRY_USERNAME> REGISTRY_PASSWORD=<REGISTRY_PASSWORD> az containerapp create \ --resource-group $RESOURCE_GROUP \ --name my-container-app \ --image $CONTAINER_IMAGE_NAME \ --environment $CONTAINERAPPS_ENVIRONMENT \ --registry-server $REGISTRY_SERVER \ --registry-username $REGISTRY_USERNAME \ --registry-password $REGISTRY_PASSWORD
5. Creación y conexión de una base de datos PostgreSQL con conectividad de identidad
A continuación, cree una base de datos PostgreSQL y configure la aplicación contenedora para conectarse a una base de datos PostgreSQL con una identidad administrada asignada por el sistema. La aplicación Quarkus se conectará a esta base de datos y almacenará sus datos al ejecutarse, conservando el estado de la aplicación independiente de dónde se ejecute la aplicación.
Cree el servicio de base de datos.
DB_SERVER_NAME='msdocs-quarkus-postgres-webapp-db' ADMIN_USERNAME='demoadmin' ADMIN_PASSWORD='<admin-password>' az postgres flexible-server create \ --resource-group $RESOURCE_GROUP \ --name $DB_SERVER_NAME \ --location $LOCATION \ --admin-user $DB_USERNAME \ --admin-password $DB_PASSWORD \ --sku-name GP_Gen5_2
Los parámetros siguientes se usan en el comando de la CLI de Azure anterior:
resource-group → Use el mismo nombre de grupo de recursos con el que creó la aplicación web, por ejemplo
msdocs-quarkus-postgres-webapp-rg
.name → El nombre del servidor de bases de datos de PostgreSQL. Este nombre debe ser único en Azure (el punto de conexión de servidor será
https://<name>.postgres.database.azure.com
). Los caracteres permitidos sonA
-Z
,0
-9
y-
. Un buen patrón consiste en usar una combinación del nombre de la empresa y un identificador del servidor. (msdocs-quarkus-postgres-webapp-db
)location → Use la misma ubicación que se usa para la aplicación web.
admin-user → Nombre de usuario para la cuenta de administrador. No puede ser
azure_superuser
,admin
,administrator
,root
,guest
nipublic
. Por ejemplo,demoadmin
está bien.admin-password → Contraseña del usuario de administrador. Debe contener entre 8 y 128 caracteres de tres de las siguientes categorías: Letras del alfabeto inglés mayúsculas y minúsculas, números y caracteres no alfanuméricos.
Importante
Al crear nombres de usuario o contraseñas, no use el carácter
$
. Más adelante en este tutorial creará variables de entorno con estos valores, donde el carácter$
tiene un significado especial dentro del contenedor de Linux que se usa para ejecutar aplicaciones de Java.public-access →
None
que establece el servidor en modo de acceso público sin reglas de firewall. Las reglas se crearán en un paso posterior.sku-name → El nombre del plan de tarifa y la configuración del proceso, por ejemplo
GP_Gen5_2
. Para más información, consulte los precios de Azure Database for PostgreSQL.
Cree una base de datos denominada
fruits
en el servicio PostgreSQL con este comando:az postgres flexible-server db create \ --resource-group $RESOURCE_GROUP \ --server-name $DB_SERVER_NAME \ --database-name fruits
Instale la extensión sin contraseña de Service Connector para la CLI de Azure:
az extension add --name serviceconnector-passwordless --upgrade
Conecte la base de datos a la aplicación contenedora con una identidad administrada asignada por el sistema mediante el comando de conexión.
az containerapp connection create postgres-flexible \ --resource-group $RESOURCE_GROUP \ --name my-container-app \ --target-resource-group $RESOURCE_GROUP \ --server $DB_SERVER_NAME \ --database fruits \ --managed-identity
6. Revisión de los cambios
Para encontrar la dirección URL de la aplicación (FQDN), use el siguiente comando:
az containerapp list --resource-group $RESOURCE_GROUP
Cuando la página web nueva muestra su lista de frutos, la aplicación se conecta a la base de datos mediante la identidad administrada. Ahora ya puede editar la lista de frutos pendientes como antes.
Limpieza de recursos
En los pasos anteriores, creó recursos de Azure en un grupo de recursos. Si prevé que no necesitará estos recursos en el futuro, elimine el grupo de recursos ejecutando el siguiente comando en Cloud Shell:
az group delete --name myResourceGroup
Este comando puede tardar varios segundos en ejecutarse.
Pasos siguientes
Más información acerca de la ejecución de aplicaciones de Java en Azure en la guía del desarrollador.