Conecta aplicaciones de Java a AlloyDB para PostgreSQL con la autenticación de IAM

1. Antes de comenzar

Java y AlloyDB: Conectividad simple y segura

AlloyDB para PostgreSQL es el servicio de base de datos completamente administrado y compatible con PostgreSQL de Google Cloud para cargas de trabajo empresariales exigentes. La conexión de una aplicación de Java a AlloyDB de forma segura y eficiente se realiza a través del conector de Java para AlloyDB (alloydb-jdbc-connector), una biblioteca cliente que va más allá de un controlador JDBC estándar.

La magia del conector de Java para AlloyDB

El alloydb-jdbc-connector funciona como un SocketFactory inteligente para el controlador JDBC de PostgreSQL estándar (org.postgresql:postgresql). Abstrae el establecimiento de una conexión segura a la base de datos para que puedas enfocarte en la lógica de la aplicación en lugar de la seguridad de redes o la rotación de credenciales:

  • Encriptación de mTLS 1.3: Establece automáticamente una conexión de TLS 1.3 autenticada de forma mutua entre tu JVM y la instancia de AlloyDB sin que tengas que administrar los certificados de cliente de SSL/TLS de forma manual.
  • Autorización basada en IAM: En lugar de depender de contraseñas de bases de datos estáticas, el conector aprovecha Google Cloud IAM y las credenciales predeterminadas de la aplicación (ADC) para obtener tokens de acceso de OAuth2 de corta duración de forma automática.
  • Resolución de IP dinámica: Consulta la API de AlloyDB Admin para resolver la dirección IP actual (PRIVATE, PUBLIC o PSC de Private Service Connect) de tu instancia de base de datos de forma dinámica. No es necesario codificar de forma rígida los nombres de host ni las direcciones IP, lo que hace que las conmutaciones por error y el mantenimiento sean transparentes.

Cómo funciona el conector de Java para AlloyDB en detalle

Requisitos previos

  • Conocimientos de Java, Maven y conceptos básicos de SQL/JDBC
  • Conocimientos básicos de Google Cloud CLI (gcloud) y los roles de IAM

Actividades

  • Configurar una instancia de AlloyDB y una cuenta de servicio para la autenticación de bases de datos de IAM sin contraseña
  • Otorga permisos de esquema y tabla de PostgreSQL con privilegios mínimos a una principal de IAM.
  • Configura un DataSource de nivel de producción con JDBC simple y HikariCP usando el SocketFactory de AlloyDB.
  • Integrar el conector de Java para AlloyDB en aplicaciones de Spring Boot, Quarkus y Micronaut
  • Registra el SocketFactory de AlloyDB para la compilación de GraalVM Native Image y soluciona problemas comunes de autenticación de IAM.

Requisitos

  • Un proyecto de Google Cloud con la facturación habilitada y un clúster y una instancia principal de AlloyDB activos (consulta la guía de creación de clústeres de AlloyDB o activa un clúster de AlloyDB Express en menos de dos segundos).
  • Los roles de IAM roles/alloydb.admin y roles/resourcemanager.projectIamAdmin en tu proyecto.
  • Java 17 o una versión posterior (se recomienda Java 17 o 21 LTS) y Apache Maven instalados
  • La CLI de gcloud y el cliente de psql instalados (o acceso a Google Cloud Shell)

2. Configura la autenticación de la base de datos de IAM en AlloyDB

Antes de escribir código de Java, debes configurar tu instancia de AlloyDB para que acepte tokens de IAM y crear la identidad de IAM que usará tu aplicación en tres capas: Google Cloud IAM, el plano de control de AlloyDB y el motor de PostgreSQL.

Configuración de tres capas para la autenticación de la base de datos de IAM de AlloyDB

Configura las variables de entorno

En la terminal, exporta las variables correspondientes a tu proyecto de Google Cloud y a la instancia de AlloyDB (reemplaza los marcadores de posición por tus valores):

export PROJECT_ID="<PROJECT_ID>"
export REGION="europe-west1"
export CLUSTER_ID="<CLUSTER_ID>"
export INSTANCE_ID="<INSTANCE_ID>"
export DB_NAME="dvdrental"

Habilita las APIs obligatorias

Habilita las APIs de AlloyDB, Compute Engine, Cloud Resource Manager, IAM y API de Service Usage en tu proyecto:

gcloud services enable \
    alloydb.googleapis.com \
    compute.googleapis.com \
    cloudresourcemanager.googleapis.com \
    iam.googleapis.com \
    serviceusage.googleapis.com \
    --project="${PROJECT_ID}"

Crea una cuenta de servicio y otorga roles de IAM

Crea una cuenta de servicio dedicada que servirá como la identidad de tu aplicación de Java:

gcloud iam service-accounts create java-alloydb-connector \
    --project="${PROJECT_ID}" \
    --display-name="Java Application DB Connector"

Otorga a la cuenta de servicio los dos roles de IAM que requiere el conector de Java para AlloyDB:

  1. roles/alloydb.client: Es necesario para recuperar los metadatos de la instancia y solicitar certificados mTLS efímeros de la API de AlloyDB Admin.
  2. roles/serviceusage.serviceUsageConsumer: Es obligatorio para la autenticación de la base de datos de IAM.
gcloud projects add-iam-policy-binding "${PROJECT_ID}" \
    --member="serviceAccount:java-alloydb-connector@${PROJECT_ID}.iam.gserviceaccount.com" \
    --role="roles/alloydb.client"

gcloud projects add-iam-policy-binding "${PROJECT_ID}" \
    --member="serviceAccount:java-alloydb-connector@${PROJECT_ID}.iam.gserviceaccount.com" \
    --role="roles/serviceusage.serviceUsageConsumer"

Habilita la autenticación de IAM en la instancia de AlloyDB

Actualiza las marcas de tu instancia de AlloyDB para establecer alloydb.iam_authentication=on. Esta es una marca dinámica y se aplica de inmediato sin reiniciar la instancia:

gcloud alloydb instances update "${INSTANCE_ID}" \
    --cluster="${CLUSTER_ID}" \
    --region="${REGION}" \
    --project="${PROJECT_ID}" \
    --database-flags=alloydb.iam_authentication=on

Registra el usuario de la base de datos de IAM

Registra la cuenta de servicio como un usuario de la base de datos de IAM_BASED en tu clúster de AlloyDB con gcloud:

gcloud alloydb users create "java-alloydb-connector@${PROJECT_ID}.iam" \
    --cluster="${CLUSTER_ID}" \
    --region="${REGION}" \
    --project="${PROJECT_ID}" \
    --type=IAM_BASED

Otorga permisos de esquema y tabla de PostgreSQL

Los usuarios de la base de datos de IAM recién creados no tienen privilegios de tabla de forma predeterminada. Conéctate a tu instancia de AlloyDB como el usuario administrador postgres (a través de psql o AlloyDB Studio en la consola de Cloud) y otorga acceso a tu base de datos y tablas de destino (como la base de datos de ejemplo de alquiler de DVD):

-- Connect to your target database first
\c dvdrental

-- (Optional) Create a sample film table if your database is empty
CREATE TABLE IF NOT EXISTS public.film (
    film_id SERIAL PRIMARY KEY,
    title VARCHAR(255) NOT NULL,
    release_year INTEGER DEFAULT 2006,
    rating VARCHAR(10) DEFAULT 'PG',
    rental_rate NUMERIC(4,2) DEFAULT 2.99
);

INSERT INTO public.film (film_id, title, release_year, rating, rental_rate) VALUES
    (1, 'Academy Dinosaur', 2006, 'PG', 0.99),
    (2, 'Ace Goldfinger', 2006, 'G', 4.99),
    (3, 'Adaptation Holes', 2006, 'NC-17', 2.99),
    (4, 'Affair Prejudice', 2006, 'G', 2.99),
    (5, 'African Egg', 2006, 'G', 2.99)
ON CONFLICT (film_id) DO NOTHING;

-- Grant permissions to the IAM user (double quotes are required because of '@' and '.')
GRANT CONNECT ON DATABASE "dvdrental" TO "java-alloydb-connector@<PROJECT_ID>.iam";
GRANT USAGE ON SCHEMA public TO "java-alloydb-connector@<PROJECT_ID>.iam";
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO "java-alloydb-connector@<PROJECT_ID>.iam";

Cuando ejecutes estas declaraciones en AlloyDB Studio (o psql), puedes inspeccionar el esquema public.film y verificar las filas de muestra:

Otorgar permisos de IAM e inspeccionar public.film en AlloyDB Studio

Configura las credenciales predeterminadas de la aplicación (ADC) locales

Cuando ejecutes en Cloud Run, Google Kubernetes Engine (GKE) o Compute Engine, adjunta la cuenta de servicio de java-alloydb-connector directamente a la carga de trabajo. Cuando ejecutes la aplicación de forma local en tu estación de trabajo, usa la identidad temporal de la cuenta de servicio para que las ADC generen tokens para esa identidad:

gcloud auth application-default login \
    --impersonate-service-account="java-alloydb-connector@${PROJECT_ID}.iam.gserviceaccount.com"

3. Conéctate con JDBC simple y HikariCP

Para cualquier aplicación de Java de nivel de producción, un grupo de conexiones es esencial, y HikariCP es el estándar de la industria. En este paso, compilarás una aplicación de JDBC + HikariCP simple que delegue la creación de sockets a com.google.cloud.alloydb.SocketFactory.

Crea el proyecto de Maven (pom.xml)

Crea un directorio nuevo jdbc-app con un archivo pom.xml que contenga el controlador JDBC de PostgreSQL (42.7.14), el conector de Java para AlloyDB (1.4.0) y HikariCP (7.1.0):

mkdir -p jdbc-app/src/main/java
cd jdbc-app

Crea pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example.alloydb</groupId>
    <artifactId>alloydb-jdbc-sample</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <exec.mainClass>AlloyDBConnectivity</exec.mainClass>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <version>42.7.14</version>
        </dependency>

        <dependency>
            <groupId>com.google.cloud</groupId>
            <artifactId>alloydb-jdbc-connector</artifactId>
            <version>1.4.0</version>
        </dependency>

        <dependency>
            <groupId>com.zaxxer</groupId>
            <artifactId>HikariCP</artifactId>
            <version>7.1.0</version>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-simple</artifactId>
            <version>2.0.16</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>3.5.0</version>
                <configuration>
                    <cleanupDaemonThreads>false</cleanupDaemonThreads>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

Crear AlloyDBConnectivity.java

Crea src/main/java/AlloyDBConnectivity.java (ver en GitHub Gist):

import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class AlloyDBConnectivity {
    // Retrieve configuration from environment variables
    private static final String ALLOYDB_INSTANCE_URI = System.getenv("ALLOYDB_INSTANCE_NAME"); // e.g., projects/<PROJECT_ID>/locations/<REGION>/clusters/<CLUSTER_ID>/instances/<INSTANCE_ID>
    private static final String ALLOYDB_DB_NAME = System.getenv("ALLOYDB_DB"); // e.g., "dvdrental"
    private static final String ALLOYDB_USER = System.getenv("ALLOYDB_USER"); // e.g., "java-alloydb-connector@<PROJECT_ID>.iam"
    private static final String ALLOYDB_PASS = System.getenv("ALLOYDB_PASS"); // Database password if not using IAM auth

    public static HikariDataSource createDataSource() {
        HikariConfig config = new HikariConfig();

        // The JDBC URL does not need a host or port. The SocketFactory will resolve the IP address.
        config.setJdbcUrl(String.format("jdbc:postgresql:///%s", ALLOYDB_DB_NAME));
        config.setUsername(ALLOYDB_USER);

        // Only set the password if you are NOT using IAM authentication.
        if (System.getenv("ALLOYDB_ENABLE_IAM_AUTH") == null || !System.getenv("ALLOYDB_ENABLE_IAM_AUTH").equalsIgnoreCase("true")) {
            config.setPassword(ALLOYDB_PASS);
        }

        // 1. Set the SocketFactory to the AlloyDB Connector's implementation.
        config.addDataSourceProperty("socketFactory", "com.google.cloud.alloydb.SocketFactory");

        // 2. Tell the connector which AlloyDB instance to connect to.
        config.addDataSourceProperty("alloydbInstanceName", ALLOYDB_INSTANCE_URI);

        // 3. (Recommended) Enable IAM database authentication.
        if (System.getenv("ALLOYDB_ENABLE_IAM_AUTH") != null && System.getenv("ALLOYDB_ENABLE_IAM_AUTH").equalsIgnoreCase("true")) {
            config.addDataSourceProperty("alloydbEnableIAMAuth", "true");
        }

        // 4. (Optional) Specify IP type (e.g., "PRIVATE", "PUBLIC", "PSC"). Defaults to PRIVATE.
        String ipType = System.getenv("ALLOYDB_IP_TYPE");
        if (ipType != null) {
            config.addDataSourceProperty("alloydbIpType", ipType);
        }

        // Baseline HikariCP settings
        config.setMaximumPoolSize(10);
        config.setMinimumIdle(2);
        config.setConnectionTimeout(30000); // 30 seconds
        config.setIdleTimeout(600000);      // 10 minutes
        config.setMaxLifetime(1800000);     // 30 minutes

        return new HikariDataSource(config);
    }

    public static void main(String[] args) {
        String sql = "SELECT title, release_year FROM public.film ORDER BY film_id LIMIT 5";

        try (HikariDataSource pool = createDataSource();
             Connection conn = pool.getConnection();
             PreparedStatement stmt = conn.prepareStatement(sql);
             ResultSet rs = stmt.executeQuery()) {
            System.out.println("Successfully connected to AlloyDB via IAM! Sample films:");
            while (rs.next()) {
                System.out.printf(" - %s (%d)%n", rs.getString("title"), rs.getInt("release_year"));
            }
        } catch (SQLException e) {
            System.err.println("Database connection failed: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

Anatomía de una URL de JDBC de AlloyDB y configuración de HikariCP

Ejecuta la aplicación de JDBC simple

Exporta las variables de entorno para tu instancia de AlloyDB (establece ALLOYDB_IP_TYPE="PUBLIC" si te conectas desde fuera de tu VPC a través de una IP pública, o "PRIVATE"/"PSC" cuando estés dentro de la VPC) y ejecuta la aplicación:

export ALLOYDB_INSTANCE_NAME="projects/${PROJECT_ID}/locations/${REGION}/clusters/${CLUSTER_ID}/instances/${INSTANCE_ID}"
export ALLOYDB_DB="${DB_NAME}"
export ALLOYDB_USER="java-alloydb-connector@${PROJECT_ID}.iam"
export ALLOYDB_ENABLE_IAM_AUTH="true"
export ALLOYDB_IP_TYPE="PRIVATE" # Set to PUBLIC if connecting over Public IP from a local laptop

mvn compile exec:java

Deberías ver un resultado similar a este:

[AlloyDBConnectivity.main()] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Starting...
[AlloyDBConnectivity.main()] INFO com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Added connection org.postgresql.jdbc.PgConnection@1998bf07
[AlloyDBConnectivity.main()] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Start completed.
Successfully connected to AlloyDB via IAM! Sample films:
 - Academy Dinosaur (2006)
 - Ace Goldfinger (2006)
 - Adaptation Holes (2006)
 - Affair Prejudice (2006)
 - African Egg (2006)

Resultado de la terminal de la muestra de JDBC simple y HikariCP

4. Conéctate con Spring Boot

Spring Boot simplifica la conectividad de la base de datos, ya que configura automáticamente un grupo de conexiones de HikariCP a partir de las propiedades de tu aplicación. La integración del conector de Java para AlloyDB no requiere ningún código de bean de DataSource personalizado.

Crea el proyecto de Spring Boot (pom.xml)

Crea un directorio spring-boot-app nuevo:

cd ..
mkdir -p spring-boot-app/src/main/java/com/example/alloydb
mkdir -p spring-boot-app/src/main/resources
cd spring-boot-app

Crea pom.xml con spring-boot-starter-jdbc (que incluye HikariCP), org.postgresql:postgresql y com.google.cloud:alloydb-jdbc-connector:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>4.0.5</version>
        <relativePath/>
    </parent>

    <groupId>com.example.alloydb</groupId>
    <artifactId>alloydb-spring-boot-sample</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <properties>
        <java.version>17</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>

        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <version>42.7.14</version>
        </dependency>

        <dependency>
            <groupId>com.google.cloud</groupId>
            <artifactId>alloydb-jdbc-connector</artifactId>
            <version>1.4.0</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

Configura application.properties o variables de entorno

Puedes configurar la URL de conexión en src/main/resources/application.properties:

# No host or port is needed; the SocketFactory handles it.
spring.datasource.url=jdbc:postgresql:///dvdrental?socketFactory=com.google.cloud.alloydb.SocketFactory&alloydbInstanceName=projects/<PROJECT_ID>/locations/<REGION>/clusters/<CLUSTER_ID>/instances/<INSTANCE_ID>&alloydbEnableIAMAuth=true
spring.datasource.username=java-alloydb-connector@<PROJECT_ID>.iam
# No password required when alloydbEnableIAMAuth is true

Para mantener tus archivos de origen completamente libres de IDs de proyectos o nombres de instancias, puedes dejar application.properties vacío y proporcionar estas variables de entorno estándar de Spring Boot en el entorno de ejecución:

Variable de entorno

Valor

SPRING_DATASOURCE_URL

jdbc:postgresql:///dvdrental?socketFactory=com.google.cloud.alloydb.SocketFactory&alloydbInstanceName=projects//locations//clusters//instances/&alloydbEnableIAMAuth=true

SPRING_DATASOURCE_USERNAME

java-alloydb-connector@.iam

Crear AlloyDbTestApplication.java

Crea src/main/java/com/example/alloydb/AlloyDbTestApplication.java (ver en GitHub Gist):

package com.example.alloydb;

import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.jdbc.core.JdbcTemplate;

@SpringBootApplication
public class AlloyDbTestApplication {

    public static void main(String[] args) {
        System.exit(SpringApplication.exit(SpringApplication.run(AlloyDbTestApplication.class, args)));
    }

    @Bean
    CommandLineRunner testConnection(JdbcTemplate jdbcTemplate) {
        return args -> {
            String result = jdbcTemplate.queryForObject("SELECT 'Connection Successful!'", String.class);
            System.out.println(">>> ALLOYDB STATUS: " + result);
        };
    }
}

Ejecuta la aplicación de Spring Boot

Exporta las variables de entorno y ejecuta la app con mvn spring-boot:run:

export SPRING_DATASOURCE_URL="jdbc:postgresql:///${DB_NAME}?socketFactory=com.google.cloud.alloydb.SocketFactory&alloydbInstanceName=projects/${PROJECT_ID}/locations/${REGION}/clusters/${CLUSTER_ID}/instances/${INSTANCE_ID}&alloydbEnableIAMAuth=true"
export SPRING_DATASOURCE_USERNAME="java-alloydb-connector@${PROJECT_ID}.iam"

mvn spring-boot:run

Deberías ver lo siguiente:

>>> ALLOYDB STATUS: Connection Successful!

Configuración automática de Spring Boot y resultado de la ejecución en vivo

5. Conéctate con Quarkus, Micronaut y GraalVM Native Image

Debido a que el conector de Java para AlloyDB opera a nivel del controlador JDBC, cambiar entre frameworks de Java nativos de la nube no modifica la forma en que proteges el tráfico de la base de datos ni administras las identidades. Tanto Quarkus como Micronaut unen el controlador JDBC subyacente y delegan la encriptación de mTLS, la resolución de IP dinámica y la autenticación de IAM al conector a través de ADC.

Frameworks de Java nativos de la nube e imagen nativa de GraalVM con AlloyDB

Configuración de Quarkus (application.properties con Agroal)

En una aplicación de Quarkus (quarkus-agroal y quarkus-jdbc-postgresql), agrega com.google.cloud:alloydb-jdbc-connector:1.4.0 a tus dependencias y pasa los parámetros del conector a través de quarkus.datasource.jdbc.additional-jdbc-properties en src/main/resources/application.properties:

quarkus.datasource.db-kind=postgresql
quarkus.datasource.username=java-alloydb-connector@<PROJECT_ID>.iam
quarkus.datasource.jdbc.url=jdbc:postgresql:///dvdrental
quarkus.datasource.jdbc.additional-jdbc-properties.socketFactory=com.google.cloud.alloydb.SocketFactory
quarkus.datasource.jdbc.additional-jdbc-properties.alloydbInstanceName=projects/<PROJECT_ID>/locations/<REGION>/clusters/<CLUSTER_ID>/instances/<INSTANCE_ID>
quarkus.datasource.jdbc.additional-jdbc-properties.alloydbEnableIAMAuth=true

Configuración de Micronaut (application.yml con HikariCP)

En una aplicación de Micronaut (micronaut-jdbc-hikari), agrega com.google.cloud:alloydb-jdbc-connector:1.4.0 y configura src/main/resources/application.yml:

datasources:
  default:
    url: jdbc:postgresql:///dvdrental?socketFactory=com.google.cloud.alloydb.SocketFactory&alloydbInstanceName=projects/<PROJECT_ID>/locations/<REGION>/clusters/<CLUSTER_ID>/instances/<INSTANCE_ID>&alloydbEnableIAMAuth=true
    username: java-alloydb-connector@<PROJECT_ID>.iam
    driver-class-name: org.postgresql.Driver

Registra el conector para la imagen nativa de GraalVM

Cuando compilas tu aplicación en una imagen nativa de GraalVM (con Spring Boot 3+, Quarkus o Micronaut), hay un detalle importante: la reflexión.

El controlador JDBC de PostgreSQL crea una instancia de com.google.cloud.alloydb.SocketFactory de forma dinámica por nombre de clase con reflexión. Para evitar que el análisis estático de GraalVM quite la clase durante la compilación nativa, regístrala de forma explícita:

  • Spring Boot 3 o versiones posteriores: Agrega @RegisterReflectionForBinding(com.google.cloud.alloydb.SocketFactory.class) a tu aplicación principal o a la clase @Configuration:
    @SpringBootApplication
    @RegisterReflectionForBinding(com.google.cloud.alloydb.SocketFactory.class)
    public class AlloyDbTestApplication { ... }
    
  • Quarkus: Agrega @RegisterForReflection(targets = com.google.cloud.alloydb.SocketFactory.class) a tu clase principal o a un bean de CDI:
    @QuarkusMain
    @RegisterForReflection(targets = com.google.cloud.alloydb.SocketFactory.class)
    public class QuarkusAlloyDbApp implements QuarkusApplication { ... }
    

6. Soluciona problemas comunes de IAM y conectividad

Si encuentras un error FATAL: password authentication failed for user o AlloyDB IAM authentication failed, verifica las siguientes cuatro áreas:

Hoja de referencia para solucionar problemas de conectividad y de IAM de AlloyDB

1. Quita .gserviceaccount.com de los nombres de usuario de la base de datos de la cuenta de servicio

La causa más frecuente de las fallas de autenticación de IAM es pasar la dirección de correo electrónico completa de la cuenta de servicio como el nombre de usuario de la base de datos. AlloyDB aplica un formato diferente a los nombres de usuario de la base de datos de IAM según el tipo de principal:

  • Para cuentas de servicio de IAM (quita .gserviceaccount.com): Si el correo electrónico de tu cuenta de servicio de Google Cloud es java-alloydb-connector@.iam.gserviceaccount.com, debes quitar el sufijo .gserviceaccount.com y establecer el nombre de usuario de la base de datos de JDBC/AlloyDB en java-alloydb-connector@.iam.
  • Para cuentas de usuario o grupos de IAM (conserva el correo electrónico completo): Si te autenticas como un usuario humano de Google Workspace o Cloud Identity, usa tu dirección de correo electrónico completa sin modificar (por ejemplo, ).

2. Verifica cómo se creó el usuario de la base de datos

¿Registraste al usuario a través de gcloud alloydb users create --type=IAM_BASED (o la consola o Terraform)? Crear un usuario con SQL sin procesar CREATE USER no funcionará para la autenticación de IAM porque AlloyDB restringe GRANT alloydbiamuser al plano de control.

3. Verifica tu identidad de ADC activa

Asegúrate de que el entorno en el que se ejecuta el proceso de Java se autentique como la principal de IAM de destino:

  • Estación de trabajo local (conectándose como cuenta de servicio): Ejecuta gcloud auth application-default login --impersonate-service-account=java-alloydb-connector@.iam.gserviceaccount.com para que las ADC generen tokens para la cuenta de servicio en lugar de tu correo electrónico personal.
  • Cloud Run/GKE: Confirma que la cuenta de servicio esté conectada a la carga de trabajo y que tenga roles/alloydb.client y roles/serviceusage.serviceUsageConsumer.

4. Considera la propagación de IAM y el enrutamiento de red

  • Retraso en la propagación de IAM: Las vinculaciones de políticas de IAM pueden tardar entre 60 y 120 segundos en propagarse. Si acabas de crear la cuenta de servicio o la vinculación de rol, espera un minuto y vuelve a intentarlo.
  • Acceso a la red de VPC: De forma predeterminada, el conector de Java para AlloyDB se conecta a la IP PRIVATE de la instancia. Si tu aplicación se ejecuta en Cloud Run, configura la salida de VPC directa (recomendada para reducir la latencia y el costo en comparación con los conectores de Acceso a VPC sin servidores heredados) o conéctate a través de Private Service Connect (PSC). Si te conectas desde una máquina local fuera de la VPC, habilita la IP pública en la instancia y pasa alloydbIpType=PUBLIC.

7. Limpia

Para evitar que se apliquen cargos innecesarios a tu cuenta de Google Cloud y quitar las identidades de IAM creadas durante este codelab, limpia los recursos que se indican a continuación.

1. Quita el usuario de la base de datos de IAM de AlloyDB y la cuenta de servicio

Borra el usuario de la base de datos de IAM de tu clúster de AlloyDB y quita la cuenta de servicio:

# Delete the IAM database user from AlloyDB
gcloud alloydb users delete "java-alloydb-connector@${PROJECT_ID}.iam" \
    --cluster="${CLUSTER_ID}" \
    --region="${REGION}" \
    --project="${PROJECT_ID}" \
    --quiet

# Remove IAM policy bindings
gcloud projects remove-iam-policy-binding "${PROJECT_ID}" \
    --member="serviceAccount:java-alloydb-connector@${PROJECT_ID}.iam.gserviceaccount.com" \
    --role="roles/alloydb.client"

gcloud projects remove-iam-policy-binding "${PROJECT_ID}" \
    --member="serviceAccount:java-alloydb-connector@${PROJECT_ID}.iam.gserviceaccount.com" \
    --role="roles/serviceusage.serviceUsageConsumer"

# Delete the Service Account
gcloud iam service-accounts delete \
    "java-alloydb-connector@${PROJECT_ID}.iam.gserviceaccount.com" \
    --project="${PROJECT_ID}" \
    --quiet

2. Restablece las credenciales predeterminadas de la aplicación local

Si configuraste la identidad temporal de ADC local, restablece tus credenciales locales a tu identidad de usuario predeterminada:

gcloud auth application-default login

3. Borra el clúster de AlloyDB (opcional)

gcloud alloydb clusters delete "${CLUSTER_ID}" \
    --region="${REGION}" \
    --project="${PROJECT_ID}" \
    --force \
    --quiet

8. Felicitaciones

Completaste el codelab y estableciste una conectividad segura y sin contraseña de Java a AlloyDB para PostgreSQL.

Objetivos logrados

  1. Configuraste la autenticación de la base de datos de IAM: Creaste una cuenta de servicio con privilegios mínimos, habilitaste alloydb.iam_authentication=on, registraste al usuario de IAM en el clúster de AlloyDB y otorgaste privilegios de tabla de PostgreSQL.
  2. Conectado con JDBC simple y HikariCP: Se configuró HikariConfig con com.google.cloud.alloydb.SocketFactory para la encriptación automática de mTLS 1.3, la actualización de tokens de IAM y la resolución dinámica de IP.
  3. Frameworks nativos de la nube integrados: Se configuraron Spring Boot, Quarkus (Agroal) y Micronaut (HikariCP) con código estándar de grupo de conexiones personalizado cero, además de sugerencias de reflexión para GraalVM Native Image.
  4. Dominaste la solución de problemas de IAM: Aprendiste a diagnosticar problemas de formato de nombres de usuario, de robo de identidad de ADC y de enrutamiento de VPC.

Más información