Skip to content

Files

Latest commit

cdbf624 · May 25, 2022

History

History
385 lines (271 loc) · 12.6 KB

microservices-dapr.md

File metadata and controls

385 lines (271 loc) · 12.6 KB
title description services author ms.service ms.topic ms.date ms.author ms.custom ms.devlang
Tutorial: Deploy a Dapr application to Azure Container Apps using the Azure CLI
Deploy a Dapr application to Azure Container Apps using the Azure CLI.
container-apps
asw101
container-apps
conceptual
03/22/2022
aawislan
ignite-fall-2021, devx-track-azurecli
azurecli

Tutorial: Deploy a Dapr application to Azure Container Apps using the Azure CLI

Dapr (Distributed Application Runtime) is a runtime that helps build resilient, stateless, and stateful microservices. In this tutorial, a sample Dapr application is deployed to Azure Container Apps.

You learn how to:

[!div class="checklist"]

  • Create a Container Apps environment for your container apps
  • Create an Azure Blob Storage state store for the container app
  • Deploy two apps that produce and consume messages and persist them in the state store
  • Verify the interaction between the two microservices.

With Azure Container Apps, you get a fully managed version of the Dapr APIs when building microservices. When you use Dapr in Azure Container Apps, you can enable sidecars to run next to your microservices that provide a rich set of capabilities. Available Dapr APIs include Service to Service calls, Pub/Sub, Event Bindings, State Stores, and Actors.

In this tutorial, you deploy the same applications from the Dapr Hello World quickstart.

The application consists of:

  • a client (Python) app that generates messages
  • a service (Node) app that consumes and persists those messages in a configured state store

The following architecture diagram illustrates the components that make up this tutorial:

:::image type="content" source="media/microservices-dapr/azure-container-apps-microservices-dapr.png" alt-text="Architecture diagram for Dapr Hello World microservices on Azure Container Apps":::

[!INCLUDE container-apps-create-cli-steps.md]


Individual container apps are deployed to an Azure Container Apps environment. To create the environment, run the following command:

az containerapp env create \
  --name $CONTAINERAPPS_ENVIRONMENT \
  --resource-group $RESOURCE_GROUP \
  --location "$LOCATION"
az containerapp env create `
  --name $CONTAINERAPPS_ENVIRONMENT `
  --resource-group $RESOURCE_GROUP `
  --location "$LOCATION"

Set up a state store

Create an Azure Blob Storage account

Choose a name for STORAGE_ACCOUNT. Storage account names must be unique within Azure, from 3 to 24 characters in length and must contain numbers and lowercase letters only.

STORAGE_ACCOUNT="<storage account name>"
$STORAGE_ACCOUNT="<storage account name>"

Set the STORAGE_ACCOUNT_CONTAINER name.

STORAGE_ACCOUNT_CONTAINER="mycontainer"
$STORAGE_ACCOUNT_CONTAINER="mycontainer"

Use the following command to create an Azure Storage account.

az storage account create \
  --name $STORAGE_ACCOUNT \
  --resource-group $RESOURCE_GROUP \
  --location "$LOCATION" \
  --sku Standard_RAGRS \
  --kind StorageV2
az storage account create `
  --name $STORAGE_ACCOUNT `
  --resource-group $RESOURCE_GROUP `
  --location "$LOCATION" `
  --sku Standard_RAGRS `
  --kind StorageV2

Get the storage account key with the following command:

STORAGE_ACCOUNT_KEY=`az storage account keys list --resource-group $RESOURCE_GROUP --account-name $STORAGE_ACCOUNT --query '[0].value' --out tsv`
$STORAGE_ACCOUNT_KEY=(az storage account keys list --resource-group $RESOURCE_GROUP --account-name $STORAGE_ACCOUNT --query '[0].value' --out tsv)

Configure the state store component

Create a config file named statestore.yaml with the properties that you sourced from the previous steps. This file helps enable your Dapr app to access your state store. The following example shows how your statestore.yaml file should look when configured for your Azure Blob Storage account:

# statestore.yaml for Azure Blob storage component
componentType: state.azure.blobstorage
version: v1
metadata:
- name: accountName
  value: "<STORAGE_ACCOUNT>"
- name: accountKey
  secretRef: account-key
- name: containerName
  value: mycontainer
secrets:
- name: account-key
  value: "<STORAGE_ACCOUNT_KEY>"
scopes:
- nodeapp

To use this file, update the placeholders:

  • Replace <STORAGE_ACCOUNT> with the value of the STORAGE_ACCOUNT variable you defined. To obtain its value, run the following command:
    echo $STORAGE_ACCOUNT
    
  • Replace <STORAGE_ACCOUNT_KEY> with the storage account key. To obtain its value, run the following command:
    echo $STORAGE_ACCOUNT_KEY
    

If you've changed the STORAGE_ACCOUNT_CONTAINER variable from its original value, mycontainer, replace the value of containerName with your own value.

Note

Container Apps does not currently support the native Dapr components schema. The above example uses the supported schema.

Navigate to the directory in which you stored the statestore.yaml file and run the following command to configure the Dapr component in the Container Apps environment.

If you need to add multiple components, create a separate YAML file for each component and run the az containerapp env dapr-component set command multiple times to add each component. For more information about configuring Dapr components, see Configure Dapr components.

az containerapp env dapr-component set \
    --name $CONTAINERAPPS_ENVIRONMENT --resource-group $RESOURCE_GROUP \
    --dapr-component-name statestore \
    --yaml statestore.yaml
az containerapp env dapr-component set `
    --name $CONTAINERAPPS_ENVIRONMENT --resource-group $RESOURCE_GROUP `
    --dapr-component-name statestore `
    --yaml statestore.yaml

Your state store is configured using the Dapr component described in statestore.yaml. The component is scoped to a container app named nodeapp and is not available to other container apps.

Deploy the service application (HTTP web server)

az containerapp create \
  --name nodeapp \
  --resource-group $RESOURCE_GROUP \
  --environment $CONTAINERAPPS_ENVIRONMENT \
  --image dapriosamples/hello-k8s-node:latest \
  --target-port 3000 \
  --ingress 'external' \
  --min-replicas 1 \
  --max-replicas 1 \
  --enable-dapr \
  --dapr-app-port 3000 \
  --dapr-app-id nodeapp
az containerapp create `
  --name nodeapp `
  --resource-group $RESOURCE_GROUP `
  --environment $CONTAINERAPPS_ENVIRONMENT `
  --image dapriosamples/hello-k8s-node:latest `
  --target-port 3000 `
  --ingress 'external' `
  --min-replicas 1 `
  --max-replicas 1 `
  --enable-dapr `
  --dapr-app-port 3000 `
  --dapr-app-id nodeapp

This command deploys:

  • the service (Node) app server on --target-port 3000 (the app port)
  • its accompanying Dapr sidecar configured with --dapr-app-id nodeapp and --dapr-app-port 3000 for service discovery and invocation

Deploy the client application (headless client)

Run the following command to deploy the client container app.

az containerapp create \
  --name pythonapp \
  --resource-group $RESOURCE_GROUP \
  --environment $CONTAINERAPPS_ENVIRONMENT \
  --image dapriosamples/hello-k8s-python:latest \
  --min-replicas 1 \
  --max-replicas 1 \
  --enable-dapr \
  --dapr-app-id pythonapp
az containerapp create `
  --name pythonapp `
  --resource-group $RESOURCE_GROUP `
  --environment $CONTAINERAPPS_ENVIRONMENT `
  --image dapriosamples/hello-k8s-python:latest `
  --min-replicas 1 `
  --max-replicas 1 `
  --enable-dapr `
  --dapr-app-id pythonapp

This command deploys pythonapp that also runs with a Dapr sidecar that is used to look up and securely call the Dapr sidecar for nodeapp. As this app is headless there is no --target-port to start a server, nor is there a need to enable ingress.

Verify the result

Confirm successful state persistence

You can confirm that the services are working correctly by viewing data in your Azure Storage account.

  1. Open the Azure portal in your browser and navigate to your storage account.

  2. Select Containers left side menu.

  3. Select mycontainer.

  4. Verify that you can see the file named order in the container.

  5. Select on the file.

  6. Select the Edit tab.

  7. Select the Refresh button to observe how the data automatically updates.

View Logs

Data logged via a container app are stored in the ContainerAppConsoleLogs_CL custom table in the Log Analytics workspace. You can view logs through the Azure portal or with the CLI. Wait a few minutes for the analytics to arrive for the first time before you are able to query the logged data.

Use the following CLI command to view logs on the command line.

LOG_ANALYTICS_WORKSPACE_CLIENT_ID=`az containerapp env show --name $CONTAINERAPPS_ENVIRONMENT --resource-group $RESOURCE_GROUP --query properties.appLogsConfiguration.logAnalyticsConfiguration.customerId --out tsv`

az monitor log-analytics query \
  --workspace $LOG_ANALYTICS_WORKSPACE_CLIENT_ID \
  --analytics-query "ContainerAppConsoleLogs_CL | where ContainerAppName_s == 'nodeapp' and (Log_s contains 'persisted' or Log_s contains 'order') | project ContainerAppName_s, Log_s, TimeGenerated | take 5" \
  --out table
$LOG_ANALYTICS_WORKSPACE_CLIENT_ID=`
(az containerapp env show --name $CONTAINERAPPS_ENVIRONMENT --resource-group $RESOURCE_GROUP --query properties.appLogsConfiguration.logAnalyticsConfiguration.customerId --out tsv)

az monitor log-analytics query `
  --workspace $LOG_ANALYTICS_WORKSPACE_CLIENT_ID `
  --analytics-query "ContainerAppConsoleLogs_CL | where ContainerAppName_s == 'nodeapp' and (Log_s contains 'persisted' or Log_s contains 'order') | project ContainerAppName_s, Log_s, TimeGenerated | take 5" `
  --out table

The following output demonstrates the type of response to expect from the CLI command.

ContainerAppName_s    Log_s                            TableName      TimeGenerated
--------------------  -------------------------------  -------------  ------------------------
nodeapp               Got a new order! Order ID: 61    PrimaryResult  2021-10-22T21:31:46.184Z
nodeapp               Successfully persisted state.    PrimaryResult  2021-10-22T21:31:46.184Z
nodeapp               Got a new order! Order ID: 62    PrimaryResult  2021-10-22T22:01:57.174Z
nodeapp               Successfully persisted state.    PrimaryResult  2021-10-22T22:01:57.174Z
nodeapp               Got a new order! Order ID: 63    PrimaryResult  2021-10-22T22:45:44.618Z

Clean up resources

Once you are done, run the following command to delete your resource group along with all the resources you created in this tutorial.

az group delete \
    --resource-group $RESOURCE_GROUP
az group delete `
    --resource-group $RESOURCE_GROUP

This command deletes the resource group that includes all of the resources created in this tutorial.

Note

Since pythonapp continuously makes calls to nodeapp with messages that get persisted into your configured state store, it is important to complete these cleanup steps to avoid ongoing billable operations.

Tip

Having issues? Let us know on GitHub by opening an issue in the Azure Container Apps repo.

Next steps

[!div class="nextstepaction"] Application lifecycle management