Skip to main content Link Menu Expand (external link) Document Search Copy Copied

Connect to the database without using username and password

You are now connecting to the Azure Key Vault by using a Workload Identity. You can use this same identity to also connect to the database. This will allow you to remove the username and password from the config repository.

Step by step guidance

  1. You will need to allow the user assigned managed identity access to the database. To configure this, you will need to first make your current logged in user account database administrator. For this to work on a MySQL database you first need an additional managed identity.

    DB_ADMIN_USER_ASSIGNED_IDENTITY_NAME=uid-dbadmin-$APPNAME-$UNIQUEID
       
    az identity create --name "${DB_ADMIN_USER_ASSIGNED_IDENTITY_NAME}" --resource-group "${RESOURCE_GROUP}" --location "${LOCATION}"
    
  2. This identity needs to be assigned to your MySQL server.

    az mysql flexible-server identity assign \
        --resource-group $RESOURCE_GROUP \
        --server-name $MYSQL_SERVER_NAME \
        --identity $DB_ADMIN_USER_ASSIGNED_IDENTITY_NAME
    
  3. Get the current logged in user and object ID. This will give you the info of the user account you are currently logged in with in the Azure CLI.

    CURRENT_USER=$(az account show --query user.name --output tsv)
    echo $CURRENT_USER
    CURRENT_USER_OBJECTID=$(az ad signed-in-user show --query id --output tsv)
    echo $CURRENT_USER_OBJECTID
    
  4. Next you create a database administrator based on your current user account.

    az mysql flexible-server ad-admin create \
        --resource-group $RESOURCE_GROUP \
        --server-name $MYSQL_SERVER_NAME \
        --object-id $CURRENT_USER_OBJECTID \
        --display-name $CURRENT_USER \
        --identity $DB_ADMIN_USER_ASSIGNED_IDENTITY_NAME
    
  5. You can now create a sql file for creating a database user for the user assigned managed identity you created earlier for usage in the spring-petclinic namespace of the cluster.

    IDENTITY_LOGIN_NAME="mysql_conn"
       
    cat <<EOF >createuser.sql
    SET aad_auth_validate_oids_in_tenant = OFF;
    DROP USER IF EXISTS '${IDENTITY_LOGIN_NAME}'@'%';
    CREATE AADUSER '${IDENTITY_LOGIN_NAME}' IDENTIFIED BY '${USER_ASSIGNED_CLIENT_ID}';
    GRANT ALL PRIVILEGES ON ${DATABASE_NAME}.* TO '${IDENTITY_LOGIN_NAME}'@'%';
    FLUSH privileges;
    EOF
    
  6. Get an access token for the database and execute the sql script with this access token.

    RDBMS_ACCESS_TOKEN=$(az account get-access-token \
        --resource-type oss-rdbms \
        --query accessToken \
        --output tsv) 
    echo $RDBMS_ACCESS_TOKEN
       
    az mysql flexible-server execute \
        --name ${MYSQL_SERVER_NAME} \
        --admin-user ${CURRENT_USER} \
        --admin-password ${RDBMS_ACCESS_TOKEN} \
        --file-path "createuser.sql"   
    
  7. You will now need to update the spring-petclinic-customers-service, spring-petclinic-visits-service and spring-petclinic-vets-service to make use of the passwordless capabilities of the Azure SDK. In each pom.xml file of each microservice replace the mysql-connector-j artifact by this one:

         <dependency>
           <groupId>com.azure.spring</groupId>
           <artifactId>spring-cloud-azure-starter-jdbc-mysql</artifactId>
         </dependency>
    
  8. In the main pom.xml file add the Azure BOM as an extra dependency between the <dependencyManagement><dependencies></dependencies></dependencyManagement> elements.

            <dependency>
              <groupId>com.azure.spring</groupId>
              <artifactId>spring-cloud-azure-dependencies</artifactId>
              <version>${version.spring.cloud.azure}</version>
              <type>pom</type>
              <scope>import</scope>
            </dependency> 
  1. In the same file also add an additional property between the <properties></properties> element for the Azure Spring Cloud version we are going to use.
   <version.spring.cloud.azure>5.2.0</version.spring.cloud.azure>
  1. With these changes done. Make sure you are in the /src folder and rebuild the project.
   cd ~/workspaces/java-microservices-aks-lab/src
   mvn clean package -DskipTests
  1. Once the build is done, move to the staging-acr directory and recreate the container images for customers, visits and vets.
   rm spring-petclinic-customers-service-$VERSION.jar
   rm spring-petclinic-visits-service-$VERSION.jar
   rm spring-petclinic-vets-service-$VERSION.jar
   cp ../spring-petclinic-customers-service/target/spring-petclinic-customers-service-$VERSION.jar spring-petclinic-customers-service-$VERSION.jar
   cp ../spring-petclinic-visits-service/target/spring-petclinic-visits-service-$VERSION.jar spring-petclinic-visits-service-$VERSION.jar
   cp ../spring-petclinic-vets-service/target/spring-petclinic-vets-service-$VERSION.jar spring-petclinic-vets-service-$VERSION.jar
   
   docker build -t $MYACR.azurecr.io/spring-petclinic-customers-service:$VERSION \
       --build-arg ARTIFACT_NAME=spring-petclinic-customers-service-$VERSION.jar \
       --build-arg APP_PORT=8080 \
       --build-arg AI_JAR=ai.jar \
       .

   docker push $MYACR.azurecr.io/spring-petclinic-customers-service:$VERSION

   docker build -t $MYACR.azurecr.io/spring-petclinic-visits-service:$VERSION \
       --build-arg ARTIFACT_NAME=spring-petclinic-visits-service-$VERSION.jar \
       --build-arg APP_PORT=8080 \
       --build-arg AI_JAR=ai.jar \
       .

   docker push $MYACR.azurecr.io/spring-petclinic-visits-service:$VERSION

   docker build -t $MYACR.azurecr.io/spring-petclinic-vets-service:$VERSION \
       --build-arg ARTIFACT_NAME=spring-petclinic-vets-service-$VERSION.jar \
       --build-arg APP_PORT=8080 \
       --build-arg AI_JAR=ai.jar \
       .
   
   docker push $MYACR.azurecr.io/spring-petclinic-vets-service:$VERSION
  1. In the config repository you will need to update the database connection information: Rename the username to mysql_conn. Remove the password. Add an additional property to indicate that you will use passwordless connections. Add a serverTimeZone to the connection string. The resulting configuration should look like this:
   spring:
     datasource:
       url: jdbc:mysql://<your-mysql-server-name>.mysql.database.azure.com:3306/petclinic?useSSL=true&serverTimezone=UTC
       username: mysql_conn
       azure.passwordless-enabled: true
  1. Commit these changes to the config repo.

    git add .
    git commit -m 'Changed db config to passwordless'
    git push
    
  2. Lastly you will need to update the spring-petclinic-customers-service.yml, spring-petclinic-visits-service.yml and spring-petclinic-vets-service.yml files in the kubernetes folder. Add a azure.workload.identity/use: "true" below line 15. The resulting template section should look like this:

     template:
       metadata:
         labels:
           app: customers-service
           azure.workload.identity/use: "true"
  1. Also add a serviceAccountName: workload-identity-sa between spec and containers below line 17.

      template:
        metadata:
          labels:
            app: customers-service
            azure.workload.identity/use: "true"
        spec:
          serviceAccountName: workload-identity-sa
          containers:   
    
  2. Reapply these 3 YAML configurations. After applying, double check that the pods are back up and running and whether the application is showing data again.

   cd ../kubernetes
   kubectl apply -f spring-petclinic-customers-service.yml 
   kubectl apply -f spring-petclinic-vets-service.yml 
   kubectl apply -f spring-petclinic-visits-service.yml 
   
   kubectl get pods -w

   kubectl logs <pod-name>
  1. In case you see errors or crashloops of your pods, you can use the below statements to diagnose what might be going wrong. A first statement you can try is look at the logs of your pod.
   kubectl logs <pod-name>