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: 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
-
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. Add aazure.workload.identity/use: "true"
below line 15. The resultingtemplate
section should look like this:
template:
metadata:
labels:
app: customers-service
azure.workload.identity/use: "true"
-
Also add a
serviceAccountName: workload-identity-sa
betweenspec
andcontainers
below line 17.template: metadata: labels: app: customers-service azure.workload.identity/use: "true" spec: serviceAccountName: workload-identity-sa containers:
-
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>