diff --git a/cleanup.md b/cleanup.md index a4e7a3e..5ebbd2b 100644 --- a/cleanup.md +++ b/cleanup.md @@ -36,7 +36,7 @@ If you're not going to continue to use this lab environment, run the following c `az cognitiveservices account deployment list -g $RESOURCE_GROUP -n $OPEN_AI_SERVICE_NAME -o table` - - delete the deployments on by one + - delete the deployments one by one `az cognitiveservices account deployment delete -g $RESOURCE_GROUP -n $OPEN_AI_SERVICE_NAME --deployment-name ` diff --git a/docs/02_lab_launch/0203.md b/docs/02_lab_launch/0203.md index 5372f50..aed9113 100644 --- a/docs/02_lab_launch/0203.md +++ b/docs/02_lab_launch/0203.md @@ -48,10 +48,10 @@ Your MySQL database will also have a firewall enabled. This firewall will by def 1. Run the following commands to create a database in the Azure Database for MySQL Flexible Server instance. ```bash - az mysql flexible-server db create \ - --server-name $MYSQL_SERVER_NAME \ - --resource-group $RESOURCE_GROUP \ - -d $DATABASE_NAME + az mysql flexible-server db create \ + --server-name $MYSQL_SERVER_NAME \ + --resource-group $RESOURCE_GROUP \ + -d $DATABASE_NAME ``` 1. You will also need to allow connections to the server from your ACA environment. For now, to accomplish this, you will create a server firewall rule to allow inbound traffic from all Azure Services. @@ -83,7 +83,7 @@ Your MySQL database will also have a firewall enabled. This firewall will by def * It changes the default `spring.sql.init` values to use `mysql` configuration. * It adds a `spring.datasource` property for your mysql database. -1. In the part you pasted, update the values of the target datasource endpoint on line 6, the corresponding admin user account on line 7, and its password on line 8 to match your configuration. Set these values by using the information in the Azure Database for MySQL Flexible Server connection string you recorded earlier in this task. +1. In the part you pasted, update the values of `url`, `username`, `password` in the segment `spring.datasource`. Set these values by using the information in the Azure Database for MySQL Flexible Server connection string you recorded earlier in this task. 1. Save the changes and push the updates you made to the _application.yml_ file to your private GitHub repo by running the following commands from the Git Bash prompt: diff --git a/docs/02_lab_launch/0205.md b/docs/02_lab_launch/0205.md index c26359e..509b220 100644 --- a/docs/02_lab_launch/0205.md +++ b/docs/02_lab_launch/0205.md @@ -62,12 +62,27 @@ Make sure the api-gateway and admin-server microservices have public IP addresse 1. Once your build has finished, you can create each of the microservices. - Create image using acr and create container apps with the image from acr. + Create image using acr and create container apps with the image from acr. A Dockerfile is required for acr to build the image. The content of the Dockerfile is: - You'll start with the **api-gateway**. Since this is the entrypoint to your other microservices, you will create it with an `external` ingress. Also, you will bind this app to the configserver and eureka components you created earlier. + ```docker + # syntax=docker/dockerfile:1 + + # run + FROM mcr.microsoft.com/openjdk/jdk:17-distroless + COPY ./target/*.jar app.jar + EXPOSE 8080 + + # Run the jar file + ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "/app.jar"] + ``` + + The content is saved in file **../tools/Dockerfile**, we use the saved file in the next steps. + +1. Let's start with the **api-gateway**. Since this is the entrypoint to your other microservices, you will create it with an `external` ingress. Also, you will bind this app to the configserver and eureka components you created earlier. ```bash APP_NAME=api-gateway + cp -f ../tools.Dockerfile ./spring-petclinic-$APP_NAME/Dockerfile az containerapp create \ --name $APP_NAME \ --resource-group $RESOURCE_GROUP \ @@ -83,19 +98,22 @@ Make sure the api-gateway and admin-server microservices have public IP addresse --runtime java ``` -1. Wait for the provisioning to finish, now you can create the other microservices, **customers-service**, **vets-service** and **visits-service**. These will be internal microservices, exposed by the **api-gateway**. Since these microservices connect to the MySQL database, you will also assign them the user assigned managed identity. +1. Wait for the provisioning to finish, now you can create the other microservices, **customers-service**, **vets-service** and **visits-service**. These will be internal microservices, exposed by the **api-gateway**. + + Since these microservices connect to the acr with managed identity, assign them the user assigned managed identity `USER_ID`. - To save the execute time, you may use the script **create-apps.sh** to deploy the apps: + To save the execute time, you may use the script **../tools/create-apps.sh** to deploy the apps: ```bash export RESOURCE_GROUP ACA_ENVIRONMENT MYACR USER_ID JAVA_CONFIG_COMP_NAME JAVA_EUREKA_COMP_NAME - ./create-apps.sh + ../tools/create-apps.sh ``` Or you can run the commands one by one to create these apps: ```bash APP_NAME=customers-service + cp -f ../tools.Dockerfile ./spring-petclinic-$APP_NAME/Dockerfile az containerapp create \ --name $APP_NAME \ --resource-group $RESOURCE_GROUP \ @@ -111,6 +129,7 @@ Make sure the api-gateway and admin-server microservices have public IP addresse --runtime java APP_NAME=vets-service + cp -f ../tools.Dockerfile ./spring-petclinic-$APP_NAME/Dockerfile az containerapp create \ --name $APP_NAME \ --resource-group $RESOURCE_GROUP \ @@ -126,6 +145,7 @@ Make sure the api-gateway and admin-server microservices have public IP addresse --runtime java APP_NAME=visits-service + cp -f ../tools.Dockerfile ./spring-petclinic-$APP_NAME/Dockerfile az containerapp create \ --name $APP_NAME \ --resource-group $RESOURCE_GROUP \ diff --git a/docs/03_lab_monitor/0302.md b/docs/03_lab_monitor/0302.md index e5f7c75..34e1464 100644 --- a/docs/03_lab_monitor/0302.md +++ b/docs/03_lab_monitor/0302.md @@ -26,7 +26,7 @@ Enable logging on your Azure Container Apps environment. You can follow the belo WORKSPACE=la-$APPNAME-$UNIQUEID az monitor log-analytics workspace create \ --resource-group $RESOURCE_GROUP \ - --workspace-name $WORKSPACE + --workspace-name $WORKSPACE ``` 1. Enable logging on your Azure Container Apps environment. diff --git a/docs/03_lab_monitor/0303.md b/docs/03_lab_monitor/0303.md index fec0e39..538fe87 100644 --- a/docs/03_lab_monitor/0303.md +++ b/docs/03_lab_monitor/0303.md @@ -44,69 +44,86 @@ You can follow the below guidance to do so. ```bash AI_CONNECTIONSTRING=$(az monitor app-insights component show --app $AINAME -g $RESOURCE_GROUP --query connectionString --output tsv) - echo $AI_CONNECTIONSTRING ``` -1. Define image tag +1. Build a image with application insights agent, and set the related environment variables. - ```bash - IMAGE_TAG=petclinic-ai-agent + We customize the Dockerfile to build the image with application insights agent. The content of the Dockerfile is + + ```dockerfile + # syntax=docker/dockerfile:1 + + # build + FROM mcr.microsoft.com/openjdk/jdk:17-mariner AS build + ARG AI_VERSION=3.5.4 + RUN yum update -y && \ + yum install -y wget + + RUN wget https://github.com/microsoft/ApplicationInsights-Java/releases/download/$AI_VERSION/applicationinsights-agent-$AI_VERSION.jar -O ai.jar --quiet + + # run + FROM mcr.microsoft.com/openjdk/jdk:17-distroless + + COPY --from=build ./ai.jar ai.jar + COPY ./target/*.jar app.jar + EXPOSE 8080 + + # Run with javaagent + ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-javaagent:/ai.jar", "-jar", "/app.jar"] ``` -1. You will now use Azure Container Registry with customized Dockerfile to build your image, and update the container app to enable Application Insights Agent. + This content is saved in file **../tools/ai.Dockerfile**, we use the saved file in the next steps. + +1. You will now update the container app to enable Application Insights Agent. - Do this first for the **api-gateway** service. Notice how you are also setting the `APPLICATIONINSIGHTS_CONNECTION_STRING` and `APPLICATIONINSIGHTS_CONFIGURATION_CONTENT` environment variables. + Do this first for the **api-gateway** service. Notice how you are also setting the environment variables `APPLICATIONINSIGHTS_CONNECTION_STRING` and `APPLICATIONINSIGHTS_CONFIGURATION_CONTENT`. ```bash APP_NAME="api-gateway" + cp -f ../tools/ai.Dockerfile spring-petclinic-$APP_NAME/Dockerfile - az acr build -g $RESOURCE_GROUP --registry $MYACR --image spring-petclinic-$APP_NAME:$IMAGE_TAG --file spring-petclinic-$APP_NAME/ai.Dockerfile spring-petclinic-$APP_NAME - az containerapp update \ --name $APP_NAME \ --resource-group $RESOURCE_GROUP \ - --image $MYACR.azurecr.io/spring-petclinic-$APP_NAME:$IMAGE_TAG \ + --source ./spring-petclinic-$APP_NAME \ --set-env-vars APPLICATIONINSIGHTS_CONNECTION_STRING=$AI_CONNECTIONSTRING APPLICATIONINSIGHTS_CONFIGURATION_CONTENT='{"role": {"name": "'$APP_NAME'"}}' ``` 1. Once the app **api-gateway** deployment has succeeded, execute the same statements for the other microservices **customers-service**, **vets-service** and **visits-service**. - To save the execute time, you may use the script **build-update-apps.sh** to deploy the apps: + To save the execute time, you may use the script **../tools/build-update-apps.sh** to deploy the apps: ```bash export RESOURCE_GROUP MYACR IMAGE_TAG AI_CONNECTIONSTRING - ./build-update-apps.sh + ../tools/build-update-apps.sh ``` Or you can run the commands one by one to build and update these apps: ```bash APP_NAME="customers-service" - az acr build -g $RESOURCE_GROUP --registry $MYACR --image spring-petclinic-$APP_NAME:$IMAGE_TAG --file spring-petclinic-$APP_NAME/ai.Dockerfile spring-petclinic-$APP_NAME - + cp -f ../tools/ai.Dockerfile spring-petclinic-$APP_NAME/Dockerfile az containerapp update \ --name $APP_NAME \ --resource-group $RESOURCE_GROUP \ - --image $MYACR.azurecr.io/spring-petclinic-$APP_NAME:$IMAGE_TAG \ + --source ./spring-petclinic-$APP_NAME \ --set-env-vars APPLICATIONINSIGHTS_CONNECTION_STRING=$AI_CONNECTIONSTRING APPLICATIONINSIGHTS_CONFIGURATION_CONTENT='{"role": {"name": "'$APP_NAME'"}}' APP_NAME="vets-service" - az acr build -g $RESOURCE_GROUP --registry $MYACR --image spring-petclinic-$APP_NAME:$IMAGE_TAG --file spring-petclinic-$APP_NAME/ai.Dockerfile spring-petclinic-$APP_NAME - + cp -f ../tools/ai.Dockerfile spring-petclinic-$APP_NAME/Dockerfile az containerapp update \ --name $APP_NAME \ --resource-group $RESOURCE_GROUP \ - --image $MYACR.azurecr.io/spring-petclinic-$APP_NAME:$IMAGE_TAG \ + --source ./spring-petclinic-$APP_NAME \ --set-env-vars APPLICATIONINSIGHTS_CONNECTION_STRING=$AI_CONNECTIONSTRING APPLICATIONINSIGHTS_CONFIGURATION_CONTENT='{"role": {"name": "'$APP_NAME'"}}' APP_NAME="visits-service" - az acr build -g $RESOURCE_GROUP --registry $MYACR --image spring-petclinic-$APP_NAME:$IMAGE_TAG --file spring-petclinic-$APP_NAME/ai.Dockerfile spring-petclinic-$APP_NAME - + cp -f ../tools/ai.Dockerfile spring-petclinic-$APP_NAME/Dockerfile az containerapp update \ --name $APP_NAME \ --resource-group $RESOURCE_GROUP \ - --image $MYACR.azurecr.io/spring-petclinic-$APP_NAME:$IMAGE_TAG \ + --source ./spring-petclinic-$APP_NAME \ --set-env-vars APPLICATIONINSIGHTS_CONNECTION_STRING=$AI_CONNECTIONSTRING APPLICATIONINSIGHTS_CONFIGURATION_CONTENT='{"role": {"name": "'$APP_NAME'"}}' ``` @@ -115,3 +132,87 @@ You can follow the below guidance to do so. {: .note } > To make sure everything is back up and running as expected, you may want to double check if all your services are back up and running. Check console log if you are seeing any service in failed state. + +## Analyze application specific monitoring data + +Now that Application Insights is properly configured, you can use this service to monitor what is going on in your application. You can follow the below guidance to do so. + +- [Application Insights Overview dashboard](https://learn.microsoft.com/azure/azure-monitor/app/overview-dashboard) + +Use this guidance to take a look at: +- The Application Map +- Performance data +- Failures +- Metrics +- Live Metrics +- Availability +- Logs + +To get the logging information flowing, you should navigate to your application and to the different sub-pages and refresh each page a couple of times. It might take some time to update Application Insights with information from your application. + +Step by step operations + +1. In your browser, navigate to the Azure Portal and your resource group. + +1. Select the Application Insights resource in the resource group. On the overview page you will already see data about Failed requests, Server response time, Server requests and Availability. + + ![ai_overview](../../images/ai_overview.png) + +1. Select _Application map_. This will show you information about the different applications running in your Spring Cloud Service and their dependencies. This is where the role names you configured in the YAML files are used. + + ![application map](../../images/app-map.png) + +1. Select the _api-gateway_ service. This will show you details about this application, like slowest requests and failed dependencies. + + ![api-gateway](../../images/api-gateway.png) + +1. Select _Performance_. This will show you more data on performance. + + ![performance](../../images/api-gw-perf.png) + +1. You can also drag your mouse on the graph to select a specific time period, and it will update the view. + +1. Select again your Application Insights resource to navigate back to the _Application map_ and the highlighted _api-gateway_ service. + +1. Select _Live Metrics_, to see live metrics of your application. This will show you near real time performance of your application, as well as the logs and traces coming in + + ![live metrics](../../images/live-perf.png) + +1. Select _Availability_, and next _Create Standard test_, to configure an availability test for your application. + +1. Fill out the following details and select _Create_: + + - *Test name*: Name for your test + - *URL*: Fill out the URL to your api-gateway + - Keep all the default settings for the rest of the configuration. Notice that Alerts for this test will be enabled. + + Once created every 5 minutes your application will now be pinged for availability from 5 test locations. + +1. Select the three dots on the right of your newly created availability test and select _Open Rules (Alerts) page_. + +1. Select the alert rule for your availability test. By default there are no action groups associated with this alert rule. We will not configure them in this lab, but just for your information, with action groups you can send email or SMS notifications to specific people or groups. + + - [Create and manage action groups in the Azure portal](https://docs.microsoft.com/azure/azure-monitor/alerts/action-groups) + +1. Navigate back to your Application Insights resource. + +1. Select _Failures_, to see information on all failures in your applications. You can click on any of the response codes, exception types or failed dependencies to get more information on these failures. + + ![failures](../../images/failure.png) + +1. Select _Performance_, to see performance data of your applications' operations. This will be a similar view to the one you looked at earlier. + + ![performance](../../images/perf2.png) + +1. Select _Logs_, to see all logged data. You can use Kusto Query Language (KQL) queries to search and analyze the logged data + + * [Log queries in Azure Monitor](https://docs.microsoft.com/azure/azure-monitor/logs/log-query-overview) + + {:style="counter-reset:step-counter 16"} +1. Select _Queries_ and next _Performance_. + +1. Double click _Operations performance_. This will load this query in the query window. + +1. Select _Run_, to see the results of this query. + + ![performance](../../images/performance3.png) diff --git a/docs/03_lab_monitor/0304.md b/docs/03_lab_monitor/0304.md deleted file mode 100644 index bd7b68b..0000000 --- a/docs/03_lab_monitor/0304.md +++ /dev/null @@ -1,91 +0,0 @@ ---- -title: '4. Analyze data' -layout: default -nav_order: 4 -parent: 'Lab 3: Enable monitoring' ---- - -# Analyze application specific monitoring data - -Now that Application Insights is properly configured, you can use this service to monitor what is going on in your application. You can follow the below guidance to do so. - -- [Application Insights Overview dashboard](https://learn.microsoft.com/azure/azure-monitor/app/overview-dashboard) - -Use this guidance to take a look at: -- The Application Map -- Performance data -- Failures -- Metrics -- Live Metrics -- Availability -- Logs - -To get the logging information flowing, you should navigate to your application and to the different sub-pages and refresh each page a couple of times. It might take some time to update Application Insights with information from your application. - -## Step by step guidance - -1. In your browser, navigate to the Azure Portal and your resource group. - -1. Select the Application Insights resource in the resource group. On the overview page you will already see data about Failed requests, Server response time, Server requests and Availability. - - ![ai_overview](../../images/ai_overview.png) - -1. Select _Application map_. This will show you information about the different applications running in your Spring Cloud Service and their dependencies. This is where the role names you configured in the YAML files are used. - - ![application map](../../images/app-map.png) - -1. Select the _api-gateway_ service. This will show you details about this application, like slowest requests and failed dependencies. - - ![api-gateway](../../images/api-gateway.png) - -1. Select _Performance_. This will show you more data on performance. - - ![performance](../../images/api-gw-perf.png) - -1. You can also drag your mouse on the graph to select a specific time period, and it will update the view. - -1. Select again your Application Insights resource to navigate back to the _Application map_ and the highlighted _api-gateway_ service. - -1. Select _Live Metrics_, to see live metrics of your application. This will show you near real time performance of your application, as well as the logs and traces coming in - - ![live metrics](../../images/live-perf.png) - -1. Select _Availability_, and next _Create Standard test_, to configure an availability test for your application. - -1. Fill out the following details and select _Create_: - - - *Test name*: Name for your test - - *URL*: Fill out the URL to your api-gateway - - Keep all the default settings for the rest of the configuration. Notice that Alerts for this test will be enabled. - - Once created every 5 minutes your application will now be pinged for availability from 5 test locations. - -1. Select the three dots on the right of your newly created availability test and select _Open Rules (Alerts) page_. - -1. Select the alert rule for your availability test. By default there are no action groups associated with this alert rule. We will not configure them in this lab, but just for your information, with action groups you can send email or SMS notifications to specific people or groups. - - - [Create and manage action groups in the Azure portal](https://docs.microsoft.com/azure/azure-monitor/alerts/action-groups) - -1. Navigate back to your Application Insights resource. - -1. Select _Failures_, to see information on all failures in your applications. You can click on any of the response codes, exception types or failed dependencies to get more information on these failures. - - ![failures](../../images/failure.png) - -1. Select _Performance_, to see performance data of your applications' operations. This will be a similar view to the one you looked at earlier. - - ![performance](../../images/perf2.png) - -1. Select _Logs_, to see all logged data. You can use Kusto Query Language (KQL) queries to search and analyze the logged data - - * [Log queries in Azure Monitor](https://docs.microsoft.com/azure/azure-monitor/logs/log-query-overview) - - {:style="counter-reset:step-counter 16"} -1. Select _Queries_ and next _Performance_. - -1. Double click _Operations performance_. This will load this query in the query window. - -1. Select _Run_, to see the results of this query. - - ![performance](../../images/performance3.png) - diff --git a/docs/03_lab_monitor/0305.md b/docs/03_lab_monitor/0305.md index 6302760..a9f7ac7 100644 --- a/docs/03_lab_monitor/0305.md +++ b/docs/03_lab_monitor/0305.md @@ -1,5 +1,5 @@ --- -title: '5. Azure Managed Grafana' +title: '4. Azure Managed Grafana' layout: default nav_order: 5 parent: 'Lab 3: Enable monitoring' diff --git a/docs/03_lab_monitor/0306.md b/docs/03_lab_monitor/0306.md index 489f324..7e0a398 100644 --- a/docs/03_lab_monitor/0306.md +++ b/docs/03_lab_monitor/0306.md @@ -1,5 +1,5 @@ --- -title: '6. Review' +title: '5. Review' layout: default nav_order: 6 parent: 'Lab 3: Enable monitoring' @@ -13,7 +13,7 @@ In this lab, you added monitoring to your Spring Petclinic microservices applica - Configured Azure Container Apps environment monitoring - Configured Application Insights to receive monitoring information from your applications - Analyzed application specific monitoring data -- (Optional) Build Java metrics dashboard with Azure Managed Grafana +- Build Java metrics dashboard with Azure Managed Grafana The below image illustrates the end state you have build in this lab. diff --git a/docs/04_lab_secrets/0401.md b/docs/04_lab_secrets/0401.md index b9321cc..508c6d9 100644 --- a/docs/04_lab_secrets/0401.md +++ b/docs/04_lab_secrets/0401.md @@ -17,7 +17,7 @@ You are already using a managed Identity to connect to the Azure Container Regis ```bash DB_ADMIN_USER_ASSIGNED_IDENTITY_NAME=uid-dbadmin-$APPNAME-$UNIQUEID - + ADMIN_IDENTITY_RESOURCE_ID=$(az identity create \ --name $DB_ADMIN_USER_ASSIGNED_IDENTITY_NAME \ --resource-group $RESOURCE_GROUP \ @@ -33,14 +33,11 @@ You are already using a managed Identity to connect to the Azure Container Regis --server-name $MYSQL_SERVER_NAME \ --identity $DB_ADMIN_USER_ASSIGNED_IDENTITY_NAME - az mysql flexible-server identity list \ --resource-group $RESOURCE_GROUP \ - --server-name $MYSQL_SERVER_NAME + --server-name $MYSQL_SERVER_NAME ``` -1. 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. - 1. Next you create a database administrator based on your current user account. ```bash @@ -50,7 +47,11 @@ You are already using a managed Identity to connect to the Azure Container Regis --object-id $AAD_USER_ID \ --display-name $USER_NAME \ --identity $DB_ADMIN_USER_ASSIGNED_IDENTITY_NAME + ``` + +1. Retrieve the database ID for later usage. +```bash DB_ID=$(az mysql flexible-server db show \ --server-name $MYSQL_SERVER_NAME \ --resource-group $RESOURCE_GROUP \ diff --git a/docs/04_lab_secrets/0402.md b/docs/04_lab_secrets/0402.md index c10b9c3..624ba1a 100644 --- a/docs/04_lab_secrets/0402.md +++ b/docs/04_lab_secrets/0402.md @@ -27,103 +27,93 @@ Since each of these apps already has a user assigned managed identity assigned t az extension add --name serviceconnector-passwordless --upgrade ``` -1. You will also need your subscription ID for creating the service connections: +1. Get the subscription id and the managed identity client id in the container apps environment: ```bash SUBID=$(az account show --query id -o tsv) + CLIENT_ID=$(az identity show --resource-group $RESOURCE_GROUP --name $ACA_IDENTITY --query clientId --output tsv) ``` -1. You will also need resource ID of the apps: +1. Create service connection for `customers-service` ```bash - CUSTOMERS_ID=$(az containerapp show \ - --resource-group $RESOURCE_GROUP \ - --name customers-service \ - --query id \ - -o tsv) - - VISITS_ID=$(az containerapp show \ - --resource-group $RESOURCE_GROUP \ - --name visits-service \ - --query id \ - -o tsv) - - VETS_ID=$(az containerapp show \ - --resource-group $RESOURCE_GROUP \ - --name vets-service \ - --query id \ - -o tsv) - ``` - -1. Create now the service connections for the `customers-service`. For this you also need the client ID of the identity you created earlier. + APP_NAME=customers-service + APP_ID=$(az containerapp show \ + --resource-group $RESOURCE_GROUP \ + --name $APP_NAME \ + --query id \ + -o tsv) - ```bash - CLIENT_ID=$(az identity show --resource-group $RESOURCE_GROUP --name $ACA_IDENTITY --query 'clientId' --output tsv) - echo $CLIENT_ID az containerapp connection create mysql-flexible \ --resource-group $RESOURCE_GROUP \ --connection mysql_conn \ - --source-id $CUSTOMERS_ID \ + --source-id $APP_ID \ --target-id $DB_ID \ --client-type SpringBoot \ --user-identity client-id=$CLIENT_ID subs-id=$SUBID mysql-identity-id=$ADMIN_IDENTITY_RESOURCE_ID user-object-id=$AAD_USER_ID \ - -c customers-service + -c $APP_NAME -y ``` 1. You can test the validity of this new connection with the `validate` command: ```bash - CUSTOMERS_CONN_ID=$(az containerapp connection list \ - --resource-group $RESOURCE_GROUP \ - --name customers-service \ - --query [].id -o tsv) - - az containerapp connection validate \ - --id $CUSTOMERS_CONN_ID + CONN_ID=$(az containerapp connection list \ + --resource-group $RESOURCE_GROUP \ + --name $APP_NAME \ + --query [].id -o tsv) + az containerapp connection validate --id $CONN_ID ``` The output of this command should show that the connection was made successful. -1. In the same way create the service connections for the `vets-service` and `visits-service`: +1. In the same way create the service connections for the `vets-service` and `visits-service`, also validate the connection: ```bash + # vets-service + APP_NAME=vets-service + APP_ID=$(az containerapp show \ + --resource-group $RESOURCE_GROUP \ + --name $APP_NAME \ + --query id \ + -o tsv) + az containerapp connection create mysql-flexible \ --resource-group $RESOURCE_GROUP \ --connection mysql_conn \ - --source-id $VETS_ID \ + --source-id $APP_ID \ --target-id $DB_ID \ --client-type SpringBoot \ --user-identity client-id=$CLIENT_ID subs-id=$SUBID mysql-identity-id=$ADMIN_IDENTITY_RESOURCE_ID user-object-id=$AAD_USER_ID \ - -c vets-service + -c $APP_NAME -y + + CONN_ID=$(az containerapp connection list \ + --resource-group $RESOURCE_GROUP \ + --name $APP_NAME \ + --query [].id -o tsv) + az containerapp connection validate --id $CONN_ID + + # visits-service + APP_NAME=visits-service + APP_ID=$(az containerapp show \ + --resource-group $RESOURCE_GROUP \ + --name $APP_NAME \ + --query id \ + -o tsv) az containerapp connection create mysql-flexible \ --resource-group $RESOURCE_GROUP \ --connection mysql_conn \ - --source-id $VISITS_ID \ + --source-id $APP_ID \ --target-id $DB_ID \ --client-type SpringBoot \ --user-identity client-id=$CLIENT_ID subs-id=$SUBID mysql-identity-id=$ADMIN_IDENTITY_RESOURCE_ID user-object-id=$AAD_USER_ID \ - -c visits-service - ``` - -1. You can test the validity of this new connection with the `validate` command: + -c $APP_NAME -y - ```bash - VETS_CONN_ID=$(az containerapp connection list \ - --resource-group $RESOURCE_GROUP \ - --name vets-service \ - --query [].id -o tsv) - - az containerapp connection validate \ - --id $VETS_CONN_ID - - VISITS_CONN_ID=$(az containerapp connection list \ - --resource-group $RESOURCE_GROUP \ - --name visits-service \ - --query [].id -o tsv) - - az containerapp connection validate \ - --id $VISITS_CONN_ID + CONN_ID=$(az containerapp connection list \ + --resource-group $RESOURCE_GROUP \ + --name $APP_NAME \ + --query [].id -o tsv) + az containerapp connection validate --id $CONN_ID ``` 1. In the Azure Portal, navigate to your `customers-service` container app. In the `customers-service` app, select the `Service Connector` menu item. diff --git a/docs/04_lab_secrets/0403.md b/docs/04_lab_secrets/0403.md index 4cc9a44..cd4f3bf 100644 --- a/docs/04_lab_secrets/0403.md +++ b/docs/04_lab_secrets/0403.md @@ -17,34 +17,34 @@ The following three apps of your application use the database hosted by the Azur ## Step by step guidance -1. 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: +1. In the main `pom.xml` file add an additional property between the `` element for the Azure Spring Cloud version we are going to use. ```xml - - com.azure.spring - spring-cloud-azure-starter-jdbc-mysql - + 5.18.0 ``` -1. In the main `pom.xml` file add the Azure BOM as an extra dependency between the `` elements. +1. In the same file add the Azure BOM as an extra dependency between the `` elements. ```xml - com.azure.spring - spring-cloud-azure-dependencies - ${version.spring.cloud.azure} - pom - import + com.azure.spring + spring-cloud-azure-dependencies + ${version.spring.cloud.azure} + pom + import ``` -1. In the same file also add an additional property between the `` element for the Azure Spring Cloud version we are going to use. +1. 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: ```xml - 5.18.0 + + com.azure.spring + spring-cloud-azure-starter-jdbc-mysql + ``` -1. In the config repository there will be no credentials, you may use the config files saved in this repository, under directory config. +1. In the config repository there will be no credentials, you may use the config files saved in the [current repository](https://github.com/Azure-Samples/java-microservices-aca-lab), under directory `config`. Update config server configuration: ```bash diff --git a/docs/05_lab_openai/0501.md b/docs/05_lab_openai/0501.md index babdd82..ab027ee 100644 --- a/docs/05_lab_openai/0501.md +++ b/docs/05_lab_openai/0501.md @@ -5,11 +5,9 @@ nav_order: 1 parent: 'Lab 5: Integrate with Azure OpenAI' --- - To add AI capablities to the application, you need create an Azure OpenAI account and deploy language models. You can use the following guidance: - [Create and deploy an Azure OpenAI Service resource](https://learn.microsoft.com/en-us/azure/ai-services/openai/how-to/create-resource) - # Step by step guidance 1. Create an Azure OpenAI account. Run the following commands to create an Azure OpenAI account. Note that the name of the account must be globally unique, so adjust it accordingly in case the randomly generated name is already in use. @@ -26,6 +24,7 @@ To add AI capablities to the application, you need create an Azure OpenAI accoun ``` 2. Deploy language models in your Azure OpenAI service instance. Use the following commands to deploy two language models `text-embedding-ada-002` and `gpt-4o`. + ```bash az cognitiveservices account deployment create \ --resource-group $RESOURCE_GROUP \ @@ -35,7 +34,7 @@ To add AI capablities to the application, you need create an Azure OpenAI accoun --model-version "2" \ --model-format OpenAI \ --sku-name "Standard" \ - --sku-capacity 1 + --sku-capacity 30 az cognitiveservices account deployment create \ --resource-group $RESOURCE_GROUP \ @@ -45,7 +44,7 @@ To add AI capablities to the application, you need create an Azure OpenAI accoun --model-version 2024-08-06 \ --model-format OpenAI \ --sku-name "GlobalStandard" \ - --sku-capacity 1 + --sku-capacity 30 ``` {: .note } @@ -54,13 +53,13 @@ To add AI capablities to the application, you need create an Azure OpenAI accoun 3. To securely access Azure OpenAI API call, you need assign `Cognitive Services OpenAI User` role for your managed identity. -```bash -OPEN_AI_RESOURCE_ID=$(az cognitiveservices account show --name $OPEN_AI_SERVICE_NAME --resource-group $RESOURCE_GROUP --query id --output tsv) + ```bash + OPEN_AI_RESOURCE_ID=$(az cognitiveservices account show --name $OPEN_AI_SERVICE_NAME --resource-group $RESOURCE_GROUP --query id --output tsv) -SP_ID=$(az identity show --resource-group $RESOURCE_GROUP --name $ACA_IDENTITY --query principalId --output tsv) + SP_ID=$(az identity show --resource-group $RESOURCE_GROUP --name $ACA_IDENTITY --query principalId --output tsv) -az role assignment create \ - --role "Cognitive Services OpenAI User" \ - --scope $OPEN_AI_RESOURCE_ID \ - --assignee $SP_ID -``` \ No newline at end of file + az role assignment create \ + --role "Cognitive Services OpenAI User" \ + --scope $OPEN_AI_RESOURCE_ID \ + --assignee $SP_ID + ``` diff --git a/docs/05_lab_openai/05_openlab_openai_aca.md b/docs/05_lab_openai/05_openlab_openai_aca.md index a0b4934..caa1191 100644 --- a/docs/05_lab_openai/05_openlab_openai_aca.md +++ b/docs/05_lab_openai/05_openlab_openai_aca.md @@ -33,7 +33,7 @@ The below image illustrates the end state you will be building in this lab. During this lab, you will: - Create an Azure Open AI account, and deploy language models -- Deploy a sample AI application, and explore the power of Azure Open AI +- Deploy an AI chat-agent, and explore the power of Azure Open AI {: .note } > The instructions provided in this exercise assume that you successfully completed the previous exercise and are using the same lab environment, including your Git Bash session with the relevant environment variables already set. diff --git a/docs/06_lab_automation/0601.md b/docs/06_lab_automation/0601.md index 736fe82..d2a97b6 100644 --- a/docs/06_lab_automation/0601.md +++ b/docs/06_lab_automation/0601.md @@ -13,7 +13,7 @@ parent: 'Deploy to Azure automatically' Make sure you have both `Contributor` and `User Access Administrator` roles to your target subscription. - Goto your subscription page, select Access control (IAM), then click View my access button to see your role assignments. + Go to your subscription page, select Access control (IAM), then click View my access button to see your role assignments. - Role `Owner` already includes roles `Contributor` and `User Access Administrator`, no role assignment required if you already have the `Owner` role. - Contact your subscription administrator on new role assignments. @@ -35,7 +35,7 @@ parent: 'Deploy to Azure automatically' echo $USER_NAME ``` - - Retrieve the user id. + - Retrieve the user object id. ```bash az ad signed-in-user show --query id --output tsv diff --git a/docs/06_lab_automation/0602.md b/docs/06_lab_automation/0602.md index 85ef4a8..4587c5c 100644 --- a/docs/06_lab_automation/0602.md +++ b/docs/06_lab_automation/0602.md @@ -54,19 +54,23 @@ Run `azd up` to deploy the petclinic solution and dependent components to Azure 1. Visit the api gateway service - Get the spring boot admin url from azd environment variables - `azd env get-values | grep gatewayFqdn` + + `azd env get-values | grep gatewayFqdn` - Visit the api-gateway url: - `api-gateway...azurecontainerapps.io` + + `api-gateway...azurecontainerapps.io` ![api gateway main page](../../images/api-gateway-main.png) 1. Visit the spring boot admin server - Get the spring boot admin url from azd environment variables - `azd env get-values | grep springbootAdminFqdn` + + `azd env get-values | grep springbootAdminFqdn` - Visit the spring boot admin page url: - `springbootadmin-azure-java.ext...azurecontainerapps.io` + + `springbootadmin-azure-java.ext...azurecontainerapps.io` ![spring boot admin](../../images/spring-boot-admin.png) diff --git a/docs/06_lab_automation/0604.md b/docs/06_lab_automation/0604.md index c9cc551..17481d5 100644 --- a/docs/06_lab_automation/0604.md +++ b/docs/06_lab_automation/0604.md @@ -114,16 +114,16 @@ Here are the steps to reuse some azure resource Locate the MySQL flexible server, get the name, group and subscription info of the existing Log Analytics Workspace, add the info to `infra/bicep/main.parameters.json`: ```text - "laWorkspaceExisting": { + "appInsightsExisting": { "value": true }, - "laWorkspaceName": { + "appInsightsName": { "value": "" }, - "laWorkspaceResourceGroup": { + "appInsightsResourceGroup": { "value": "" }, - "laWorkspaceSubscription": { + "appInsightsSubscription": { "value": "" }, ``` diff --git a/docs/06_lab_automation/06_openlab_automation.md b/docs/06_lab_automation/06_openlab_automation.md index c83c995..79d12a1 100644 --- a/docs/06_lab_automation/06_openlab_automation.md +++ b/docs/06_lab_automation/06_openlab_automation.md @@ -40,15 +40,15 @@ During this lab, you will: ## Others - - This version of azd templates includes most operations in: - - [Lab 2: Launch a Spring Apps microservices application to Azure Container Apps]({% link docs/02_lab_launch/02_openlab_setup_aca.md %}) - - [Lab 3: Enable monitoring and end-to-end tracing]({% link docs/03_lab_monitor/03_openlab_monitoring_aca.md %}) - - [Lab 4: Connect to Database securely using identity]({% link docs/04_lab_secrets/04_openlab_secrets_aca.md %}) - - [Lab 5: Integrate with Azure OpenAI]({% link docs/05_lab_openai/05_openlab_openai_aca.md %}) - - - By default, the automation process will create MySQL server admin user password with random string, you can reset the admin password in either way: - - Portal: Go to your MySQL server instance page, navigate to `Overview` and click Reset password - - CLI: `az mysql flexible-server update -g -n --admin-password ""` +- This version of azd templates includes most operations in: + - [Lab 2: Launch a Spring Apps microservices application to Azure Container Apps]({% link docs/02_lab_launch/02_openlab_setup_aca.md %}) + - [Lab 3: Enable monitoring and end-to-end tracing]({% link docs/03_lab_monitor/03_openlab_monitoring_aca.md %}) + - [Lab 4: Connect to Database securely using identity]({% link docs/04_lab_secrets/04_openlab_secrets_aca.md %}) + - [Lab 5: Integrate with Azure OpenAI]({% link docs/05_lab_openai/05_openlab_openai_aca.md %}) + +- By default, the automation process will create MySQL server admin password with random string, you can reset the admin password in either way: + - Portal: Go to your MySQL server instance page, navigate to `Overview` and click Reset password + - CLI: `az mysql flexible-server update -g -n --admin-password ""` {: .note } > The instructions provided in this exercise assume that you successfully completed the previous exercise and are using the same lab environment, including your Git Bash session with the relevant environment variables already set. diff --git a/docs/10_lab_reliable_application/1002.md b/docs/10_lab_reliable_application/1002.md index 6fa10fc..0c0f3a7 100644 --- a/docs/10_lab_reliable_application/1002.md +++ b/docs/10_lab_reliable_application/1002.md @@ -79,16 +79,21 @@ public class ServiceHealthIndicator implements HealthIndicator { } } ``` -In this sample, the code `ServiceHealthIndicator` will report health status `UP` only after some db operation is ready. This can be helpful in some scenarios where you application needs some warmup (e.g. cache/db preload) time before receiving traffic. +In this sample, the code `ServiceHealthIndicator` will report health status `UP` only after some db operation is ready. This can be helpful in some scenarios where you application needs some warmup (e.g. cache/db preload) time before receiving traffic. ### 3. Config Health probes in Azure Container Apps Health probes can be configed via either Portal or [ARM template](https://learn.microsoft.com/en-us/azure/container-apps/health-probes?tabs=arm-template). -- Portal: Find the application `customers-service` -> Go to the `Revisions blade` -> Create a new revision -> Save this new revision. -![lab 10 health probes](../../images/lab10-liveness-probe.png) -![lab 10 readiness probes](../../images/lab10-readiness-probe.png) +- Portal: Find the application `customers-service` -> Go to the `Revisions blade` -> Create a new revision. + + In the Container tab, select and edit the container, in the pop out window, check the settings in `Health Probes`. + + The screenshots of the liveness and readiness probes. + + ![lab 10 health probes](../../images/lab10-liveness-probe.png) + ![lab 10 readiness probes](../../images/lab10-readiness-probe.png) Here, we set the `initial delay seconds` in readiness probe to 10 seconds, which align with the above health check logic in `ServiceHealthIndicator`. diff --git a/images/spring-boot-admin.png b/images/spring-boot-admin.png index 4ff3c52..90d71b5 100644 Binary files a/images/spring-boot-admin.png and b/images/spring-boot-admin.png differ diff --git a/src/build-update-apps.sh b/src/build-update-apps.sh deleted file mode 100755 index a2e0f2d..0000000 --- a/src/build-update-apps.sh +++ /dev/null @@ -1,49 +0,0 @@ -#!/usr/bin/env bash - -DIR=/tmp - -build_and_deploy() { - APP_NAME=$1 - - echo "Start building and deploying app $APP_NAME with application insights agent ..." - - az acr build -g $RESOURCE_GROUP --registry $MYACR \ - --image spring-petclinic-$APP_NAME:$IMAGE_TAG \ - --file spring-petclinic-$APP_NAME/ai.Dockerfile spring-petclinic-$APP_NAME \ - > $DIR/$APP_NAME.build.log 2>&1 - if [[ $? -ne 0 ]]; then - echo "Build image for $APP_NAME failed, check $DIR/$APP_NAME.build.log for more details" - return 1 - fi - - az containerapp update \ - --name $APP_NAME \ - --resource-group $RESOURCE_GROUP \ - --image $MYACR.azurecr.io/spring-petclinic-$APP_NAME:$IMAGE_TAG \ - --set-env-vars APPLICATIONINSIGHTS_CONNECTION_STRING=$AI_CONNECTIONSTRING APPLICATIONINSIGHTS_CONFIGURATION_CONTENT='{"role": {"name": "'$APP_NAME'"}}' \ - > $DIR/$APP_NAME.deploy.log 2>&1 - - if [[ $? -ne 0 ]]; then - echo "Deploy app $APP_NAME failed, check $DIR/$APP_NAME.deploy.log for more details" - return 2 - fi - - return 0 -} - -CHECK_FAIL=$DIR/aca-lab.$$ - -for name in customers-service vets-service visits-service; do - build_and_deploy $name || touch $CHECK_FAIL & -done - -wait < <(jobs -p) - -if [[ -f $CHECK_FAIL ]]; then - echo "Error happens on build and depploy apps, please check the logs for more details" - exit 1 -else - echo "Build and deploy apps succeed" - exit 0 -fi - diff --git a/tools/Dockerfile b/tools/Dockerfile new file mode 100644 index 0000000..392c147 --- /dev/null +++ b/tools/Dockerfile @@ -0,0 +1,11 @@ +# syntax=docker/dockerfile:1 + +# run +FROM mcr.microsoft.com/openjdk/jdk:17-distroless + +COPY ./target/*.jar app.jar + +EXPOSE 8080 + +# Run the jar file +ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "/app.jar"] diff --git a/tools/ai.Dockerfile b/tools/ai.Dockerfile new file mode 100644 index 0000000..a5292b0 --- /dev/null +++ b/tools/ai.Dockerfile @@ -0,0 +1,23 @@ +# syntax=docker/dockerfile:1 + +# build +FROM mcr.microsoft.com/openjdk/jdk:17-mariner AS build + +ARG AI_VERSION=3.5.4 + +RUN yum update -y && \ + yum install -y wget + +RUN wget https://github.com/microsoft/ApplicationInsights-Java/releases/download/$AI_VERSION/applicationinsights-agent-$AI_VERSION.jar -O ai.jar --quiet + +# run +FROM mcr.microsoft.com/openjdk/jdk:17-distroless + +COPY --from=build ./ai.jar ai.jar + +COPY ./target/*.jar app.jar + +EXPOSE 8080 + +# Run the jar file +ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-javaagent:/ai.jar", "-jar", "/app.jar"] diff --git a/src/create-apps.sh b/tools/create-apps.sh similarity index 94% rename from src/create-apps.sh rename to tools/create-apps.sh index 0612ed5..d73c20a 100755 --- a/src/create-apps.sh +++ b/tools/create-apps.sh @@ -9,6 +9,8 @@ create_app() { echo "Start creating app $APP_NAME ..." + cp -f ../tools/ai.Dockerfile spring-petclinic-$APP_NAME/Dockerfile + az containerapp create \ --name $APP_NAME \ --resource-group $RESOURCE_GROUP \ diff --git a/tools/update-apps-passwordless.sh b/tools/update-apps-passwordless.sh new file mode 100755 index 0000000..e0221fc --- /dev/null +++ b/tools/update-apps-passwordless.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash + +DIR=/tmp + +PROFILE=passwordless + +update_app_passwordless() { + APP_NAME=$1 + + echo "Start updating app $APP_NAME with application insights agent ..." + + cp -f ../tools/ai.Dockerfile ./spring-petclinic-$APP_NAME/Dockerfile + + az containerapp update \ + --name $APP_NAME \ + --resource-group $RESOURCE_GROUP \ + --source ./spring-petclinic-$APP_NAME \ + --set-env-vars SPRING_PROFILES_ACTIVE=$PROFILE \ + > $DIR/$APP_NAME.update.log 2>&1 + + if [[ $? -ne 0 ]]; then + echo "Update app $APP_NAME failed, check $DIR/$APP_NAME.update.log for more details" + return 2 + fi + + return 0 +} + +CHECK_FAIL=$DIR/aca-lab.$$ + +for name in customers-service vets-service visits-service; do + update_app_passwordless $name || touch $CHECK_FAIL & +done + +wait < <(jobs -p) + +if [[ -f $CHECK_FAIL ]]; then + echo "Error happens on update apps, please check the logs for more details" + exit 1 +else + echo "Update apps succeed" + exit 0 +fi + diff --git a/tools/update-apps.sh b/tools/update-apps.sh new file mode 100755 index 0000000..54d9a2c --- /dev/null +++ b/tools/update-apps.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash + +DIR=/tmp + +update_app_with_ai() { + APP_NAME=$1 + + echo "Start updating app $APP_NAME with application insights agent ..." + + cp -f ../tools/ai.Dockerfile ./spring-petclinic-$APP_NAME/Dockerfile + + az containerapp update \ + --name $APP_NAME \ + --resource-group $RESOURCE_GROUP \ + --source ./spring-petclinic-$APP_NAME \ + > $DIR/$APP_NAME.update.log 2>&1 + + if [[ $? -ne 0 ]]; then + echo "Update app $APP_NAME failed, check $DIR/$APP_NAME.update.log for more details" + return 2 + fi + + return 0 +} + +CHECK_FAIL=$DIR/aca-lab.$$ + +for name in customers-service vets-service visits-service; do + update_app_with_ai $name || touch $CHECK_FAIL & +done + +wait < <(jobs -p) + +if [[ -f $CHECK_FAIL ]]; then + echo "Error happens on update apps, please check the logs for more details" + exit 1 +else + echo "Update apps succeed" + exit 0 +fi +