/acme_fitness_demo

Deploys ACME Fitness application across different environments

Primary LanguageCSSMIT LicenseMIT

page_type languages products description urlFragment
sample
java
Azure Spring Cloud
Azure Database for PostgresSQL
Azure Cache for Redis
Azure Active Directory
Deploy Microservice Apps to Azure

Deploy Microservice Applications to Azure Spring Cloud

Azure Spring cloud enables you to easily run Spring Boot and polyglot applications on Azure.

This quickstart shows you how to deploy existing microservices written in Java, Python, and C# to Azure. When you're finished, you can continue to manage the application via the Azure CLI or switch to using the Azure Portal.

What will you experience

You will:

  • Provision an Azure Spring Cloud service instance.
  • Configure Application Configuration Service repositories
  • Deploy polyglot applications to Azure and build using Tanzu Build Service
  • Configure routing to the applications using Spring Cloud Gateway
  • Open the application
  • Explore the application API with Api Portal
  • Configure Single Sign On (SSO) for the application
  • Monitor applications
  • Automate provisioning and deployments using GitHub Actions

The following diagram shows the architecture of the ACME Fitness Store that will be used for this guide:

What you will need

In order to deploy a Java app to cloud, you need an Azure subscription. If you do not already have an Azure subscription, you can activate your MSDN subscriber benefits or sign up for a free Azure account.

In addition, you will need the following:

| Azure CLI version 2.17.1 or higher | Git | jq utility |

Note - The jq utility. On Windows, download this Windows port of JQ and add the following to the ~/.bashrc file:

alias jq=<JQ Download location>/jq-win64.exe

Note - The Bash shell. While Azure CLI should behave identically on all environments, shell semantics vary. Therefore, only bash can be used with the commands in this repo. To complete these repo steps on Windows, use Git Bash that accompanies the Windows distribution of Git. Use only Git Bash to complete this training on Windows. Do not use WSL.

OR Use Azure Cloud Shell

Or, you can use the Azure Cloud Shell. Azure hosts Azure Cloud Shell, an interactive shell environment that you can use through your browser. You can use the Bash with Cloud Shell to work with Azure services. You can use the Cloud Shell pre-installed commands to run the code in this README without having to install anything on your local environment. To start Azure Cloud Shell: go to https://shell.azure.com, or select the Launch Cloud Shell button to open Cloud Shell in your browser.

To run the code in this article in Azure Cloud Shell:

  1. Start Cloud Shell.

  2. Select the Copy button on a code block to copy the code.

  3. Paste the code into the Cloud Shell session by selecting Ctrl+Shift+V on Windows and Linux or by selecting Cmd+Shift+V on macOS.

  4. Select Enter to run the code.

Install the Azure CLI extension

Install the Azure Spring Cloud extension for the Azure CLI using the following command

az extension add --name spring-cloud

Note - spring-cloud CLI extension 3.0.0 or later is a pre-requisite to enable the latest Enterprise tier functionality to configure VMware Tanzu Components. Use the following command to remove previous versions and install the latest Enterprise tier extension:

az extension remove --name spring-cloud
az extension add --name spring-cloud

Clone the repo

Create a new folder and clone the sample app repository to your Azure Cloud account

mkdir source-code
cd source-code
git clone --branch Azure https://github.com/spring-cloud-services-samples/acme_fitness_demo
cd acme_fitness_demo

Unit 1 - Deploy and Build Applications

Prepare your environment for deployments

Create a bash script with environment variables by making a copy of the supplied template:

cp ./azure/setup-env-variables-template.sh ./azure/setup-env-variables.sh

Open ./azure/setup-env-variables.sh and enter the following information:

export SUBSCRIPTION=subscription-id                 # replace it with your subscription-id
export RESOURCE_GROUP=resource-group-name           # existing resource group or one that will be created in next steps
export SPRING_CLOUD_SERVICE=azure-spring-cloud-name # name of the service that will be created in the next steps
export LOG_ANALYTICS_WORKSPACE=log-analytics-name   # existing workspace or one that will be created in next steps
export POSTGRES_SERVER_USER=change-name             # Postgres server username to be created in next steps
export POSTGRES_SERVER_PASSWORD=change-name         # Postgres server password to be created in next steps
export REGION=region-name                           # choose a region with Enterprise tier support

Then, set the environment:

source ./azure/setup-env-variables.sh

Login to Azure

Login to the Azure CLI and choose your active subscription. Be sure to choose the active subscription that is whitelisted for Azure Spring Cloud

az login
az account list -o table
az account set --subscription ${SUBSCRIPTION}

Create Azure Spring Cloud service instance

Prepare a name for your Azure Spring Cloud service. The name must be between 4 and 32 characters long and can contain only lowercase letters, numbers, and hyphens. The first character of the service name must be a letter and the last character must be either a letter or a number.

Create a resource group to contain your Azure Spring Cloud service.

Note: This step can be skipped if using an existing resource group

az group create --name ${RESOURCE_GROUP} \
    --location ${REGION}

Accept the legal terms and privacy statements for the Enterprise tier.

Note: This step is necessary only if your subscription has never been used to create an Enterprise tier instance of Azure Spring Cloud.

az provider register --namespace Microsoft.SaaS
az term accept --publisher vmware-inc --product azure-spring-cloud-vmware-tanzu-2 --plan tanzu-asc-ent-mtr

Create an instance of Azure Spring Cloud Enterprise.

az spring-cloud create --name ${SPRING_CLOUD_SERVICE} \
    --resource-group ${RESOURCE_GROUP} \
    --location ${REGION} \
    --sku Enterprise \
    --enable-application-configuration-service \
    --enable-service-registry \
    --enable-gateway \
    --enable-api-portal

The service instance will take around 10-15 minutes to deploy.

Set your default resource group name and cluster name using the following commands:

az configure --defaults \
    group=${RESOURCE_GROUP} \
    location=${REGION} \
    spring-cloud=${SPRING_CLOUD_SERVICE}

Create Azure Cache for Redis

Create an instance of Azure Cache for Redis using the Azure CLI.

az redis create \
  --name ${AZURE_CACHE_NAME} \
  --location ${REGION} \
  --resource-group ${RESOURCE_GROUP} \
  --sku Basic \
  --vm-size c0

Create an Azure Database for Postgres

Using the Azure CLI, create an Azure Database for Postgres Flexible Server:

az postgres flexible-server create --name ${POSTGRES_SERVER} \
    --resource-group ${RESOURCE_GROUP} \
    --location ${REGION} \
    --admin-user ${POSTGRES_SERVER_USER} \
    --admin-password ${POSTGRES_SERVER_PASSWORD} \
    --yes

# Allow connections from other Azure Services
az postgres flexible-server firewall-rule create --rule-name allAzureIPs \
     --name ${POSTGRES_SERVER} \
     --resource-group ${RESOURCE_GROUP} \
     --start-ip-address 0.0.0.0 --end-ip-address 0.0.0.0
     
# Enable the uuid-ossp extension
az postgres flexible-server parameter set \
    --resource-group ${RESOURCE_GROUP} \
    --server-name ${POSTGRES_SERVER} \
    --name azure.extensions --value uuid-ossp

Create a database for the order service:

az postgres flexible-server db create \
  --database-name ${ORDER_SERVICE_DB} \
  --server-name ${POSTGRES_SERVER}

Create a database for the catalog service:

az postgres flexible-server db create \
  --database-name ${CATALOG_SERVICE_DB} \
  --server-name ${POSTGRES_SERVER}

Note: wait for all services to be ready before continuing

Configure Log Analytics for Azure Spring Cloud

Create a Log Analytics Workspace to be used for your Azure Spring Cloud service.

Note: This step can be skipped if using an existing workspace

az monitor log-analytics workspace create \
  --workspace-name ${LOG_ANALYTICS_WORKSPACE} \
  --location ${REGION} \
  --resource-group ${RESOURCE_GROUP}   

Retrieve the resource ID for the recently create Azure Spring Cloud Service and Log Analytics Workspace:

export LOG_ANALYTICS_RESOURCE_ID=$(az monitor log-analytics workspace show \
    --resource-group ${RESOURCE_GROUP} \
    --workspace-name ${LOG_ANALYTICS_WORKSPACE} | jq -r '.id')

export SPRING_CLOUD_RESOURCE_ID=$(az spring-cloud show \
    --name ${SPRING_CLOUD_SERVICE} \
    --resource-group ${RESOURCE_GROUP} | jq -r '.id')

Configure diagnostic settings for the Azure Spring Cloud Service:

az monitor diagnostic-settings create --name "send-logs-and-metrics-to-log-analytics" \
    --resource ${SPRING_CLOUD_RESOURCE_ID} \
    --workspace ${LOG_ANALYTICS_RESOURCE_ID} \
    --logs '[
         {
           "category": "ApplicationConsole",
           "enabled": true,
           "retentionPolicy": {
             "enabled": false,
             "days": 0
           }
         },
         {
            "category": "SystemLogs",
            "enabled": true,
            "retentionPolicy": {
              "enabled": false,
              "days": 0
            }
          },
         {
            "category": "IngressLogs",
            "enabled": true,
            "retentionPolicy": {
              "enabled": false,
              "days": 0
             }
           }
       ]' \
       --metrics '[
         {
           "category": "AllMetrics",
           "enabled": true,
           "retentionPolicy": {
             "enabled": false,
             "days": 0
           }
         }
       ]'

Configure Application Configuration Service

Create a configuration repository for Application Configuration Service using the Azure CLI:

az spring-cloud application-configuration-service git repo add --name acme-fitness-store-config \
    --label Azure \
    --patterns "catalog/default,catalog/key-vault,identity/default,identity/key-vault,payment/default" \
    --uri "https://github.com/spring-cloud-services-samples/acme_fitness_demo" \
    --search-paths config

Configure Tanzu Build Service

Create a custom builder in Tanzu Build Service using the Azure CLI:

az spring-cloud build-service builder create -n ${CUSTOM_BUILDER} \
    --builder-file azure/builder.json \
    --no-wait

Create applications in Azure Spring Cloud

Create an application for each service:

az spring-cloud app create --name ${CART_SERVICE_APP} --instance-count 1 --memory 1Gi
az spring-cloud app create --name ${ORDER_SERVICE_APP} --instance-count 1 --memory 1Gi
az spring-cloud app create --name ${PAYMENT_SERVICE_APP} --instance-count 1 --memory 1Gi
az spring-cloud app create --name ${CATALOG_SERVICE_APP} --instance-count 1 --memory 1Gi
az spring-cloud app create --name ${FRONTEND_APP} --instance-count 1 --memory 1Gi

Bind to Application Configuration Service

Several applications require configuration from Application Configuration Service, so create the bindings:

az spring-cloud application-configuration-service bind --app ${PAYMENT_SERVICE_APP}
az spring-cloud application-configuration-service bind --app ${CATALOG_SERVICE_APP}

Bind to Service Registry

Several application require service discovery using Service Registry, so create the bindings:

az spring-cloud service-registry bind --app ${PAYMENT_SERVICE_APP}
az spring-cloud service-registry bind --app ${CATALOG_SERVICE_APP}

Create Service Connectors

The Order Service and Catalog Service use Azure Database for Postgres, create Service Connectors for those applications:

# Bind order service to Postgres
az spring-cloud connection create postgres-flexible \
    --resource-group ${RESOURCE_GROUP} \
    --service ${SPRING_CLOUD_SERVICE} \
    --connection ${ORDER_SERVICE_DB_CONNECTION} \
    --app ${ORDER_SERVICE_APP} \
    --deployment default \
    --tg ${RESOURCE_GROUP} \
    --server ${POSTGRES_SERVER} \
    --database ${ORDER_SERVICE_DB} \
    --secret name=${POSTGRES_SERVER_USER} secret=${POSTGRES_SERVER_PASSWORD} \
    --client-type dotnet
    

# Bind catalog service to Postgres
az spring-cloud connection create postgres-flexible \
    --resource-group ${RESOURCE_GROUP} \
    --service ${SPRING_CLOUD_SERVICE} \
    --connection ${CATALOG_SERVICE_DB_CONNECTION} \
    --app ${CATALOG_SERVICE_APP} \
    --deployment default \
    --tg ${RESOURCE_GROUP} \
    --server ${POSTGRES_SERVER} \
    --database ${CATALOG_SERVICE_DB} \
    --secret name=${POSTGRES_SERVER_USER} secret=${POSTGRES_SERVER_PASSWORD} \
    --client-type springboot

The Cart Service requires a connection to Azure Cache for Redis, create the Service Connector:

az spring-cloud connection create redis \
    --resource-group ${RESOURCE_GROUP} \
    --service ${SPRING_CLOUD_SERVICE} \
    --connection $CART_SERVICE_CACHE_CONNECTION \
    --app ${CART_SERVICE_APP} \
    --deployment default \
    --tg ${RESOURCE_GROUP} \
    --server ${AZURE_CACHE_NAME} \
    --database 0 \
    --client-type java 

Configure Spring Cloud Gateway

Assign an endpoint and update the Spring Cloud Gateway configuration with API information:

az spring-cloud gateway update --assign-endpoint true
export GATEWAY_URL=$(az spring-cloud gateway show | jq -r '.properties.url')
    
az spring-cloud gateway update \
    --api-description "Acme Fitness Store API" \
    --api-title "Acme Fitness Store" \
    --api-version "v1.0" \
    --server-url "https://${GATEWAY_URL}" \
    --allowed-origins "*"

Create routing rules for the applications:

az spring-cloud gateway route-config create \
    --name ${CART_SERVICE_APP} \
    --app-name ${CART_SERVICE_APP} \
    --routes-file azure/routes/cart-service.json
    
az spring-cloud gateway route-config create \
    --name ${ORDER_SERVICE_APP} \
    --app-name ${ORDER_SERVICE_APP} \
    --routes-file azure/routes/order-service.json

az spring-cloud gateway route-config create \
    --name ${CATALOG_SERVICE_APP} \
    --app-name ${CATALOG_SERVICE_APP} \
    --routes-file azure/routes/catalog-service.json

az spring-cloud gateway route-config create \
    --name ${FRONTEND_APP} \
    --app-name ${FRONTEND_APP} \
    --routes-file azure/routes/frontend.json

Build and Deploy Polyglot Applications

Deploy and build each application, specifying its required parameters

# Deploy Payment Service
az spring-cloud app deploy --name ${PAYMENT_SERVICE_APP} \
    --config-file-pattern payment/default \
    --source-path apps/acme-payment

# Deploy Catalog Service
az spring-cloud app deploy --name ${CATALOG_SERVICE_APP} \
    --config-file-pattern catalog/default \
    --source-path apps/acme-catalog

# Deploy Order Service after retrieving the database connection info
export POSTGRES_CONNECTION_STR=$(az spring-cloud connection show -g ${RESOURCE_GROUP} \
    --service ${SPRING_CLOUD_SERVICE} \
    --deployment default \
    --connection ${ORDER_SERVICE_DB_CONNECTION} \
    --app ${ORDER_SERVICE_APP} | jq '.configurations[0].value' -r)

az spring-cloud app deploy --name ${ORDER_SERVICE_APP} \
    --builder ${CUSTOM_BUILDER} \
    --env "DatabaseProvider=Postgres" "ConnectionStrings__OrderContext=${POSTGRES_CONNECTION_STR}" \
    --source-path apps/acme-order

# Deploy the Cart Service after retrieving the cache connection info
export REDIS_CONN_STR=$(az spring-cloud connection show -g ${RESOURCE_GROUP} \
    --service ${SPRING_CLOUD_SERVICE} \
    --deployment default \
    --app ${CART_SERVICE_APP} \
    --connection $CART_SERVICE_CACHE_CONNECTION | jq -r '.configurations[0].value')

az spring-cloud app deploy --name ${CART_SERVICE_APP} \
    --builder ${CUSTOM_BUILDER} \
    --env "CART_PORT=8080" "REDIS_CONNECTIONSTRING=${REDIS_CONN_STR}" \
    --source-path apps/acme-cart

# Deploy Frontend App
az spring-cloud app deploy --name ${FRONTEND_APP} \
    --builder ${CUSTOM_BUILDER} \
    --source-path apps/acme-shopping

Access the Application through Spring Cloud Gateway

Retrieve the URL for Spring Cloud Gateway and open it in a browser:

open "https://${GATEWAY_URL}"

You should see the ACME Fitness Store Application:

An image of the ACME Fitness Store Application homepage

Explore the application, but notice that not everything is functioning yet. Continue on to Unit 2 to configure Single Sign On to enable the rest of the functionality.

Explore the API using API Portal

Assign an endpoint to API Portal and open it in a browser:

az spring-cloud api-portal update --assign-endpoint true
export PORTAL_URL=$(az spring-cloud api-portal show | jq -r '.properties.url')

open "https://${PORTAL_URL}"

Unit 2 - Configure Single Sign On

The following section steps through creating a Single Sign On Provider using Azure AD. To use an existing provider, skip ahead to Using an Existing SSO Provider

Register Application with Azure AD

Create an Application registration with Azure AD and save the output.

az ad app create --display-name acme-fitness-store > ad.json

Retrieve the Application ID and collect the client secret:

export APPLICATION_ID=$(cat ad.json | jq -r '.appId')

az ad app credential reset --id ${APPLICATION_ID} --append > sso.json

Assign a Service Principal to the Application Registration

az ad sp create --id ${APPLICATION_ID}

More detailed instructions on Application Registrations can be found here.

Prepare your environment for deployments

Set the environment using the provided script and verify the environment variables are set:

source ./azure/setup-sso-variables-ad.sh

echo ${CLIENT_ID}
echo ${CLIENT_SECRET}
echo ${TENANT_ID}
echo ${ISSUER_URI}
echo ${JWK_SET_URI}

The ISSUER_URI should take the form https://login.microsoftonline.com/${TENANT_ID}/v2.0 The JWK_SET_URI should take the form https://login.microsoftonline.com/${TENANT_ID}/discovery/v2.0/keys

Add the necessary redirect URIs to the Azure AD Application Registration:

az ad app update --id ${APPLICATION_ID} \
    --reply-urls "https://${GATEWAY_URL}/login/oauth2/code/sso" "https://${PORTAL_URL}/oauth2-redirect.html" "https://${PORTAL_URL}/login/oauth2/code/sso"

Detailed information about redirect URIs can be found here.

Using an Existing SSO Identity Provider

Note: Continue on to Configure Spring Cloud Gateway with SSO if you just created an Azure AD Application Registration

To use an existing SSO Identity Provider, copy the existing template

cp ./azure/setup-sso-variables-template.sh ./azure/setup-sso-variables.sh

Open ./azure/setup-sso-variables.sh and provide the required information.

export CLIENT_ID=change-me        # Your SSO Provider Client ID
export CLIENT_SECRET=change-me    # Your SSO Provider Client Secret
export ISSUER_URI=change-me       # Your SSO Provider Issuer URI
export JWK_SET_URI=change-me      # Your SSO Provider Json Web Token URI

The issuer-uri configuration should follow Spring Boot convention, as described in the official Spring Boot documentation: The provider needs to be configured with an issuer-uri which is the URI that the it asserts as its Issuer Identifier. For example, if the issuer-uri provided is "https://example.com", then an OpenID Provider Configuration Request will be made to "https://example.com/.well-known/openid-configuration". The result is expected to be an OpenID Provider Configuration Response. Note that only authorization servers supporting OpenID Connect Discovery protocol can be used

The JWK_SET_URI typically takes the form ${SSUER_URI}/$VERSION/keys

Set the environment:

source ./azure/setup-sso-variables.sh

Add the following to your SSO provider's list of approved redirect URIs:

echo "https://${GATEWAY_URL}/login/oauth2/code/sso"
echo "https://${PORTAL_URL}/oauth2-redirect.html" 
echo "https://${PORTAL_URL}/login/oauth2/code/sso"

Configure Spring Cloud Gateway with SSO

Configure Spring Cloud Gateway with SSO enabled:

export GATEWAY_URL=$(az spring-cloud gateway show | jq -r '.properties.url')

az spring-cloud gateway update \
    --api-description "ACME Fitness Store API" \
    --api-title "ACME Fitness Store" \
    --api-version "v1.0" \
    --server-url "https://${GATEWAY_URL}" \
    --allowed-origins "*" \
    --client-id ${CLIENT_ID} \
    --client-secret ${CLIENT_SECRET} \
    --scope ${SCOPE} \
    --issuer-uri ${ISSUER_URI}

Deploy the Identity Service Application

Create the identity service application

az spring-cloud app create --name ${IDENTITY_SERVICE_APP} --instance-count 1 --memory 1Gi

Bind the identity service to Application Configuration Service

az spring-cloud application-configuration-service bind --app ${IDENTITY_SERVICE_APP}

Bind the identity service to Service Registry.

az spring-cloud service-registry bind --app ${IDENTITY_SERVICE_APP}

Create routing rules for the identity service application

az spring-cloud gateway route-config create \
    --name ${IDENTITY_SERVICE_APP} \
    --app-name ${IDENTITY_SERVICE_APP} \
    --routes-file azure/routes/identity-service.json

Deploy the Identity Service:

az spring-cloud app deploy --name ${IDENTITY_SERVICE_APP} \
    --env "JWK_URI=${JWK_SET_URI}" \
    --config-file-pattern identity/default \
    --source-path apps/acme-identity

Update Existing Applications

Update the existing applications to use authorization information from Spring Cloud Gateway:

# Update the Cart Service
az spring-cloud app update --name ${CART_SERVICE_APP} \
    --env "AUTH_URL=https://${GATEWAY_URL}" "CART_PORT=8080" "REDIS_CONNECTIONSTRING=${REDIS_CONN_STR}"
    
# Update the Order Service
az spring-cloud app  update --name ${ORDER_SERVICE_APP} \
    --env "AcmeServiceSettings__AuthUrl=https://${GATEWAY_URL}" "ConnectionStrings__OrderContext=$POSTGRES_CONNECTION_STR"

Access the Application through Spring Cloud Gateway

Retrieve the URL for Spring Cloud Gateway and open it in a browser:

open "https://${GATEWAY_URL}"

You should see the ACME Fitness Store Application, and be able to log in using your SSO Credentials. Once logged in, the remaining functionality of the application will be available. This includes adding items to the cart and placing an order.

Configure SSO for API Portal

Configure API Portal with SSO enabled:

export PORTAL_URL=$(az spring-cloud api-portal show | jq -r '.properties.url')

az spring-cloud api-portal update \
    --client-id ${CLIENT_ID} \
    --client-secret ${CLIENT_SECRET}\
    --scope "openid,profile,email" \
    --issuer-uri ${ISSUER_URI}

Explore the API using API Portal

Open API Portal in a browser, this will redirect you to log in now:

open "https://${PORTAL_URL}"

To access the protected APIs, click Authorize and follow the steps that match your SSO provider. Learn more about API Authorization with API Portal here

Unit 3 - Securely Load Application Secrets

Use Azure Key Vault to store and load secrets to connect to Azure services.

Prepare your environment for Key Vault

Create a bash script with environment variables by making a copy of the supplied template:

cp ./azure/setup-env-variables-keyvault-template.sh ./azure/setup-env-variables-keyvault.sh

Open ./azure/setup-env-variables-keyvault.sh and enter the following information:

export KEY_VAULT=change-me      # customize this

Set the Environment.

source ./azure/setup-env-variables-keyvault.sh

Create Azure Key Vault and store secrets

Create an Azure Key Vault and store connection secrets.

az keyvault create --name ${KEY_VAULT} -g ${RESOURCE_GROUP}
export KEYVAULT_URI=$(az keyvault show --name ${KEY_VAULT} | jq -r '.properties.vaultUri')

Store database connection secrets in Key Vault.

export POSTGRES_SERVER_FULL_NAME="${POSTGRES_SERVER}.postgres.database.azure.com"

az keyvault secret set --vault-name ${KEY_VAULT} \
    --name "POSTGRES-SERVER-NAME" --value ${POSTGRES_SERVER_FULL_NAME}

az keyvault secret set --vault-name ${KEY_VAULT} \
    --name "ConnectionStrings--OrderContext" --value "Server=${POSTGRES_SERVER_FULL_NAME};Database=${ORDER_SERVICE_DB};Port=5432;Ssl Mode=Require;User Id=${POSTGRES_SERVER_USER};Password=${POSTGRES_SERVER_PASSWORD};"
    
az keyvault secret set --vault-name ${KEY_VAULT} \
    --name "CATALOG-DATABASE-NAME" --value ${CATALOG_SERVICE_DB}
    
az keyvault secret set --vault-name ${KEY_VAULT} \
    --name "POSTGRES-LOGIN-NAME" --value ${POSTGRES_SERVER_USER}
    
az keyvault secret set --vault-name ${KEY_VAULT} \
    --name "POSTGRES-LOGIN-PASSWORD" --value ${POSTGRES_SERVER_PASSWORD}

Retrieve and store redis connection secrets in Key Vault.

az redis show -n ${AZURE_CACHE_NAME} > redis.json
export REDIS_HOST=$(cat redis.json | jq -r '.hostName')
export REDIS_PORT=$(cat redis.json | jq -r '.sslPort')

export REDIS_PRIMARY_KEY=$(az redis list-keys -n ${AZURE_CACHE_NAME} | jq -r '.primaryKey')

az keyvault secret set --vault-name ${KEY_VAULT} \
  --name "CART-REDIS-CONNECTION-STRING" --value "rediss://:${REDIS_PRIMARY_KEY}@${REDIS_HOST}:${REDIS_PORT}/0"

Store SSO Secrets in Key Vault.

az keyvault secret set --vault-name ${KEY_VAULT} \
    --name "SSO-PROVIDER-JWK-URI" --value ${JWK_SET_URI}

Enable System Assigned Identities for applications and export identities to environment.

az spring-cloud app identity assign --name ${CART_SERVICE_APP}
export CART_SERVICE_APP_IDENTITY=$(az spring-cloud app show --name ${CART_SERVICE_APP} | jq -r '.identity.principalId')

az spring-cloud app identity assign --name ${ORDER_SERVICE_APP}
export ORDER_SERVICE_APP_IDENTITY=$(az spring-cloud app show --name ${ORDER_SERVICE_APP} | jq -r '.identity.principalId')

az spring-cloud app identity assign --name ${CATALOG_SERVICE_APP}
export CATALOG_SERVICE_APP_IDENTITY=$(az spring-cloud app show --name ${CATALOG_SERVICE_APP} | jq -r '.identity.principalId')

az spring-cloud app identity assign --name ${IDENTITY_SERVICE_APP}
export IDENTITY_SERVICE_APP_IDENTITY=$(az spring-cloud app show --name ${IDENTITY_SERVICE_APP} | jq -r '.identity.principalId')

az spring-cloud app identity assign --name ${FRONTEND_APP}
export FRONTEND_APP_IDENTITY=$(az spring-cloud app show --name ${FRONTEND_APP} | jq -r '.identity.principalId')

Add an access policy to Azure Key Vault to allow Managed Identities to read secrets.

az keyvault set-policy --name ${KEY_VAULT} \
    --object-id ${CART_SERVICE_APP_IDENTITY} --secret-permissions get list
    
az keyvault set-policy --name ${KEY_VAULT} \
    --object-id ${ORDER_SERVICE_APP_IDENTITY} --secret-permissions get list

az keyvault set-policy --name ${KEY_VAULT} \
    --object-id ${CATALOG_SERVICE_APP_IDENTITY} --secret-permissions get list

az keyvault set-policy --name ${KEY_VAULT} \
    --object-id ${IDENTITY_SERVICE_APP_IDENTITY} --secret-permissions get list

az keyvault set-policy --name ${KEY_VAULT} \
    --object-id ${FRONTEND_APP_IDENTITY} --secret-permissions get list

Activate applications to load secrets from Azure Key Vault

Delete Service Connectors and activate applications to load secrets from Azure Key Vault.

az spring-cloud connection delete \
    --resource-group ${RESOURCE_GROUP} \
    --service ${SPRING_CLOUD_SERVICE} \
    --connection ${ORDER_SERVICE_DB_CONNECTION} \
    --app ${ORDER_SERVICE_APP} \
    --deployment default \
    --yes 

az spring-cloud connection delete \
    --resource-group ${RESOURCE_GROUP} \
    --service ${SPRING_CLOUD_SERVICE} \
    --connection ${CATALOG_SERVICE_DB_CONNECTION} \
    --app ${CATALOG_SERVICE_APP} \
    --deployment default \
    --yes 

az spring-cloud connection delete \
    --resource-group ${RESOURCE_GROUP} \
    --service ${SPRING_CLOUD_SERVICE} \
    --connection ${CART_SERVICE_CACHE_CONNECTION} \
    --app ${CART_SERVICE_APP} \
    --deployment default \
    --yes 
    
az spring-cloud app update --name ${ORDER_SERVICE_APP} \
    --env "ConnectionStrings__KeyVaultUri=${KEYVAULT_URI}" "AcmeServiceSettings__AuthUrl=https://${GATEWAY_URL}"

az spring-cloud app update --name ${CATALOG_SERVICE_APP} \
    --config-file-pattern catalog/default,catalog/key-vault \
    --env "SPRING_CLOUD_AZURE_KEYVAULT_SECRET_PROPERTY_SOURCES_0_ENDPOINT=${KEYVAULT_URI}" "SPRING_CLOUD_AZURE_KEYVAULT_SECRET_PROPERTY_SOURCES_0_NAME='animal-rescue-vault'" "SPRING_PROFILES_ACTIVE=default,key-vault"
    
az spring-cloud app update --name ${IDENTITY_SERVICE_APP} \
    --config-file-pattern identity/default,identity/key-vault \
    --env "SPRING_CLOUD_AZURE_KEYVAULT_SECRET_PROPERTY_SOURCES_0_ENDPOINT=${KEYVAULT_URI}" "SPRING_CLOUD_AZURE_KEYVAULT_SECRET_PROPERTY_SOURCES_0_NAME='animal-rescue-vault'" "SPRING_PROFILES_ACTIVE=default,key-vault"
    
az spring-cloud app update --name ${CART_SERVICE_APP} \
    --env "CART_PORT=8080" "KEYVAULT_URI=${KEYVAULT_URI}" "AUTH_URL=https://${GATEWAY_URL}"
    
az spring-cloud app update --name ${FRONTEND_APP} \
    --env "KEYVAULT_URI=${KEYVAULT_URI}"

Next Steps

In this quickstart, you've deployed polyglot microservices to Azure Spring Cloud using Azure CLI. You also configured VMware Tanzu components in the enterprise tier. To learn more about Azure Spring Cloud or VMware Tanzu components, go to: