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
-
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}"
-
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
-
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
-
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
-
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
-
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"
-
You will now need to update the
spring-petclinic-customers-service
,spring-petclinic-visits-service
andspring-petclinic-vets-service
to make use of the passwordless capabilities of the Azure SDK. In eachpom.xml
file of each microservice replace themysql-connector-j
artifact by this one:<dependency> <groupId>com.azure.spring</groupId> <artifactId>spring-cloud-azure-starter-jdbc-mysql</artifactId> </dependency>
-
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>
-
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>
-
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
-
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
-
In the config repository you will need to update the database connection information. Replace the contents of the current
application.yml
file with the contents of the 0406_application.yml file. Make sure you fill out your current MySQL server name on line12
. This file includes the following changes:- It adds a
serverTimezone=UTC
on line12
. - It changes the username tp
mysql_conn
on line13
, which is the name of the AAD connected user you created in the database. - It adds an extra
spring.datasource.passwordless-enabled
property with a value oftrue
on line14
.
- It adds a
-
Commit these changes to the config repo.
git add . git commit -m 'Changed db config to passwordless' git push
-
Lastly you will need to update the
spring-petclinic-customers-service.yml
,spring-petclinic-visits-service.yml
andspring-petclinic-vets-service.yml
files in thekubernetes
folder. Navigate to the kubernetes directory and update these files with the contents from the spring-petclinic-customers-service.yml, spring-petclinic-visits-service.yml and spring-petclinic-vets-service.yml files respectively. You can again curl the updates for these files and then fill out the correct container registry name.curl -o spring-petclinic-customers-service.yml https://raw.githubusercontent.com/Azure-Samples/java-microservices-aks-lab/main/docs/04_lab_secrets/spring-petclinic-customers-service.yml IMAGE=${MYACR}.azurecr.io/spring-petclinic-customers-service:$VERSION sed -i "s|#image#|$IMAGE|g" spring-petclinic-customers-service.yml curl -o spring-petclinic-visits-service.yml https://raw.githubusercontent.com/Azure-Samples/java-microservices-aks-lab/main/docs/04_lab_secrets/spring-petclinic-visits-service.yml IMAGE=${MYACR}.azurecr.io/spring-petclinic-visits-service:$VERSION sed -i "s|#image#|$IMAGE|g" spring-petclinic-visits-service.yml curl -o spring-petclinic-vets-service.yml https://raw.githubusercontent.com/Azure-Samples/java-microservices-aks-lab/main/docs/04_lab_secrets/spring-petclinic-vets-service.yml IMAGE=${MYACR}.azurecr.io/spring-petclinic-vets-service:$VERSION sed -i "s|#image#|$IMAGE|g" spring-petclinic-vets-service.yml
-
Inspect the new contents of these files. These files have:
- An additional
azure.workload.identity/use: "true"
on line16
. - An additional
serviceAccountName: workload-identity-sa
on line18
.
- An additional
-
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>
-
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>
In case not all pods start up properly again, a full overview of how to recover from errors in the lab can be found in the LabTips.