Share via


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

  1. 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>
    
  2. 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

  1. 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
    
  2. 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.

  3. 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 repositorio quarkus-postgres-passwordless-app, que contiene la imagen quarkus-postgres-passwordless-app:v1.

    docker push mycontainerregistry007/quarkus-postgres-passwordless-app:v1
    

4. Creación de una aplicación de contenedor en Azure

  1. 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
    
  2. 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.

  1. 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 son A-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 ni public. 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-accessNone 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.

  1. 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
    
  2. Instale la extensión sin contraseña de Service Connector para la CLI de Azure:

    az extension add --name serviceconnector-passwordless --upgrade
    
  3. 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.